0

I'm building a heightmap out of a 2D array of shorts. The code to generate the vertices is

MeshVertex v; // has position, normal, and texCoord fields
v.position = glm::vec3(
     (float) x * 150,
     height * 64,
     (float) z * 150
);

When I generate the indices for the terrain mesh, I followed the tutorial on learnopengl.com, where I loop through each row, loop through each column, and assign the two sets of indices for the two triangles in each cell.

for(unsigned int i = 0; i < mapSize-1; i++)       // for each row a.k.a. each strip
{
    for(unsigned int j = 0; j < mapSize; j++)      // for each column
    {
        for(unsigned int k = 0; k < 2; k++)      // for each side of the strip
        {
            indices.push_back(j + mapSize * (i + k));
        }
    }
}

Lastly, I thought GL_TRIANGLE_STRIP draws the tris in a counter clockwise direction, based on indices 0, 1, 2; 2, 1, 3 as per wikipedia. Assuming 0-based numbering, wouldn't this mean that vertices 1 and 4 share a texture coordinate and vertices 2 and 3 share a texture coordinate? I'm building my texture coords based on this with the following code

switch(index % 6) {
    case 0:
        v.texCoords = glm::vec2(0, (bandHeight * 1) + bandHeight);
        break;
    case 1:
    case 4:
        v.texCoords = glm::vec2(0, (bandHeight * 1));
        break;
    case 2:
    case 3:
        v.texCoords = glm::vec2(1, (bandHeight * 1));
        break;
    case 5:
        v.texCoords = glm::vec2(1, (bandHeight * 1) + bandHeight);
        break;
}

I don't know that it's relevant, but the bandHeight variable is due to my textures being a variable length vertical image of subimages, where the first texture is row 0, second texture is row 1, etc. That's all that is, with 1 meaning we're looking at the second texture, which I've hardcoded just for testing.

When I render the terrain mesh, only one quad in every 6 looks right. The rest are warped, and I'm not sure why. What is the right formula for generating texture coordinates based on which index the loop is processing?

incorrect texture

Here's what a full picture of the terrain looks like, with each cell having the texture coordinates generated with the current cell's intended texture.

full range of textures

Edit

As there have been some votes to close the question as "not enough code to reproduce", here's a link to the full repository. You'll need your own copy of HUNTDAT from Carnivores2; I can't provide that due to copyright reasons. It can easily be found through some google searches, though.

It compiles on Windows 10 with MinGW 8, although the cmakelists file should be easy enough to customize to other platforms.

The file that generates the terrain is found here.

Goldentoa11
  • 1,700
  • 2
  • 17
  • 29
  • "Assuming 0-based numbering, wouldn't this mean that vertices 1 and 4 share a texture coordinate and vertices 2 and 3 share a texture coordinate?" That doesn't make the slightest sense. Different vertices don't share texture coordinates, not in any meaningful way at least. The triangles share vertices. If you draw a triangle strip `0,1,2,3`, to represent a quad, you'll have 4 individual vertices with unique texcoords each, the whole `switch(index % 6)` doesn't make sense at all. – derhass Apr 22 '22 at 17:05
  • 1
    The original map data stores the texture id to use for the vertex, as opposed to the coordinate within the texture. That's why I have that `switch(index % 6)` - so I can generate the correct coordinate for the texture based on whether the vertex is lower left, upper left, lower right, or upper right? Does that make any sense? – Goldentoa11 Apr 22 '22 at 18:12
  • No, not the slightest. Your vertex array is just a grid of `mapsize*mapsize` vertices, and the index array you set up just connects each grid cell to a quad, so there are just 4 vertices per quad, not 6. `index % 6` doesn't relate to anything meaningful at all in this scenario. Neither does `index %4`, btw. – derhass Apr 22 '22 at 18:22
  • However, you have a much bigger problem here: your data structure doesn't match the input data you want to represent here: "so I can generate the correct coordinate for the texture based on whether the vertex is lower left, upper left, lower right, or upper right?" That's not how your structure works: Every vertex (apart from the ones on the boundary) is used as upper left, lower left, upper right and lower right _at the same time_. It's part of 4 adjacent quads. – derhass Apr 22 '22 at 18:24
  • Providing a link to the full code makes the question close-worthy for the opposite problem: too *much* code. Ideally your question will have only the smallest amount of code needed to make the problem happen. – user253751 Apr 26 '22 at 11:14
  • Given that any real-life problem is going to be a web of dependencies due to encapsulation (ie Terrain extends from Entity, which to be drawn requires the State, which needs a Renderer, etc, etc, etc), I don't know of any other way to do it. I agree that there's "too much code", but there's not really any other way to do it. – Goldentoa11 Apr 26 '22 at 13:42

0 Answers0