scott_r_howell
scott_r_howell

Reputation: 121

C++ OpenGL Large Mesh is missing triangles

So I'm putting together a height map renderer that will do most of the work int he vertex shader, but first of course I generate a mesh to render, at the moment I'm playing around with upper limits of openGL and C++ to see how dense a mesh I can render (so I later have something to go by in terms of LoD mesh dividing)

ANYWAY! to cut to the issue;

the issue I noticed after testing a meshResolution of 32, 64 and at 128 I experienced runtime crashes, I stopped them by using the a self made class "indexFace" which holds 6 indices to lower the array length, problem is at 128 resolution only a 3rd of the mesh actually displays, I was wondering if there was a limit to how many indices openGL can render or hold using 1 set of BufferObjects or if its an issue with my handling of the C++ side of things.

I'm generating the mesh via the following:

void HeightMapMesh::GenerateMesh(GLfloat meshScale, GLushort meshResolution)
{
    GLushort vertexCount = (meshResolution + 1) * (meshResolution + 1);
    Vertex_Texture* vertexData = new Vertex_Texture[vertexCount];
    GLushort indexCount = (meshResolution * meshResolution) * 6;

//indexFace holds 6 GLushort's in an attempt to overcome the array size limit
    indexFace* indexData = new indexFace[meshResolution * meshResolution];
    GLfloat scalar = meshScale / ((GLfloat)meshResolution);
    GLfloat posX = 0;
    GLfloat posY = 0;
    for (int x = 0; x <= meshResolution; x++)
    {
        posX = ((GLfloat)x) * scalar;
        for (int y = 0; y <= meshResolution; y++)
        {
            posY = ((GLfloat)y) * scalar;
            vertexData[y + (x * (meshResolution + 1))] = Vertex_Texture(posX, posY, 0.0f, x, y);
        }
    }
    GLint indexPosition;
    GLint TL, TR, BL, BR;
    for (int x = 0; x < meshResolution; x++)
    {
        for (int y = 0; y < meshResolution; y++)
        {
            indexPosition = (y + (x * (meshResolution)));
            BL = y + (x * (meshResolution + 1));
            TL = y + 1 + (x * (meshResolution + 1));
            BR = y + ((x + 1) * (meshResolution + 1));
            TR = y + 1 + ((x + 1) * (meshResolution + 1));
            indexData[indexPosition] = indexFace(
                    BL, TR, TL,
                    BL, BR, TR
                    );
        }
    }
    mesh.Fill(vertexData, vertexCount, (void *)indexData, indexCount, GL_STATIC_DRAW, GL_STATIC_DRAW);
    delete [] vertexData;
    delete [] indexData;
}

//This is for mesh.Fill()
    void Fill(T* vertData, GLushort vertCount, void* indData, GLushort indCount, GLenum vertUsage, GLenum indUsage)
    {
        indexCount = indCount;
        vertexCount = vertCount;
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectID);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObjectID);
        glBufferData(GL_ARRAY_BUFFER, sizeof(T) * vertexCount, vertData, vertUsage);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indexCount, indData, indUsage);
    }

Upvotes: 1

Views: 548

Answers (1)

PeterT
PeterT

Reputation: 8284

its because you made your indices shorts.

For example this: GLushort indexCount = (meshResolution * meshResolution) * 6; is hitting USHRT_MAX at a value of 105 for meshResolution. (105*105*6 = 66150 > 65535)

Use ints as indices. So change your indices everywhere to unsigned ints and do the final draw call like this:

glDrawElements( GL_QUADS, indCount, GL_UNSIGNED_INT, indices); //do this
//glDrawElements( GL_QUADS, indCount, GL_UNSIGNED_SHORT, indices); //instead of this
//also GL_QUADS is deprecated but it seems your data is in that format so I left it that way

You could save a bunch of indices if you drew GL_TRIANGLE_STRIPs instead or better yet do tesselation on the GPU, since this is like the perfect use-case for it.

Upvotes: 1

Related Questions