Jump to content
  • Advertisement
Sign in to follow this  
Endemoniada

2D Problem

This topic is 4144 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys, I have my 2D engine working almost perfectly but occasionally the texture coordinates come out wrong; it happens randomly but just enough that's it's noticable but there doesn't seem to be anything causing it. For example, if I have a 40x40 pixel sprite that I make all black and make the rest of the texture pink and display it on a black background I'll occasionally see a 1-pixel wide pink line so it's getting the soure coordinates wrong. I'm using pretransformed vertices (D3DFVF_XYZRHW|D3DFVF_TEX1) and subtract 0.5f from the X and Y values when I render. My texture is 1024x1024. It's driving me crazy because it hardly happens so I can't figure out the conditions that are causing it, I can't even duplicate it except by randomly moving my sprite around the screen waiting for it to happen. Any ideas ? The game is like a scrolling asteroids just so you have an idea. Here are the states I set right after I create D3D and setup the vertex/index buffers and texture: g_d3d_device->SetVertexShader(NULL); g_d3d_device->SetRenderState(D3DRS_ZENABLE,D3DZB_FALSE); g_d3d_device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); g_d3d_device->SetRenderState(D3DRS_LIGHTING,FALSE); g_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); g_d3d_device->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); g_d3d_device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); g_d3d_device->SetFVF(D3DFVF_CUSTOMVERTEX); g_d3d_device->SetStreamSource(0,g_vertex_buffer,0,sizeof(CUSTOMVERTEX)); g_d3d_device->SetIndices(g_index_buffer); g_d3d_device->SetTexture(0,g_texture);

Share this post


Link to post
Share on other sites
Advertisement
Two things I can think of:

1) Make sure you're using POINT filtering. How you set this depends on whether you're using the programmable pipeline or the fixed function one, but either way, you'll want to be using POINT filtering (unless you want scaling or rotation).

2) Try different numbers other than 0.5. I've heard people talk about 0.375 or 0.425 instead of 0.5, but the exact value may vary. Try different values and see if it helps at all.

Hope this helps.

Share this post


Link to post
Share on other sites
Yeah, this is a common artifact when using linear filtering. Your texture coordinates are slightly wrong and sampler is fetching a pixel outside your intended region and this gets blended slightly into the final value - giving you the results you're observing [smile]

When using sprites the size of the entire texture you can set up your TC's to CLAMP to avoid similar wrap-around artifacts. For your case, where you're using a texture palette/atlas you're going to have to get your TC's 100% correct.

Draw it out on paper if I were you - and if you're not familiar with bilinear filtering (provided sirob's suggesting of using POINT isn't acceptable) then read up on how it fetches texels. Chances are you can quickly spot how/why it's getting unwanted values...

hth
Jack

Share this post


Link to post
Share on other sites
Hi guys,

Thanks for trying to help me but I'm still not sure what to research.

I don't know if I'm using the programmable pipeline or the fixed function one but I added these (even though they are the default):

g_d3d_device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_POINT);
g_d3d_device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_POINT);

I'm not sure if that's what you meant.

When I compute my texture coordinates I do it like this:

int angle=(between 0 and 17 inclusive);

tex_l=((float)angle*40.0f)/1024.0f;
tex_r=((float)angle*40.0f+40.0f)/1024.0f;
tex_t=100.0f/1024.0f;
tex_b=140.0f/1024.0f;

...the sprites on the bitmap start at (0,100), are 40x40 pixels, and are tiled left to right.

I usually see the artifact on the top or bottom, but most of the time it's perfectly fine. I'm not scaling, rotating or anything like that, it's all straight 2D (like DirectDraw).

I'll try some numbers other than 0.5 as well but i don't feel comfortable with that because I don't know what will happen on other people's computers.

Then I'll do some research on bilinear filtering.

I'm using VS2005 and doing everything in C++ (if that matters).

Thanks again.

Share this post


Link to post
Share on other sites
The problem can be in z coordinate sorting. For example:
You have red background. In front of it are green woods, and then in front of woods is your blue ship.
If you position ship to 0.4 z coordinate and woods to 0.5, and you draw ship first, and then woods, you will see red line around your ship.
The program works fine, but ship 'alpha' piece is taken from background, and if you don't draw woods before ship, alpha piece will be red, because background is red.
So, even if direct x sort things right on z axis, you need to draw things in right order (background, woods and ship), it gives less headache.

Quote:

tex_l=((float)angle*40.0f)/1024.0f;
tex_r=((float)angle*40.0f+40.0f)/1024.0f;
tex_t=100.0f/1024.0f;
tex_b=140.0f/1024.0f;

I see you are using u,v coordinates that can be from 0.0f to 1.0f. That can be very painful if you use sprites of for example, 33x33 because 33/1024 will give you floating number that isn't so precise. You will get non-precise sprites coordinates , if you work with numbers like 0.32323232323 etc.

Easier way: DirectX have also ID3DXSprite interface. Defining sprite coordinates with this interface is much more easier. You need to define one rect structure and put coordinates in it.
In your example it will be:
rect.left = 40;
rect.right = 40;
rect.top = 100;
rect.bottom = 140;
and then you call draw method wit these coordinates.
Look at it.

Also one more thing [smile]
in
Quote:

tex_l=((float)angle*40.0f)/1024.0f;
tex_r=((float)angle*40.0f+40.0f)/1024.0f;
tex_t=100.0f/1024.0f;
tex_b=140.0f/1024.0f;


You don't need downcast to float because if angle is integer, multiplying integer with float is float, and you don't even get a warning.
So the shorter version is:
tex_l=angle*40.0f/1024.0f;
tex_r=(angle*40.0f+40.0f)/1024.0f;
tex_t=100.0f/1024.0f;
tex_b=140.0f/1024.0f;

Share this post


Link to post
Share on other sites
well not really looked at the forum very much but I think it may be mipmaping see if you are using mipmaping it will mix the pixels from the top with the bottom so just turn it off or you can make the textures not tile. that will work probaly? yeah do that turn off the tiling. hope that helps

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!