# OpenGL My terrain contains some strange line segments

This topic is 375 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey guys, I need your help again if somebody here would kindly help me out.

I recently loaded my very first terrain using a heightmap image for the first time. It worked great! However, I noticed some strange line segments that are being drawn from the top of the terrain stretching all the way down to the very bottom. I will post images of this below so you could see what I mean, I will also link you the resource I used to generate my terrain (which is really just 1 YouTube video) here:

" rel="external" style="background-color:#fafafa;color:#5381ac;font-size:13px;text-align:left;">

I'd be very thankful if somebody could review the code with me and help me identify the problem...

Oddly enough, the person in the YouTube video seemed to have had a very similar (if not the exact same) problem I am having at 18:38 but he fixed it by adding one simple thing which I also added but didn't do the trick for me  Also he is using the fixed function pipeline to demonstrate the technique, I am using the programmable pipeline for better performance. Anyway, here is the result of my terrain:

The unwanted line segments:

As you can see, I also have grass (very awful looking grass too :p) on top of my terrain while playing around with the geometry shader the other day.

Here is how I am loading the heightmap, and here is where I believe the problem lies:


void TerrainLoader::LoadHeightmapImage(const char* file)
{
Uint32 Pixel = 0;

// Check for errors
if (m_pImage == nullptr)
{
std::cerr << "error: Heightmap image could not be loaded.\n";
return;
}

// Get bitmap's width and height
m_HeightmapHeight = m_pImage->h;
m_HeightmapWidth = m_pImage->w;

// Read the bitmap (stores in this 2D STL vector of floats: vector<vector<float> > m_vHeights;)
std::vector<float> tmp;
for (int i = 0; i < m_HeightmapHeight; ++i)
{
for (int j = 0; j < m_HeightmapWidth; ++j)
{
Pixel = ((Uint32*)m_pImage->pixels)[i * m_pImage->pitch / 4 + j];
unsigned char r, g, b;
SDL_GetRGB(Pixel, m_pImage->format, &r, &g, &b);
tmp.push_back((float)r / 255.0);
}

m_vHeights.push_back(tmp);
tmp.clear();
}

SDL_FreeSurface(m_pImage);

float h = 0.4f, terrainSize = 0.005f;

std::vector<glm::vec3> Vertices;
std::vector<glm::vec2> Textures;

for (int i = 0; i < m_vHeights.size() - 1; ++i)
{
for (int j = 0; j < m_vHeights.size() - 1; ++j)
{
// Put the vertices and texture coordinates in their respective buffers
Textures.push_back(glm::vec2(0.0f, 0.0f));
Vertices.push_back(glm::vec3(i * terrainSize, m_vHeights[j] * h, j * terrainSize));

Textures.push_back(glm::vec2(1.0f, 0.0f));
Vertices.push_back(glm::vec3((i + 1) * terrainSize, m_vHeights[i + 1][j] * h, j * terrainSize));

Textures.push_back(glm::vec2(1.0f, 1.0f));
Vertices.push_back(glm::vec3(i * terrainSize, m_vHeights[j + 1] * h, (j + 1) * terrainSize));

Textures.push_back(glm::vec2(0.0f, 1.0f));
Vertices.push_back(glm::vec3((i + 1) * terrainSize, m_vHeights[i + 1][j + 1] * h, (j + 1) * terrainSize));
}
}

// Send the data to the GPU
glGenVertexArrays(1, &m_VAO);
glBindVertexArray(m_VAO);

glGenBuffers(1, &m_VBO[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO[0]);
glBufferData(GL_ARRAY_BUFFER, Vertices.size() * sizeof(glm::vec3), &Vertices[0], GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

glGenBuffers(1, &m_VBO[1]);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO[1]);
glBufferData(GL_ARRAY_BUFFER, Textures.size() * sizeof(glm::vec2), &Textures[0], GL_STATIC_DRAW);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

// This concludes the function
}

Then, this is how I'm simply drawing the terrain to the scene:

void TerrainLoader::Draw()
{
glBindVertexArray(m_VAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (m_HeightmapWidth - 1) * (m_HeightmapHeight - 1) * 4);
}

Alright, I hope that's enough information for someone to help me figure out the issue with this...

Thank you very much for taking the time to read my thread, I really appreciate it! Enjoy your day!

Edited by MaimaVanPersie

##### Share on other sites

Only had a very brief look, but wild guess, off by one error? i.e. to make a fence 10 metres long with fenceposts every 1 metre, you need 11 fenceposts, not 10...

Edit .. Ah no I think I see it ... you are using triangle strip, are you using an index buffer too? You need to reset the triangle strip after each row with a degenerate triangle or something like that.

Edited by lawnjelly

##### Share on other sites

If indexed draw, the glDrawElements call would be used to fire the render. I'm looking at the third parameter calculation in the glDrawArrays call as the bad guy, as a guess because it seems way too many for triangle strip.

Edit: looks like you're not building your triangle strip properly. Graph what you're doing on paper of what your double for loop does. When the loop starts, the first two triangles are correct. At the second iteration the first and second triangles are degenerate then the third and fourth fill the grid location hiding the problem. The error is repeated to the end. When a grid like this is built using triangle strip, a degenerate triangle is needed when you complete building a row and advance to the next row then repeat.

Edited by GoliathForge
Came back after work to look proper.

##### Share on other sites

On 9/29/2017 at 1:09 AM, lawnjelly said:

Edit .. Ah no I think I see it ... you are using triangle strip, are you using an index buffer too? You need to reset the triangle strip after each row with a degenerate triangle or something like that.

I'm not using an index buffer to draw my triangles, how do I reset the triangle strip after each row?

##### Share on other sites

Okay, problem fixed (FINALY!!!). Thank you so much for the help guys. Here's what I did for anyone interested, I stopped using triangle strips and I used indices instead with GL_TRIANGLES. That fixed the problem. I'm really glad I fixed this, for whoever encounters this problem and somehow stumbles upon this thread in the future, there were numerous solutions I researched to fixing this issue, I simply chose the indices/triangle approach as it seemed simple, but I will leave links for you here:

https://gamedev.stackexchange.com/questions/143448/opentk-terrain-triangle-strip-issue (<-- This is basically my problem)

The problem is really mentioned by the users above. I am very thankful for your help guys!

##### Share on other sites
15 hours ago, MaimaVanPersie said:

Okay, problem fixed (FINALY!!!). Thank you so much for the help guys. Here's what I did for anyone interested, I stopped using triangle strips and I used indices instead with GL_TRIANGLES. That fixed the problem. I'm really glad I fixed this, for whoever encounters this problem and somehow stumbles upon this thread in the future, there were numerous solutions I researched to fixing this issue, I simply chose the indices/triangle approach as it seemed simple, but I will leave links for you here:

https://gamedev.stackexchange.com/questions/143448/opentk-terrain-triangle-strip-issue (<-- This is basically my problem)

The problem is really mentioned by the users above. I am very thankful for your help guys!

The indexed triangle list is indeed the right thing to use, but you need to generate a proper triangle index ordering or your GPU will have very poor cache utilization. There is many tool and algo to optimize this NP complete problem, one i like is this one : https://tomforsyth1000.github.io/papers/fast_vert_cache_opt.html

1. 1
2. 2
Rutin
18
3. 3
4. 4
5. 5

• 9
• 14
• 9
• 9
• 9
• ### Forum Statistics

• Total Topics
632919
• Total Posts
3009208
• ### Who's Online (See full list)

There are no registered users currently online

×