Problems with Direct3D
I program in C++ with Visual C++ 2005 Express and I have just decided to begin programming with DirectX because I am interested in game programming and decided that DirectX would be the best step to take. Unfortunately I have run into a few problems, I have taken two tutorials so far and neither of them nor any that I have looked up address my problem.
Here are the problems I am having:
-I don't know how to draw multiple primitives from one vertex buffer in different positions(ex: I want to draw a tiles floor and I want to repeat the same square for the whole room but unfortunately I do not know how to move only one primitive at a time. What I mean is when I move a square using translation it moves every square in the world space.)
-I need to know how to move only one vertex at a time.
Those are the main problems that I am helping and any help is greatly appreciated.
For a tiled floor there are several options:
1) Store a single quad in a vertex buffer and render individual tiles, one at a time.
2) Store all of the tiles in the vertex buffer and render them all together.
3) Use a mesh and render the entire mesh.
You should prefer either 2 or 3 for speed.
But, if you want to do it like 1) then you do it like this:
1) Put your quad in the vertex buffer, set up your index buffer as well.
2) Set the translation matrix for the current tile.
3) Draw the quad using DrawIndexedPrimitive() or DrawPrimitive() if you are not using an index buffer.
4) Repeat 2 and 3 until the whole floor is done.
You should really be looking to use methods 2 and 3 for a render like this though. If you are doing what i have suggested then paste your code.
Dave
1) Store a single quad in a vertex buffer and render individual tiles, one at a time.
2) Store all of the tiles in the vertex buffer and render them all together.
3) Use a mesh and render the entire mesh.
You should prefer either 2 or 3 for speed.
But, if you want to do it like 1) then you do it like this:
1) Put your quad in the vertex buffer, set up your index buffer as well.
2) Set the translation matrix for the current tile.
3) Draw the quad using DrawIndexedPrimitive() or DrawPrimitive() if you are not using an index buffer.
4) Repeat 2 and 3 until the whole floor is done.
You should really be looking to use methods 2 and 3 for a render like this though. If you are doing what i have suggested then paste your code.
Dave
When you set the world matrix your actually setting something that all vertices that you send to D3D will be transformed by. This is why you are getting all your vertices transformed at once. For something like a tiled floor, you have a several options (not all are good).
1. Pre-transform. When you pack your vertex buffer, you perform the translation for each tile BEFORE putting them into the buffer. Set the world matrix to identity and push the whole buffer through. 1 draw call, 1 vertex buffer.
2. Use multiple draw calls for each primitive changing the world matrix after each (this is probrably the slowest as it has poor batching). Multiple vertex buffers, multiple draw calls.
3. Pack everything into a single vertex buffer and maintain an array of transforms, send 1 primitive at a time, and then switch up the transform. 1 vertex buffer, multiple draw calls.
4. If your using a shader you can encode translation information for the tiles into a texture co-ordinate and have the shader translate the vertices for you. You can stuff everything into the 1 vertex buffer and do 1 draw call here also.
5. Hardware instancing, you can store 1 copy of the verts for the tile in 1 stream, and the translation data in a seperate stream. This is probrably not a great idea either, hardware instancing is ment for more complex meshes.
6. You could of course store a single quad (2 triangles) the size of your entire floor and just alter your texture co-ordinates to make the texture tile. Probrably the fastest method.
Hope this helps.
1. Pre-transform. When you pack your vertex buffer, you perform the translation for each tile BEFORE putting them into the buffer. Set the world matrix to identity and push the whole buffer through. 1 draw call, 1 vertex buffer.
2. Use multiple draw calls for each primitive changing the world matrix after each (this is probrably the slowest as it has poor batching). Multiple vertex buffers, multiple draw calls.
3. Pack everything into a single vertex buffer and maintain an array of transforms, send 1 primitive at a time, and then switch up the transform. 1 vertex buffer, multiple draw calls.
4. If your using a shader you can encode translation information for the tiles into a texture co-ordinate and have the shader translate the vertices for you. You can stuff everything into the 1 vertex buffer and do 1 draw call here also.
5. Hardware instancing, you can store 1 copy of the verts for the tile in 1 stream, and the translation data in a seperate stream. This is probrably not a great idea either, hardware instancing is ment for more complex meshes.
6. You could of course store a single quad (2 triangles) the size of your entire floor and just alter your texture co-ordinates to make the texture tile. Probrably the fastest method.
Hope this helps.
Thanks a lot for responding so quickly! Also I have one more question:
How would I move a model about a 3D World and only move the model, notthe whole world? Also does anyone know of some tutorials that are good for Direct3D 3D Game Programming or perhaps a tutorial that teaches you to make your first game in Direct3D?
How would I move a model about a 3D World and only move the model, notthe whole world? Also does anyone know of some tutorials that are good for Direct3D 3D Game Programming or perhaps a tutorial that teaches you to make your first game in Direct3D?
Again, your gonna want to do something similar one of the previous posts.
pDirect3DDevice9->SetTransform(D3DTS_WORLD, &GroundTransform);
RenderLevel();
pDirect3DDevice9->SetTransform(D3DTS_WORLD, &ModelTransform);
Render3DModel();
pDirect3DDevice9->SetTransform(D3DTS_WORLD, &GroundTransform);
RenderLevel();
pDirect3DDevice9->SetTransform(D3DTS_WORLD, &ModelTransform);
Render3DModel();
Thank you, also do you need one LPDIRECT3DVERTEXBUFFER9 for each CUSTOMVERTEX array. For example in this code:
d3ddev->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&t_buffer,
NULL);
VOID* pVoid; // a void pointer
// lock t_buffer and load the vertices into it
t_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, t_vert, sizeof(t_vert));
t_buffer->Unlock();
if we wanted to make another array of Vertices for something else would we also need to create another LPDIRECT3DVERTEXBUFFER or could we use another CreateVertxBuffer() function with the same Vertex Buffer (t_buffer) except for different vertices and could we memcpy those vertices into the same Void pointer or would we need to do the whole process over again with a different buffer and void pointer?
d3ddev->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&t_buffer,
NULL);
VOID* pVoid; // a void pointer
// lock t_buffer and load the vertices into it
t_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, t_vert, sizeof(t_vert));
t_buffer->Unlock();
if we wanted to make another array of Vertices for something else would we also need to create another LPDIRECT3DVERTEXBUFFER or could we use another CreateVertxBuffer() function with the same Vertex Buffer (t_buffer) except for different vertices and could we memcpy those vertices into the same Void pointer or would we need to do the whole process over again with a different buffer and void pointer?
New pointer, otherwise you'll have lost your old one :-) That's called a memory leak, maybe consider using some sort of COMPointer to stop this happening automatically :-)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement