سؤال

I've just finished my heightmap, rendered with triangle strip per row. My solution was:

height=data[k];
coords.push_back((float)col);
coords.push_back((float)(height/heightscale));
coords.push_back((float)row);
k+=3; //red is enough, im using greyscale

and the indexes for the strip:

for(int row=0;row<infoheader.biHeight-1;row++)
   {
    for(int col=0;col<infoheader.biWidth;col++)
    {
        indexes.push_back((row+1)*infoheader.biWidth+col);
        indexes.push_back(row*infoheader.biWidth+col);
    }
   }

I use a VertexArrayObject and drawelements in a loop per row. Now I'm using it with a single shader coloring based on height, but i want it to combine with textures(also based on height but still not thats my problem)

I want to put the texture on 2 triangles forming a quad,

0,1-1,1     
 |  /|
 | / |
 |/  |
0,0-1,0

...but I really have no idea how to implement it, I've read all topics about this but they didn't work(only solid color appeared or the whole map was black).

So, is it possible to make an array only for the first "quad" (2 triangles) and it textures the whole map based on it by for example increasing the indexes? If yes how can i do this. And one more: how can I put 1 texture on top of the whole map, scaling it over the terrain.

I could do them with a single quad or a triangle strip with 2 triangles, but not for ~3 000 000 triangles.

The main problem is the indexing, because if I'm right, it draws not only the vertice position based on the indexes but the colors and texture coordinates.

my map: http://kepfeltoltes.hu/view/130827/1094341850Untitled_www.kepfeltoltes.hu_.png I know its a pretty "overasked" question but I still have not found the right way. EDIT: I want to tile textures.

هل كانت مفيدة؟

المحلول

I will make the following assumptions (which can be relaxed but you'll get my drift) about your mesh and texture:

  • they are both square shaped
  • the mesh's extents in x and z range from 0 to TERRAIN_WIDTH (which is some positive integer, inclusive).

If the above assumptions hold, your texture coordinates for some vertex of your terrain mesh

v = (v_x, v_y, v_z)

is simply

texcoord = (v_x / TERRAIN_WIDTH, v_z / TERRAIN_WIDTH)

This texcoord is passed to your fragment shader and used for texture lookups. You can generate this texcoord directly inside your vertex shader using either a const value, or better, a uniform value.

uniform float TERRAIN_WIDTH; // or a less flexible const float TERRAIN_WIDTH;
uniform mat4  ModelViewProjection;

in  vec4 Position; // x and z assumed to be in 0 .. TERRAIN_WIDTH (inclusive)

out vec2 TexCoord;

void main()
{
    TexCoord    = Position.xz / TERRAIN_WIDTH:
    gl_Position = ModelViewProjection * Position;
}

Warning: Untested code!

EDIT: In regards to tiling: The above does still hold. However, TERRAIN_WIDTH should be replace with something like TILE_WIDTH. I still assume an overall square mesh and square tiles.

For instance, if you terrain has dimensions 256x256 and is made up of 4 tiles with dimensions 128x128, the texcoords for the vertex at (240, 0, 240) are computed as:

texcoord = (240 / TILE_WIDTH, 240 / TILE_WIDTH) = (240 / 128, 240 / 128) = (1.875, 1.875)

Using GL_REPEAT as the TEXTURE_WRAP_S and TEXTURE_WRAP_T mode (the default), the integer part (i.e. 1) will simply be ignored and the resulting texcoord is (0.875, 0.875).

You can see, this is again in [0, 1] and will lookup the same texel for (240, 0, 240) as for (112, 0, 112). Thus, you get your tiling effect using the same texture.

Note: For tiling to work visually, your texture need to be tiling as well or the illusion will literally burst at the seams. ;)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top