Problem with texture translations

Started by
3 comments, last by mdias 18 years, 9 months ago
I'm trying to use textured quads to display 2D sprites on a screen. I've gotten the textures to display and scale properly, however I can't translate the texture around on the quad so that different parts are being shown. My idea was to have a tileset as the texture, and different frames of animation would be shown on the quad by scaling and translating the texture in the right way, however I can't make them translate at all. Keep in mind that I'm just entering the scaling and translation values manually in the code for now, as a proof of concept type of thing. It's also kind of broken up, just to show the relevant parts of the texture code.

struct CUSTOMVERTEX
{
    FLOAT x, y, z; 
    DWORD color;  
    FLOAT u, v;
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0))

...

CUSTOMVERTEX Vertices[] =
    {
        {0.0f, 0.0f, 0.0f, 0xffffffff, 1.0f, 1.0f}, // x, y, z, color, u, v
        {1.0f, 0.0f, 0.0f, 0xffffffff, 0.0f, 1.0f},
        {1.0f, 1.0f, 0.0f, 0xffffffff, 0.0f, 0.0f},
	{0.0f, 1.0f, 0.0f, 0xffffffff, 1.0f, 0.0f},
    };
//this is then put in the vertex buffer once, at the beginning of the program

...


g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);

...

D3DXMatrixScaling(&matScaling, 0.5f, 0.5f, 1.0f);
D3DXMatrixTranslation(&matTranslation, 0.0f, 0.0f, 0.0f); //what values go here?
texTransform = matScaling * matTranslation;
	
if(FAILED(g_pd3dDevice->SetTransform(D3DTS_WORLD, &quadTransform)))
{
	return(E_FAIL);
}

When I run the program, the upper left tile of the tileset will display properly, but I can't translate the texture around to show the other tiles. I'm not sure what I'm missing here, or if I've forgotten some important piece of code somewhere. I suppose I could avoid doing this by just loading each frame as a separate texture, but then I'd have to make each frame an individual file, which is messy.
Advertisement
Here's a piece of my engine's code that should help you:
//=========================================================//	Compute the matrix//=========================================================void kTransformTexture::computeMatrix( D3DXMATRIX *pOutMatrix ){	D3DXMATRIX mat;	D3DXMatrixIdentity( pOutMatrix );	// rotation	D3DXMatrixRotationZ( &mat, m_rotation.z );	// u/v modifiers	(*pOutMatrix)[2][0] = m_position.x;	(*pOutMatrix)[2][1] = m_position.y;	// scaling	(*pOutMatrix)[0][0] = m_scale.x;	(*pOutMatrix)[1][1] = m_scale.y;	D3DXMatrixMultiply( pOutMatrix, &mat, pOutMatrix );}
If I understand you correctly, typically you would use texture coordinates for a task like this.

Let's say you have a 128x128 texture. It contains 4 64x64 frames.

To render frame number *one* you'd use [0.0,0.0] to [.5, .5] as the texture coordinates. The render frame number *two* you'd use [.5, 0.0] to [1.0, .5] as the texture coordinates.
Co-creator of Star Bandits -- a graphical Science Fiction multiplayer online game, in the style of "Trade Wars'.
Quote:Original post by The Frugal Gourmet
If I understand you correctly, typically you would use texture coordinates for a task like this.

Let's say you have a 128x128 texture. It contains 4 64x64 frames.

To render frame number *one* you'd use [0.0,0.0] to [.5, .5] as the texture coordinates. The render frame number *two* you'd use [.5, 0.0] to [1.0, .5] as the texture coordinates.


Is there some way to use matrix transformations to accomplish this? I'd rather avoid locking and unlocking the vertex buffer just to change the texture coordinates of the vertices.

I also just now tried manually setting the translation values in the matrix, and that doesn't work either.

*edit* Oh snap, it does work. I'm not sure why it would work, as opposed to using D3DXMatrixTranslation() though. Thanks guys.
Texture translations don't work with D3DXMatrixTranslation because it uses different "indexes" of the matrix for the translation.

As the code I posted above shows, to modify the translation you have to access the matrix[2][0] and matrix[2][1] to change the u/v coordinates.

Now for the animation, let's suppose you have a quad:
vertices[0].uv = vector2( 0.0f, 0.0f ); // upper leftvertices[1].uv = vector2( 1.0f/(float)numFrames, 0.0f ); // upper rightvertices[2].uv = vector2( 0.0f, 1.0f ); // bottom leftvertices[3].uv = vector2( 1.0f/(float)numFrames, 1.0f ); // bottom right

Now, to render the quad with the frame you want you'd change matrix[2][0] like this:
float delta = 1.0f/(float)numFrames;matrix[2][0] = delta * (float)curFrame;


numFrames --> variable that contains the number of frames in the texture
curFrame --> current frame that you want to be rendered.

note: This example assumes all your frames are next to each other (i.e. not changing the v coordinate of the texture).

This topic is closed to new replies.

Advertisement