i was following this tutorial here: https://www.youtube.com/watch?v=yNYwZMmgTJk, in which i was translating from Java to C++ to generate a terrain, and stumbled across this issue:


As it appears, it is rendering lines instead of triangles. i have checked, glDrawArrays() which was drawing triangles like normal. i checked the generator and the textures which was normal. But when i put in verticies manually it drew the terrain normally. This then leads to me suspecting that the error is in the terrain generator. another possibility, but least likely, is that i suspect is that i am not passing the data to the vertex and fragment shader correctly.

here is the terrain generator code:

const int vertex_count = 128;
const int size = 800;

GLfloat vert[(vertex_count * vertex_count) * 3]{

GLfloat norm[(vertex_count * vertex_count) * 3]{

GLfloat texCoord[(vertex_count * vertex_count) * 2]{

int vertexPointer = 0;

for (int i = 0; i < vertex_count; i++) {
    for (int j= 0; j < vertex_count; j++) {
        vert[vertexPointer * 3] = -(float)j / ((float)vertex_count - 1) * size;
        vert[vertexPointer * 3 + 1] = 0;
        vert[vertexPointer * 3 + 2] = -(float)i / ((float)vertex_count - 1) * size;

        norm[vertexPointer * 3] = 0;
        norm[vertexPointer * 3 + 1] = 1;
        norm[vertexPointer * 3 + 2] = 0;

        texCoord[vertexPointer * 2] = (float)j / ((float)vertex_count - 1);
        texCoord[vertexPointer * 2 + 1] = (float)i / ((float)vertex_count - 1);


and glDrawArrays():

 glDrawArrays(GL_TRIANGLES, 0, sizeof(vert));

and passing the data to the fragment and vertex shaders:

GLuint vao, vbo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(vert), vert, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

GLuint vbo2;
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

GLuint vbo3;
glGenBuffers(1, &vbo3);
glBindBuffer(GL_ARRAY_BUFFER, vbo3);
glBufferData(GL_ARRAY_BUFFER, sizeof(norm), norm, GL_STATIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);

You appear to be writing your vertices in a straight line.

That is, vertex0 has position (0,0,0). vertex1 has position (-6,0,0). vertex2 has position (-12,0,0). vertex3 has position (-18,0,0), and so on. Once you've finished all 128 vertices along one strip, you move back to the start and then specify vertex128 (0,0,-6). (and then (-6,0,-6), (-12,0,-6), and so on)

glDrawArrays(), when called using GL_TRIANGLES, expects to receive vertices in triples, defining the triangles to be drawn. So it looks at vertex 0, 1, and 2, and draws a triangle between those three points. In your case, vertices 0, 1, 2 (and in fact, everything up to vertex 127) are all completely in line with each other. So trying to draw triangles between any of them will end up looking like a line.

The standard thing to do here would be to use glDrawElements() instead of glDrawArrays(), and provide another data buffer containing the vertex indices of the triangles you want to draw (that buffer might start as {0,1,128, 1,129,128, ...} and so on.

But if you want to stick with glDrawArrays(), then you'll need to modify how you build that vertex buffer (and the normals and texture coordinates as well) so that the vertices in the buffer, when taken in consecutive sets of three, form the triangles that you actually want glDrawArrays() to draw. (note that this would require multiple copies of most vertices, since most vertices in your grid will be used in multiple triangles)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.