Sign in to follow this  
manxankur

Clipping a texture - not using DX sprite functions

Recommended Posts

manxankur    123
Hi all, Ok here is the situation. I've loaded a sprite sheet into my game. I want to be able to clip the sprite sheet and display a certain part of it on the face of some polys in the 3D world. Is there a DX function which can do this? I know of the sprite functions but this is for sprites on a screen (like HUD stuff). Any help and suggestions are appreciated! Ankur

Share this post


Link to post
Share on other sites
jollyjeffers    1570
hmm, not sure I see the problem here!?

Texture coordinates are the basic mechanism for selecting an arbitrary region of a texture, but I'm sure you're aware of this [smile]

ID3DXSprite can be used for 2D HUD-style rendering, and the ::Draw() method takes a RECT that allows you to define the region of the source texture to use.

If the sprite interface can't handle your HUD requirements then roll your own with D3DFVF_XYZRHW / POSITIONT geometry...

If the above isn't what you wanted, restating your problem and goal might be helpful...

hth
Jack

Share this post


Link to post
Share on other sites
manxankur    123
Hi Jack,

yeah i've got the HUD sprite sorted i understand that part. I also know about the texture coordinates.

Ok so let me explain the situation a little better. Imagine a 3D world, it has a road, pavement, buildings etc. Now i have made a two triangle polygon which has on it a texture. This texture is actually a sprite sheet. Currently i have the texture coordinates set so that it displays the first sprite i.e. a man standing. Now i want to be able to change the texture coordinates (the u & v values) in real time rather than just at load time so that it displays the next sprite i.e. man starting to walk. I don't want to have to unlock and lock the vertex buffer to edit the texture coordinates every time as this requires a lot of the computers resources (so i've heard). Is there another way of doing this?

There is one way i think could work but it requires a dynamic way of making vertex buffers so that i can make the right amount of polygons e.g. 2 triangles per sprite. This way i can tell the SetTexture function which triangles to draw.


Thanks in advance

Ankur

Share this post


Link to post
Share on other sites
MasterWorks    496
Quote:
Original post by manxankur
I don't want to have to unlock and lock the vertex buffer to edit the texture coordinates every time as this requires a lot of the computers resources (so i've heard). Is there another way of doing this?

The standard way to do this is to use a dynamic vertex buffer. If your vertex information is changing from frame to frame, you don't really have much choice.

Your other option might be to use the texture transform matrix. You could apply the correct scale/shift to the texture matrix and then render your geometry and then set it back to identity; this way I think you could get it done without a VB lock. But, you have to break the batch to do this.

Also FYI I'm not sure that your statement 'This way i can tell the SetTexture function which triangles to draw' makes any sense. D3D is a state machine, and SetTexture just sets the current texture. All drawing is done through DrawPrimitive-type calls.

Share this post


Link to post
Share on other sites
Quote:
Original post by manxankur
There is one way i think could work but it requires a dynamic way of making vertex buffers so that i can make the right amount of polygons e.g. 2 triangles per sprite. This way i can tell the SetTexture function which triangles to draw.


Your vertex buffer can be extra large. The arguments to Draw[Indexed]Primitive tell D3D which parts of the buffer to use. Generally you have a dynamic buffer large enough to hold a few hundred to a few thousand quads/sprites at once. You can draw before it's full, then append more data on to the end, and draw some more. It's best not to draw each sprite by itself, as Draw calls are expensive.

When using a dynamic VB, it must be in pool default (so you'll have to handle a lost device. Kill the VB and remake it when you are able to Reset).

When locking a dynamic VB you'll use one of two flags.
DISCARD = I'd like to start writing to the start of the buffer.

NOOVERWRITE = I'd like to add stuff to the end of the buffer. I promise I won't touch anything written previously (ie: I promise I won't screw up a buffered draw call).


DISCARD *usually* also lets you have control of the VB immediately. If a VB is being used by a buffered draw call, D3D will actually switch things around internally to give you a new VB. If you're drawing many batches per frame, you want to have a larger VB and use NOOVERWRITE sometimes. There are a limited number of "rename buffers" D3D can give you, so you don't always want to lock with DISCARD unless you've only got 1 or 2 draw calls per frame. If you run out of buffers, D3D will wait until one is free.

NOOVERWRITE lets you have control of the VB immediately, as you've promised to not interfere with anything.

With static vertex buffers you always wait until the GPU has finished processing before you get the buffer.

Share this post


Link to post
Share on other sites
manxankur    123
Quote:
Original post by manxankur
There is one way i think could work but it requires a dynamic way of making vertex buffers so that i can make the right amount of polygons e.g. 2 triangles per sprite. This way i can tell the SetTexture function which triangles to draw.


Hi,

Sorry what i meant to put was DrawIndexedPrimitive not SetTexture :P

I'm going to have a go at Dynamic VB and look up texture transform matrix. Thanks i'll report back.

Ankur

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this