PDA

View Full Version : Changing Novashell source - Linear Filter



garcia
11-04-2010, 03:22 PM
Hello everybody,

I am changing the Novashell source code so it can use the linear filter when scaling tiles.

I have created a checkbox in the entity/tile properties page so the user can enable the linear filter if necessary.

I think I've changed everything correctly, but something is not working.

In Tile.cpp - RenderTilePic(...) there is the following code



rectDest.bottom = RoundNearest(rectDest.bottom, 1.0f);
rectDest.right = RoundNearest(rectDest.right, 1.0f);
rectDest.top = RoundNearest(rectDest.top, 1.0f);
rectDest.left = RoundNearest(rectDest.left, 1.0f);

clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MAG_FILTER, CL_NEAREST);
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MIN_FILTER, CL_NEAREST);

pSurf->set_color(pTile->GetColor());
pSurf->draw_subpixel(pTile->m_rectSrc, rectDest, pGC);


I've changed it to


rectDest.bottom = RoundNearest(rectDest.bottom, 1.0f);
rectDest.right = RoundNearest(rectDest.right, 1.0f);
rectDest.top = RoundNearest(rectDest.top, 1.0f);
rectDest.left = RoundNearest(rectDest.left, 1.0f);

if (pTile->GetBit(Tile::e_linearFilter)) // flag created for the linear filter
{
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MAG_FILTER, CL_LINEAR);
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MIN_FILTER, CL_LINEAR);
}
else
{
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MAG_FILTER, CL_NEAREST);
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MIN_FILTER, CL_NEAREST);
}
pSurf->set_color(pTile->GetColor());
pSurf->draw_subpixel(pTile->m_rectSrc, rectDest, pGC);


When I check the Linear Filter checkbox the if condition is satisfied and the correct code is executed



clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MAG_FILTER, CL_LINEAR);
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MIN_FILTER, CL_LINEAR);


But the filtering is not applied to the tile.

If I just change the CL_NEAREST param to CL_LINEAR with no IF, then the filtering is applied, but it is applied to all tiles.

It seems like the clTexParameteri call with CL_NEAREST is cancelling any previous calls with CL_LINEAR.

Thank you for any help.

Seth
11-04-2010, 11:13 PM
Hmm, before the clTexParameteri statements try adding this:


clBindTexture(CL_TEXTURE_2D, pSurf->get_handle());


Without binding it first, the parameter changes could be happening to the wrong texture. I don't think I really understood that when I wrote that code. :sweatdrop:

garcia
11-05-2010, 04:16 AM
Seth,
the clBindTexture didn't work. When I added it, all the TilePics started to show the same image.


clEnable(CL_TEXTURE_2D); // I tested with and without this line.
clBindTexture(CL_TEXTURE_2D, pSurf->get_handle());

if (pTile->GetBit(Tile::e_linearFilter))
{
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MAG_FILTER, CL_LINEAR);
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MIN_FILTER, CL_LINEAR);
}
else
{
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MAG_FILTER, CL_NEAREST);
clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MIN_FILTER, CL_NEAREST);
}


Unfortunately the CL_Surface does not have the set_min_filter(...) and set_mag_filter(...) methods as the CL_Texture has.

I saw some opengl examples and all of them set the min and mag filter just before the creation of the texture. Maybe I should recreate the Surface if the linear filter is set, but I guess it would generate a big code change.

What do you think Seth?

Seth
11-05-2010, 05:51 AM
Oops, I forgot about Clanlib's batching stuff.

Try replacing clBindTexture(CL_TEXTURE_2D, pSurf->get_handle()); with:


CL_OpenGLState state(pGC);
state.set_active();
clBindTexture(CL_TEXTURE_2D, pSurf->get_handle());


And you will probably need to add this at the top of Tile.cpp:


#include "ClanLib/GL/opengl_state.h"

garcia
11-05-2010, 10:59 AM
It works! But I had to do another little change in order to really work.

I had to comment out the clTexParameteri(...) from HashedResource::LoadImage()



bool HashedResource::LoadImage()
{
GetGameLogic()->ShowLoadingMessage();

SAFE_DELETE(m_pImage);

CL_PixelBuffer p = CL_ProviderFactory::load(m_strFilename);
//use this method gives us a chance to twiddle with the bits a bit
if (m_bColorKeyActive)
{
p.set_colorkey(true, m_colorKey);
}

m_pImage = new CL_Surface(p);
// clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MAG_FILTER, CL_NEAREST);
// clTexParameteri(CL_TEXTURE_2D, CL_TEXTURE_MIN_FILTER, CL_NEAREST);
return m_pImage != NULL;
}


I am going to test it during the development of my game. If everything is ok, I will create a patch for the repository. Should I use the Create Patch of Tortoise and post it in the forums?

Thanks Seth for your help.

Seth
11-07-2010, 01:25 PM
I am going to test it during the development of my game. If everything is ok, I will create a patch for the repository. Should I use the Create Patch of Tortoise and post it in the forums?

Sure, that would be great.

garcia
11-14-2010, 03:53 PM
Hi Seth,

I've been using the engine since I made the Linear Filter change and it seems to be working normally. So, I made a patch in case you want to apply to the repository.

480

Please, when you apply the patch, inform me so I can update my copy.

Thanks,
Marcio.

Seth
11-14-2010, 11:15 PM
Thanks, committed! I tried setting the new linear filtering checkbox on a few sprites in the treeworld example and zoomed in but I didn't see the filtering turn on. Might want to double check that I added the patch right, code looks right.. hmm.

garcia
11-15-2010, 12:00 AM
Seth,
try to change the scale of the sprites. I don't know whether it would be applied by zooming.