• Advertisement
Sign in to follow this  

Rendering Parts of a Texture for Animated Sprites

This topic is 4733 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

I've been making my own sprite class for billboarding and havn't been using the D3DXSprite class for a couple of reasons: 1) Positioning using center co-ords must be calculated based on texture size 2) The entire co-ord system for the textures seems flipped when the billboard flag is set. I've tried working a lot with the transform matrices, but nothing seems to budge. If i can get the sprites to render upright then using the D3DXSprite class is fine. I would like to do animated sprites using one texture that has all the frames in it. This requires renderding only parts of the texture at a time. My class uses 4 vertices, a textured quad. I tried modifying the u,v co-ords of the vertex buffer at run time using a dynamic buffer, but the performace was crap. Maybe I did something wrong. The next idea is to extract only the portion for the current frame from the texture surface, create a new texture with it, and set that texture in the device. Tried some variations on that, but it usually crashes when i go to make the second texture. I'm not sure if that is the best way. Any suggestions? Here's my code using D3DXSprite's in case I'm doing something wrong that's making them go upside-down. Code in C#:
Sprite.SetWorldViewLH( Matrix.Translation(Position), d3dDevice.Transform.View );
Sprite.Begin( SpriteFlags.AlphaBlend | SpriteFlags.Billboard );
Sprite.Draw( texture, new Vector3(0,0,0), new Vector3(0,0,0), Color.White );
Sprite.End();

Thanks

Share this post


Link to post
Share on other sites
Advertisement
I think you should stick with changing the u, v co-ordinates. Have you run a profiler over the 'crap' code to see why things are slowing down so much? Try GlowCode's free trial, I think you get about 30 days and it is awesome. I went on to buy the full thing and it has become essential.

Regards.

Mark Coleman

Share this post


Link to post
Share on other sites
u can use a vertex buffer and fixed index buffer. the vertex buffer data should change at run time according to the texture u would like to draw.

Share this post


Link to post
Share on other sites
I would create the IB with the WriteOnly flag, and the vb with the Dynamic and WriteOnly flags, and when locking the vb use the Discard flag.
Hope that helps!

Share this post


Link to post
Share on other sites
Thanks for the help. Using the LockFlags.Discard when locking the VB for writing helped a good amount. However there is still some performance issues, although not as bad now. If I have more then 10 sprites on the screen I can watch the framerate begin to drop the more I add.

Also, what is the point in using an IB? I thought the main reason is to save video memory. In this case, I have just four vertices im drawing using a triangle strip. Adding the index buffer doesnt really help me here, does it?

Here is the code i'm using to write to the VB:


private void SetTextureCoords( Rectangle rect, Texture texture )
{
if ( rect == Rectangle.Empty )
{
// use the whole texture
verts[0].Tu = 0.0f; verts[0].Tv = 0.0f;
verts[1].Tu = 0.0f; verts[1].Tv = 1.0f;
verts[2].Tu = 1.0f; verts[2].Tv = 0.0f;
verts[3].Tu = 1.0f; verts[3].Tv = 1.0f;
}
else
{
float width=256f, height=256f;
// using ( Surface s = texture.GetSurfaceLevel(0) )
// {
// width = s.Description.Width;
// height = s.Description.Height;
// }

// set to specified rectangle
verts[0].Tu = rect.Left / width; verts[0].Tv = rect.Top / height;
verts[1].Tu = rect.Left / width; verts[1].Tv = rect.Bottom / height;
verts[2].Tu = rect.Right / width; verts[2].Tv = rect.Top / height;
verts[3].Tu = rect.Right / width; verts[3].Tv = rect.Bottom / height;
}

// set the new vertex data
VertexBuff.SetData( verts, 0, LockFlags.Discard );
}



Note that I have commented out the part where it queries the texture for its dimensions in case it may have been that, but I am still seeing lag as more sprites are rendered.

Thanks,
SpeeD

[Edited by - SpeeD on March 4, 2005 8:17:50 PM]

Share this post


Link to post
Share on other sites
You dont have to lock the buffer to switch texture coordinates, you can set a transformation matrix for it instead.


// set texture transformation
D3DXMATRIX texturematrix;
D3DXMatrixIdentity(&texturematrix);
texturematrix._11 = (sourcewidth-1.0f)/texture->width; // sourcewidth/texturewidth
texturematrix._22 = (sourceheight-1.0f)/texture->height; // sourceheight/textureheight
texturematrix._31 = (1.0f+srcrect.left)/texture->width; // sourceoffsetx/texturewidth
texturematrix._32 = (1.0f+srcrect.top)/texture->height; // sourceoffsety/textureheight

d3d_device->SetTransform( D3DTS_TEXTURE0, &texturematrix );

Share this post


Link to post
Share on other sites
If I were u, i would batch all the vertex data in a temporary array, and when your all your quads from a single texture are drawn, lock the VB, copy the temp buffer to VB, and then render them all. This is esp. helpful if u pack all the sprites in one single texture.

Share this post


Link to post
Share on other sites
Thanks guys, looks like the performance issue now lies in the implementation rather than changing the texture co-ords.

The transformatin matrix is what i'm using for now, it seems a bit faster than writing to the VB. Thanks Peter, thats an interesting matrix, where'd you come up with that? I'm not sure why the first two items are subtracting 1.0f from the width & height, but it works :).

For further performance I'll most likely have to batch sprites together rather than rendering them one at a time. Thanks Yuhaobo.

I used GlowCode to find a memory error where I wasnt disposing of surfaces due to some wierd .net referencing issues, thanks mrcoleman.

I'm not using an IB becuase it seems redundant since I only have 4 vertices. Would using an IB help? I didnt notice a performance difference.

Share this post


Link to post
Share on other sites
the +1 and -1 has to do with that d3d samples from the "middle" of a pixel. And i think that when sampling close to the edges of the texture you somtimes got a thin line of junk from outside the texture if it was streched. But it was many years since i wrote that, you can probebly throw the +1 and -1 away saftly. :-)

Share this post


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

  • Advertisement