DX9 and textures

Associate
Joined
22 Sep 2009
Posts
2,085
Location
Leicester
Currently in the process of 'learning' D3D, however I've stumbled across a small issue that I can't seem to figure out. I'm trying to load an image file which contains multiple textures (think of a tile sheet), and draw one of those textures, I can do it however it's a really unsightly method and I'm guessing there has to be something easier that I haven't managed to find.

This is my code basically:

Code:
void blitD3D(IDirect3DTexture9 *texture, RECT *rDest, D3DCOLOR vertexColour, float rotate)
{
	TLVERTEX *vertices;

	//lock the vertex buffer so only this thread can access it
	vertexBuffer->Lock(0, 0, (void**)&vertices, NULL);

	//vertices go clockwise
	vertices[0].colour = vertexColour;
	vertices[0].x = (float) rDest->left - 0.5f;
	vertices[0].y = (float) rDest->top - 0.5f;
	vertices[0].z = 0.0f;
	vertices[0].rhw = 1.0f;
	vertices[0].u = 0.0f;
	vertices[0].v = 0.0f;

	vertices[1].colour = vertexColour;
	vertices[1].x = (float) rDest->right - 0.5f;
	vertices[1].y = (float) rDest->top - 0.5f;
	vertices[1].z = 0.0f;
	vertices[1].rhw = 1.0f;
	vertices[1].u = 1.0f;
	vertices[1].v = 0.0f;

	vertices[2].colour = vertexColour;
	vertices[2].x = (float) rDest->right - 0.5f;
	vertices[2].y = (float) rDest->bottom - 0.5f;
	vertices[2].z = 0.0f;
	vertices[2].rhw = 1.0f;
	vertices[2].u = 1.0f;
	vertices[2].v = 1.0f;

	vertices[3].colour = vertexColour;
	vertices[3].x = (float) rDest->left - 0.5f;
	vertices[3].y = (float) rDest->bottom - 0.5f;
	vertices[3].z = 0.0f;
	vertices[3].rhw = 1.0f;
	vertices[3].u = 0.0f;
	vertices[3].v = 1.0f;

	if(rotate)
	{
		//rotation code here
	}

	//unlock the vertex buffer for external use
	vertexBuffer->Unlock();

	d3ddev->SetTexture(0, texture);

	d3ddev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
}

Now using the example of a 1024x1024 image which contains 4 textures of 512x512 each, I could change the u and v (my texture coordinates) to be u = 0.0f and v = 0.5f to load the top left corner of the second image, however this is going to become complex and erroneous if I start using say 3 images (0.333333333f anyone?), so is there something more friendly I can use than this?
 
Maybe my brain is just having a slow day, but how will that help? I'm still going to be working with annoying numbers as opposed to coordinates unless I'm overlooking something blindly obvious.
 
You'll always want to know how many tiles you have per texture I guess?

Plus, the size of each tile, and size of the texture

const int tileWidth = 512;
const int tileHeight = 512;

const int textureWidth = 1024;
const int textureHeight = 1024;

// find out how big a single pixel is in terms of a float value 0.0 - 1.0
float RecipW = 1.0f / textureWidth;
float RecipH = 1.0f / textureHeight;

Then you'll be able to easily just specify offsets in terms of pixels into the texture.

So say you want to use what's effectively the bottom left tile in a 4x4 arrangement, just do:

// top left vertex
vertices[0].u = 0.0f; //we're bottom left so don't offset into the x position
vertices[0].v = (float)(tileHeight) * RecipH; // we're offset down one tile on the Y, so increment by tile height

// top right vertex
vertices[1].u = (float)(tileWidth) * RecipW; //we're skipping across by the width of the tile
vertices[1].v = (float)(tileHeight) * RecipH; // we're offset down one tile on the Y, so increment by tile height

lets say we want bottom right tile..

// top left vertex
vertices[0].u = (float)(tileWidth) * RecipW; //we're bottom right so offset across x by size of one tile
vertices[0].v = (float)(tileHeight) * RecipH; // we're offset down one tile on the Y, so increment by tile height

I think that's right..sorry if it's not explained well. Is this for animation or are you just trying to create a texture atlas?
 
Ah right, I see how that'd work. Also although I do know the image dimensions they will probably vary (so not able to hard code) and I hate having lots of arguments in my prototypes, but flicking through the DX documentation there's the option to store image data in a struct and read back dimensions from there, which is what I did to make things easier.

Anyway since doing this I've come to realise my classes are becoming increasingly more complex and awkward, so before I go ahead and use/change my current classes, is there a way to load only a certain set of coordinates from a file as a texture? D3DXCreateTextureFromFileEx allows me to specify the width and heigh in pixels, however this is from (0,0) and unfortunately there doesn't appear to be a way to change the origin, is there a similar function which would allow me to do this? If there is, it'd make things a hell of a lot easier for me however I'm not familiar with the majority of functions available to me.

EDIT: Disregard this, I really was having a slow day, I've sorted out my classes now into a structured layout.
 
Last edited:
Back
Top Bottom