Textures in D3D
My problem is this: DrawIndexedPrimitive can render a bunch of triangles at once, but they all have to use the same texture, correct?
I have a list of transformed & lit vertices and a list of indices that I was originally planning to pass to DrawIndexedPrimitive. There are about 10K triangles here. Since I want to specify the texture for each triangle, though, its sounds like I will have to go through the list one element at a time, setting up a SetTexture call and a DrawPrimitive call for every individual triangle.
This seems inefficient and I was wondering if there is a btter way to do this.
Here would be my ideal solution, though I doubt it is possible:
(1) set all my textures at the start of the render process. I can limit the number of textures to 8, so perhaps one could go in each texture stage.
(2) specify a particular texture for each *vertex*. Maybe a vertex can indicate a particular texture stage? I guess this raises the question, "what if one vertex of a triangle specifies one texture, and the other two specify different textures?". In this case I would actually like the two textures to be blended (i.e. fade from one to the other across the triangle). I don''t know exactly how ridiculous or unrealistic this is, because I don''t know much about texture stages.
By the way, I''m rendering terrain here. I have a 2D array of heights, and I''m rendering each "cell" with 2 right triangles (well, it''s a bit more complex than that). Anyway, that''s where my list of 10K triangles is coming from.
Right - going through for each triangle and doing settexture/drawprimitive is a bad and very time consuming process. I don''t suggest it - your performance will be hit considerably.
As to idea 1 - ick. Not nice. You don''t want to clutter up the card with all those textures and some cards don''t even handle 8 stages. It would also not work.
Idea 2 - per vertex texture *argh* going even further off the track I think.
The suggestion I have for you is that you store the triangles by texture after you have transformed & lit them.
Write some sort of class/routines that means that you can add textures to a list then attach tris to these texture entrys. After you have finished transforming/lighting all your vertices you can then run through each texture do a settexture then render the relavent vertices. This will probably give you a nice framerate aswell since you avoid the slowdown of the settexture being done too many times.
As to idea 1 - ick. Not nice. You don''t want to clutter up the card with all those textures and some cards don''t even handle 8 stages. It would also not work.
Idea 2 - per vertex texture *argh* going even further off the track I think.
The suggestion I have for you is that you store the triangles by texture after you have transformed & lit them.
Write some sort of class/routines that means that you can add textures to a list then attach tris to these texture entrys. After you have finished transforming/lighting all your vertices you can then run through each texture do a settexture then render the relavent vertices. This will probably give you a nice framerate aswell since you avoid the slowdown of the settexture being done too many times.
If you''re transforming and lighting before calling DrawPrimitive, you won''t be able to take advantage of TnL cards, which I expect in time to become the ''norm''. Why bother transforming them first anyway, because if the camera moves every frame you won''t save much time. Also, unless your transformation routine is optimised, you''re best of letting Direct3D do it in DrawPrimitive (as ProcessVertices is slow). So I recommend sending untransformed and unlit vertices.
You should group by texture as Mr.Flibble says. Also, to minimise texture changes, use large textures that cover as much triangles as possible eg 256x256. You''ll probably need to compile some smaller textures (each of a particular terrain type) into the big texture (but you''ll want to do this anyway if you want smooth blending of textures).
You should group by texture as Mr.Flibble says. Also, to minimise texture changes, use large textures that cover as much triangles as possible eg 256x256. You''ll probably need to compile some smaller textures (each of a particular terrain type) into the big texture (but you''ll want to do this anyway if you want smooth blending of textures).
Ok, so if I have 8 textures, I'll just have 1 vertex list and 8 index lists (and only 8 DrawIndexedPrimitive calls). Geez, this solution seems so obvious now... I guess I just didn't think of grouping tri's by texture. Thanks MrFlibble.
Palm, I just realized that you're right, there's no point in me transforming the vertices myself (the light is pre-calculated, though). So that's cool, now I can use hardware TnL (or the "T" anyway, right? ).
Now, perhaps someone can help me with the texture blending:
Like Palm suggested, I'm planning on 256x256 textures for each type of terrain. A texture will span 8-16 triangles. Currently I'm just using each tri's world-space (x,z) coords (scaled down) as the texture coords (I'm relying on the "wrap" addressing mode).
Like I mentioned before, I want to blend the two textures at the boundary between different types of terrain. I know that I *should* pre-render these blended textures on to a new texture, but I'm lazy and also pressed for time on this project. Also, there are relatively few of these triangles. So, is there an easy way to do this without setting up additional textures? Let me clarify something: For any blended tri, 2 vertices will be one texture, the other will be different. In other words, the boundary is exactly one triangle wide.
Edited by - Eric on May 11, 2000 2:53:49 PM
Palm, I just realized that you're right, there's no point in me transforming the vertices myself (the light is pre-calculated, though). So that's cool, now I can use hardware TnL (or the "T" anyway, right? ).
Now, perhaps someone can help me with the texture blending:
Like Palm suggested, I'm planning on 256x256 textures for each type of terrain. A texture will span 8-16 triangles. Currently I'm just using each tri's world-space (x,z) coords (scaled down) as the texture coords (I'm relying on the "wrap" addressing mode).
Like I mentioned before, I want to blend the two textures at the boundary between different types of terrain. I know that I *should* pre-render these blended textures on to a new texture, but I'm lazy and also pressed for time on this project. Also, there are relatively few of these triangles. So, is there an easy way to do this without setting up additional textures? Let me clarify something: For any blended tri, 2 vertices will be one texture, the other will be different. In other words, the boundary is exactly one triangle wide.
Edited by - Eric on May 11, 2000 2:53:49 PM
To be even more efficent if you could somehow corralate the 8 index lists into one at run-time i.e. build a large index list of triangles that are to be drawn from the same vertex list then only make one DIP call that''d probably help aswell.
As to the blending across texture changes. I can''t really see anyway around it without creating a new transitional texture really. This sort of boundary crossing can be done in two ways (thinking quickly here):
1) A texture which mixes between the 2 land types i.e. grass->desert/sand, grass->snow/ice.
2) Create a texture that can blend across the section
i.e. base texture = grass, blend over top = sand overlay (which is partly transparent in places to give a correct blend effect).
To be honest, both are probably as good as each other, but the 2nd one would probably take longer to implement correctly.
As to the blending across texture changes. I can''t really see anyway around it without creating a new transitional texture really. This sort of boundary crossing can be done in two ways (thinking quickly here):
1) A texture which mixes between the 2 land types i.e. grass->desert/sand, grass->snow/ice.
2) Create a texture that can blend across the section
i.e. base texture = grass, blend over top = sand overlay (which is partly transparent in places to give a correct blend effect).
To be honest, both are probably as good as each other, but the 2nd one would probably take longer to implement correctly.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement