Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Eric

transforming D3D vertices efficiently (when & how)

This topic is 6914 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 my current project, I have a single vertex list that is used in about 8 different DrawIndexedPrimitive calls. Each DrawIndexedPrimitive call uses a different texture, so I don't think the calls & corresponding index lists can be combined. My vertices originate from a height map and need to be transformed at some point every frame. I can think of 3 options: 1) Use height map data to create a list of transformed vertices. This would involve manually multiplying the world-space coords by my matrix. Pass this to each DrawIndexedPrimitive call. 2) Use height map data to create a list untransformed vertices. Use ProcessVertices to create a transformed vertex list, and pass this to each DrawIndexedPrimitive call. Particularly if hardware TnL is present, ProcessVertices will probably be faster than do-it-yourself (right?), but the memory transfer from source buffer to dest buffer (including pre-calced light & texture data) would cost a little. 3) Use height map data to create a list of untransformed vertices. Pass this to each DrawIndexedPrimitive call. Some of the calls would use the same vertices, so probably about 10% of the vertices would get transformed more than once by the function. So which would be fastest? Or is there another, better way? Any opinions are much appreciated Edited by - Eric on 5/14/00 12:49:16 AM

Share this post


Link to post
Share on other sites
Advertisement
I recommend using the heightmap data to create a Vertex Buffer with untransformed vertices. Then use the VB in each DrawIndexedPrimitiveVB(). This will ensure that the vertices are transformed only once.

If you don''t have TnL I you should put the vertices in the VB, then call ProcessVertices() to transform them once, then use DrawIndexedPrimitiveVB() to render from them.

Here''s a few comments on your ideas:

ProcessVertices() cannot utilize the hardware acceleration of TnL because it need the result after transformation. Because of that ProcessVertices() are always done in software.

DrawIndexedPrimitive() should not be used to render from the same vertices more than once, this because _all_ the supplied vertices are transformed _every_ time.

- WitchLord

Share this post


Link to post
Share on other sites
I don''t agree with putting all the vertices in one vertex buffer.

Firstly, I don''t like ProcessVertices and think it should be avoided, because it involves Direct3D copying transformed data back into a vertex buffer, whereas just sending untransformed data doesn''t involve copying the data back. ProcessVertices is justified if you intend to use the transformed data for several frames, but not if you need to transform the data every frame (ie moving camera).

Secondly, if you render from the same vertex buffer in subsequent calls, you should try and use different parts of the vertex buffer, or else you will stall the 3D rendering. That is, you will have to wait for the first call to unlock the vertex buffer... basically it slows it down.

So if you separate reused vertices, you may as well put it in different vertex buffers and just use DrawIndexedPrimitive and untransformed vertices (ie no.3).

Share this post


Link to post
Share on other sites
Hi Eric--
I had the same problem. Unfortunately, there is no easy way to fix it. I myself don''t understand how all these APIs didn''t let you specify the texture coordinate when you send the triangle, and not the vertex, but that''s just me.

What I ended up doing was this: I pre-transform all my vertices (using DirectX ProcessVertices. The downsize of this is that you can''t use hardware TNL, but sometimes you gotta make the call).

Then, I use the transformed data and draw UNTRANSFORMED/unlit vertices to the screen, just duplicating any vertices that need to use texture.

I only saved about 10% speed, though. Probably not worth it.


-- Goodlife

-----------------------------
Think of your mind as a door on a house. Leave the door always closed, and it's not a house, it's a prison. Leave the door always open, and it's not a house, it's a wilderness-- all the vermin creep in.

Share this post


Link to post
Share on other sites
How many texturing passes are you going to make? Assuming that you might need to make 4 passes (if each corner has a different texture) you''re much better off blending the texture once, storing it somewhere, and using that texture for the duration of the program.

This will use up a lot of texture memory if you have a large landscape, but then you can move to dynamic blending, where you only create the texture when it comes into view.

Its a much better approach in the long-run if youre worried about speed.

Share this post


Link to post
Share on other sites
I appreciate your help, everyone, and I thought I''d let you know what I ended up doing.

It turns out I need to transform the vertices myself, one by one, before adding them to any vertex list. This is because of how my vertex list is set up:

terrainVertices[ z * terrainWidth + x ] == vertex at height-map (x,z) coord

Because of my LOD algorithm, I don''t actually have vertices at every (x,z) coord, hence my vertex list has "holes" in it -- un-used, uninitialized elements. If I pass the vertex list untransformed, DirectX wouldn''t know which elements actually contain vertex data and which don''t, so it would end up transforming a bunch of junk data. Also, note that I''m only rendering a small rectangular portion of my height-map each frame, in case you''re wondering why I can''t do a lot of this in advance.

Palm: I talked about my texture blending in
this thread
.

Screenshot -- craters like the one shown will be created in real-time, via land mines & other toys

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!