• Advertisement
Sign in to follow this  

[DX9] How to properly apply textures to an index buffered cube

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

In the program I am working on is a skybox. This skybox is made out of a vertex buffer and index buffer, consisting of 8 verteces, and 36 indexes (to make the 12 faces). Using the vertexformat D3DFVF_XYZ|D3DFVF_DIFFUSE and giving each vertex a colour I can see all verteces/faces are drawn as they should. But I ran into a problem when I started texturing. Adding 2 texture coordinates seems to work for only 4 of my 6 sides of the cube. This does make sense, as each vertex is a part of multiple faces, and in 2 of the faces, this creates conflicting texture coordinates. To solve this problem, I tried adding more texture coordinate sets (going as far as setting D3DFVF_TEX4). This however does not appear to have any effect, and I'm very much doubting if that is even the right approach. this is what I have so far:
	#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
	
	// vertex buffer
	CUSTOMVERTEX g_Vertices[] =  {
		// { x, y, z, color, tu1, tv1},
	        { -1.0f, 1.0f, 1.0f, 0xffff0000, 0.0f, 0.0f}, 	// top far left
	        { 1.0f, 1.0f, 1.0f, 0xffffff00, 1.0f, 0.0f}, 	// top far right
	        { -1.0f, 1.0f, -1.0f, 0xffffff00, 0.0f, 1.0f}, 	// top near left
		{ 1.0f, 1.0f, -1.0f, 0xffff00ff, 1.0f, 1.0f}, 	// top near right
		{ -1.0f, -1.0f, 1.0f, 0xffff00ff, 0.0f, 1.0f},	// bottom far left
		{ 1.0f, -1.0f, 1.0f, 0xff00FFFF, 1.0f, 1.0f},	// bottom far right
		{ -1.0f, -1.0f, -1.0f, 0xff00ffff, 0.0f, 0.0f},	// bottom near left
		{ 1.0f, -1.0f, -1.0f, 0xff0000FF, 1.0f, 0.0f}	// bottom near right		
    	};

	// index buffer
	int indices[] = {1,0,2, // top faces
			2,3,1,
			1,0,4, // back faces
			4,5,1,
			1,5,3, // right faces
			3,5,7,
			7,2,3, // front faces
			2,7,6,
			6,0,2, // left faces
			6,4,0,
			4,6,5, // bottom faces
			5,6,7};

it is currently being drawn by this code
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
		g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
		g_pd3dDevice->SetIndices(g_pIB);

		g_pd3dDevice->SetTexture( 0, g_pTop );
		//top
		g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 0, 2 );

		 g_pd3dDevice->SetTexture( 0, g_pNorth );
		//north
		g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 6, 2 );

		 g_pd3dDevice->SetTexture( 0, g_pSouth );
		//south
		g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 18, 2 );

		 g_pd3dDevice->SetTexture( 0, g_pBottom );
		//bottom
		g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 30, 2 );

		// these next 2 textures are drawn incorrectly, because of conflicting texture coordinates
		g_pd3dDevice->SetTexture( 1, g_pEast );
		//east
		g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 12, 2 );

		g_pd3dDevice->SetTexture( 1, g_pWest );
		//west
		g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 24, 2 );
I've searched this forum, the msdn, dx9 documentation and various websites for clues to how to solve this, but I cant figure it out. How can I draw a square texture on each of the 6 sides of my cube, without having to resort to using only a vertex buffer. While I realise that may make things a lot easier for this particular problem, it is significantly less efficient, as well as the fact that I have other index buffered objects which I would also like to texture, once I finish the skybox.

Share this post


Link to post
Share on other sites
Advertisement
Dude. Its a cube! Obsessing about optimizing the 8 vertices of a cube is silly. Graphics hardware can draw millions of cubes in a second and drawing a skybox is never going to be any sort of bottleneck.

Just duplicate the vertices with the necessary distinct texture coordinates in order to draw your skybox. You can only share whole vertices, not pieces of a vertex (like just the position).

Share this post


Link to post
Share on other sites
Even so, I have a terrain for example as well, also with index and vertex buffer, as well as various other models. All of these will need textures. Converting a cube to a simple vertex buffer isnt going to be a big efficiency hit, but a 256x256 terrain will be...

On top of that, I figured it would be a good exercise to get to grips with index buffers and texturing, as it is a straightforward model.

Share this post


Link to post
Share on other sites
Quote:
Original post by GSFJohnDoe
Even so, I have a terrain for example as well, also with index and vertex buffer, as well as various other models. All of these will need textures. Converting a cube to a simple vertex buffer isnt going to be a big efficiency hit, but a 256x256 terrain will be...

On top of that, I figured it would be a good exercise to get to grips with index buffers and texturing, as it is a straightforward model.


Whether its a cube or a terrain or a character model makes no difference. You can't share pieces of a vertex, only whole vertices. If any of the components of the vertex are different at a triangle boundary, then the vertex must be duplicated, it can't be shared.

You're looking at the wrong end of the conceptual funnel to be thinking about optimization. If you want to learn about how to do things fast, read a book like Real-Time Rendering instead of trying to obsess about individual vertex sharing.

Share this post


Link to post
Share on other sites
Ok...

So does this mean index buffers have a very limited use? It seems you run into texturing problems very quickly, and we all like to see textures on our models.

It would appear then that index buffers are often not usable when you want to texture your model too?

Share this post


Link to post
Share on other sites

Hello,

There is a simple solution for this problem : use cubemap, with its 6 sides you can have unique texture for each side of the sky cube. You'll need just one 3D texture coordinate per vertex and one texture for the whole cube. And, you can draw it with one draw call.

Good luck!

Share this post


Link to post
Share on other sites
I will look into the cubemap :)

for now I think I solved the problem by getting multiple coordinate sets ( D3DFVF_TEX2 ) to work by setting SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1); when drawing the last 2 sides of the cube.

Share this post


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

  • Advertisement