Textures and terrain rendering

Started by
17 comments, last by Mescalito 21 years, 5 months ago
Hi I''m currently writing a terrain rendering engine with Direct3D (ver 8.1), the terrain is drawn with only one DrawPrimitive (I use triangle strip), and my pixel shader contains x,y and z positions, u and v texture coordonates and a diffuse color. I''ve got a problem when using textures. I want to work with 32*32 textures stored in a single texture(the bmp file is 256*256 so I''ve got 64 textures in one...) But I don''t know how to apply a texture to each triangle of my terrain (I know how to apply a single texture for the entire terrain but with many textures ??) Should I use another set of u & v texture coordonates ? How ? Thank you.
Advertisement
I just posted that exact same question a couple days ago, look here. I am trying to figure out the problem as well.

http://www.gamedev.net/community/forums/topic.asp?topic_id=119888

--------------------------Vantage: Greenlit on Steam / Independent Games Festival Submission http://www.crystaldragon.com

I can imagine you doing this two ways. When loading your terrain create a blank texture large enough to hold all of the tiles when they are paced on the geometry, and copy all of the individual tile''s texture''s into that one using device->copyrects. This way you can render the terrain from one texture that is a compilation of all the tiles. This is the method I would use - it''s very easy.

Another way, if you insist on each tile having it''s own texture is to render the terrains geometry in a loop, where each iteration you use device->settexture, and then give device->drawprimitive an argument that tells it what part of the vertex buffer to render from. I would not reccomend this method, it seems like it would be slower.
Yes, you use texture coords. Imagine one quad of your terrain...the texture coords of the quad are (0,0), (0,1), (1,1), and (1,0) respectively. This will map the ENTIRE texture over the quad.

But, of course, you don''t want that. You want the upper left subtexture in your larger texture. The subtexture covers 1/8th of your main texture in both the x and y directions. So, you need to set your coords to be (0,0), (0,.125), (.125, .125), (.125,0). 0.125 is 1/8 - if you had 16 textures in each of 16 rows, you''d want 1/16, etc.

To get the next texture over, you''d offset the texture coords by 1/8 in the X direction.

I hope this makes sense, as I''m typing quick and watching the football game. It''s the same technique I use - I have 64 256x256 textures packed into a 2048x2048 terrain texture. Also, you might have to add a little extra onto each texture to make sure you don''t include the last line of the texture next to the one you want to use.



First of all thank you for the posts.

Wolliwer, I understood what is is your way to do it.
I think it is easy to implement and it''s also a good way to implement other stuffs like shadows, terrain modifiers...
I''ll try this.

But what about the memory usage for it, it seems a good idea for small maps but for huge ones ? Is there a "better" ways (one who doesn''t need too much memory)

AJF, I didn''t understand what was your way.
I know all you said and I can implement that but for a given squad there are only 4 coordonates and not 8 ! So we have to use the same texture for the entire map ?!...
hi mescalito,

ajf solution i think is the best way indeed. i think his trying to say is, you have only one texture for your terrain. And it''s all up to you how big you like your terrain. Then when specifying their uv coordinates, you wouldn''t map each quad inside your VB to the whole texture but instead, you just map a piece/portion on the texture terrain,

this way, once call to settexture, one call to draw primitive,
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
I have spent all day yesterday, and today figure out this exact same problem. AJFs plan will not work at all, though it sounds like it would.

You cannot simply "offset" the texture coordinates for a triagngle strip of vertex data. Each point is passed only ONCE. For example, if you want your texture at (.125,.125) placed at your 0x0 terrain grid, and (.375,.375) at you 1x0 terrain grid you must remember your first quad goes from .125 to .250, then from .375 to .5. You must define 2 vertex points at the same place at point 1x0, because you must set one to end the triangle with .250 then start the next triangle at the same point using .375. I have spent countless hours trying to figure out this problem and the only way to do it is to add those extra vertex points into your index buffer. Then make a programmable vertex shader exactly how S1CA explained in my post (URL above).

I will let you know if I think of a better way.

--------------------------Vantage: Greenlit on Steam / Independent Games Festival Submission http://www.crystaldragon.com

I think one solution can be to use triangle list instead of triangle strip, so you can define an own UV map for every triangle!
programmer
Carradine, you can''t do what you are thinking you can do. A point can only have one set of texture coords in single-pass texturing. You have to store two points with the same world-space location in order to assign two different texture coords.

Unless, of course, you define your FVF format to contain more than one set of texture coords, and somehow know in your custom shader which set to used based on what triangle you are rendering.

I use triangle lists to string 2 triangles together for a quad, and draw on a quad by quad basis with one texture. Each set of four points in the buffer define one quad. Each set of four points is followed by another 4 points, 2 of which share the same physical location as 2 points in the previous quad. Yeah, it uses memory, but memory is cheap

Of course, this is just my solution and there''s always better. Good luck.
Thank you I''ll try it !

This topic is closed to new replies.

Advertisement