D3DXSprite Scaling anti-aliasing (Texture Filtering) issue (Solved)

Started by
2 comments, last by ubersheep 16 years ago
Hi all, Have scoured the internet for a while and not found a solution yet so I wonder if you guys could help me: I'm drawing a sizable amount of sprites per frame, and am using a single 'sprite sheet' image to contain all the individual sprites. These are all 8x8 sprites, and each of my Actor objects references a RECT within this spritesheet. At render time, the Actor's sprite object is transformed (scaled, rotated etc) and each Actor's 8x8 RECT area of the sprite sheet is drawn to screen, using spriteObject->Draw(). My problem is that after being scaled around 3/4 times, the sprites become blurred and lose their crispness. Also it seems that the RECT that the sprite object takes uses this anti-aliasing as well, as each draw call seems to begin drawing outside this RECT: I have outlined the exact pixels that should be being drawn for the large sprite above, in a snippet of the sprite sheet below: So far I've read that common advice for similar issues would be to give up and use GDI... although I can't immediately see the benefit of such. Are there any RenderStates etc. that would help me? The behaviour is similar to when zooming using the Windows Picture and Fax Viewer tool, so is it a Windows-related thing? Thanks in advance, [Edited by - ubersheep on May 3, 2008 8:27:22 PM]
Advertisement
This isn't anti-aliasing really, it's texture filtering.

It depends on what you chose as a minification/magnification filter. A bilinear filter will interpolate between pixels and produce the blurred, smooth output you're seeing. In most 3D games, this is a desirable outcome.

By default, D3DXSprite sets the magnification/minification filters to perform anisotropic filtering (AF) if the card support it. Otherwise, it uses bilinear. In your case, you can turn it off by calling the following function after ID3DXSprite::Begin():
IDirect3DDevice9::SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT)
NextWar: The Quest for Earth available now for Windows Phone 7.
Thankyou! It helps me to understand what I'm talking about, so yes I mean Texture Filtering.

However, I have implemented the SetSamplerState code directly after spriteObject->Begin(), and it doesn't seem to make a difference. Do I need to create a state block on the device?

Here's the render loop:

    // Render the scene    if( SUCCEEDED( pd3dDevice->BeginScene() ) )    {		LPD3DXSPRITE spriteObject = NULL;		V( D3DXCreateSprite( pd3dDevice, &spriteObject ) );		spriteObject->Begin( D3DXSPRITE_ALPHABLEND );		V( pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT) );		std::vector<Enemy*>::iterator iter;		for ( iter = g_paEnemy.begin(); iter != g_paEnemy.end(); ++iter )		{			(*iter)->RenderSprite( pd3dDevice, spriteObject );		}		spriteObject->End();		SAFE_RELEASE(spriteObject);        V( pd3dDevice->EndScene() );    }


Edit: An Enemy IS an Actor, and RenderSprite() calls SetTransform on spriteObject, then Draw().
WOOHOO :) Added MinFilter as well and it works perfectly!

		V( pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT) );		V( pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT) );


Thankyou Sc4Freak - really appreciate your help here :)

This topic is closed to new replies.

Advertisement