glDrawElements not drawing all of my triangles

im trying to remake my voxel engine in c++ so i took some vertex data from my c# code and ported it to c++ using glm and im using the same face indices and its not drawing 2 of the faces

i put the code in paste bin since im new to the forums and i don’t know how to add a code block

im only 14 so hint’s wont help that much

code → source to help me with - Pastebin.com

included below:

buffer utils class
void BufferUtil::Vec3BufferData(std::vector<glm::vec3> data,int attrib)
{
    glBufferData(GL_ARRAY_BUFFER, sizeof(data) * sizeof(glm::vec3), data.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(attrib, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
    glEnableVertexAttribArray(attrib);
}
void BufferUtil::Vec2BufferData(std::vector<glm::vec2> data, int attrib)
{
    glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(glm::vec2), data.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), (void*)0);
    glEnableVertexAttribArray(attrib);
}
void BufferUtil::Vec4BufferData(std::vector<glm::vec4> data,int attrib)
{
    glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(glm::vec4), data.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(attrib, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (void*)0);
    glEnableVertexAttribArray(attrib);

}
void BufferUtil::IntBufferData(std::vector<int> data, int attrib)
{
    glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(unsigned int), data.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(attrib, 1, GL_INT, GL_FALSE, sizeof(unsigned int), (void*)0);
    glEnableVertexAttribArray(attrib);
}
void BufferUtil::IntElementData(std::vector<unsigned int> data)
{
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.size() * sizeof(unsigned int), &data[0], GL_STATIC_DRAW);
}
void BufferUtil::CreateVec3Buffer(std::vector<glm::vec3> data, unsigned int buffer, int attrib)
{
    if (buffer <= 0)
    {
    }
    glGenBuffers(1, &buffer);

    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    Vec3BufferData(data, attrib);
}
void BufferUtil::CreateVec2Buffer(std::vector<glm::vec2> data, unsigned int buffer, int attrib)
{
    if (buffer <= 0)
    {
    }
    glGenBuffers(1, &buffer);

    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    Vec2BufferData(data, attrib);
}
void BufferUtil::CreateVec4Buffer(std::vector<glm::vec4> data, unsigned int buffer, int attrib)
{
    if (buffer <= 0)
    {
    }
    glGenBuffers(1, &buffer);

    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    Vec4BufferData(data, attrib);
}
void BufferUtil::CreateIndexBuffer(std::vector<unsigned int> data, unsigned int buffer)
{
    if (buffer <= 0)
    {
    }
    glGenBuffers(1, &buffer);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
    IntElementData(data);
}
----------------------------

mesh class

Mesh::Mesh()
{


}
int Mesh::GetVertexCount()
{
    return Vertices.size();
}
void Mesh::Upload()
{
    glGenVertexArrays(1, &VAO);
    
    glBindVertexArray(VAO);
    BufferUtil::CreateVec3Buffer(Vertices, VBO, 0);
    BufferUtil::CreateIndexBuffer(Indices, IBO);
    if (UV.size() > 0)
    {
        BufferUtil::CreateVec2Buffer(UV, TBO, 1);
    }
    if (Colors.size() > 0)
    {
        BufferUtil::CreateVec4Buffer(Colors, CBO, 2);
    }
}
void Mesh::Draw()
{

    if (UV.size() > 0)
    {
        glEnableVertexAttribArray(1);
    }
    if (Colors.size() > 0)
    {
        glEnableVertexAttribArray(2);
    }

    glBindVertexArray(VAO);

    glDrawElements(GL_TRIANGLES, sizeof(GLuint) * Indices.size(), GL_UNSIGNED_INT, 0);

    glBindVertexArray(0);

    if (UV.size() > 0)
    {
        glDisableVertexAttribArray(1);
    }
    if (Colors.size() > 0)
    {
        glDisableVertexAttribArray(1);
    }
}

voxel meshing function
void ChunkMesher::AddFaceToMesh(int x, int y, int z, VoxelFace Face, Mesh& mesh)
{
    int VertOffset = mesh.GetVertexCount();
    int faceid = (int)Face;

    glm::vec3 pos = glm::vec3(x, y, z);

    for (int i = 0;i < sizeof(Indices) / sizeof(Indices[0]);i++)
    {
        mesh.Indices.push_back(Indices[i] + VertOffset);
    }
    switch (Face)
    {
        case VoxelFace::Left:
            AddQuad(Vertices[0] + pos, Vertices[1] + pos, Vertices[2] + pos, Vertices[3] + pos, mesh);
            AddUV(0, 0, mesh);
            break;
        case VoxelFace::Right:
            AddQuad(Vertices[4] + pos, Vertices[5] + pos, Vertices[6] + pos, Vertices[7] + pos, mesh);
            AddUV(0, 0, mesh);
            break;
        case VoxelFace::Bottom:
            AddQuad(Vertices[8] + pos, Vertices[9] + pos, Vertices[10] + pos, Vertices[11] + pos, mesh);
            AddUV(0, 0, mesh);
            break;
        case VoxelFace::Top:
            AddQuad(Vertices[12] + pos, Vertices[13] + pos, Vertices[14] + pos, Vertices[15] + pos, mesh);
            AddUV(0, 0, mesh);
            break;
        case VoxelFace::Back:
            AddQuad(Vertices[16] + pos, Vertices[17] + pos, Vertices[18] + pos, Vertices[19] + pos, mesh);
            AddUV(0, 0, mesh);
            break;
        case VoxelFace::Front:
            AddQuad(Vertices[20] + pos, Vertices[21] + pos, Vertices[22] + pos, Vertices[23] + pos, mesh);
            AddUV(0, 0, mesh);
            break;
    }
}
add quad function
void ChunkMesher::AddQuad(glm::vec3 v1, glm::vec3 v2, glm::vec3 v3, glm::vec3 v4, Mesh& mesh)
{
    mesh.Vertices.push_back(v1);
    mesh.Vertices.push_back(v2);
    mesh.Vertices.push_back(v3);
    mesh.Vertices.push_back(v4);
}

---------------------
voxel data
glm::vec3 ChunkMesher::Vertices[24] =
{
    //left
    glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, 0.5f, 0.5f),
    glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, 0.5f),
    //right
    glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.5f, 0.5f, -0.5f),
    glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, -0.5f),
    //bottom
    glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f),
    glm::vec3(-0.5f, -0.5f, -0.5f),glm::vec3(0.5f, -0.5f, -0.5f),
    //top
    glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f),
    glm::vec3(-0.5f, 0.5f, 0.5f),  glm::vec3(0.5f, 0.5f, 0.5f),
    //back
    glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, 0.5f, -0.5f),
    glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
    //front
    glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f),
    glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f)

};
VoxelFace ChunkMesher::Faces[6] =
{
    VoxelFace::Left,
    VoxelFace::Right,
    VoxelFace::Bottom,
    VoxelFace::Top,
    VoxelFace::Back,
    VoxelFace::Front
};
glm::vec2 ChunkMesher::UVS[4] = 
{
    glm::vec2(0,0),glm::vec2(1,0),
    glm::vec2(0,1),glm::vec2(1,1)
};
unsigned int ChunkMesher::Indices[6] =
{
    2, 1, 0, 2, 3, 1
};

No problem. I copied the code into a code block in your post and fixed up your pastebin link.

The Forum Posting Guidelines describe how to create a code block. Just search down to “source code”. Basically you just paste the source code into a post and surround it with lines that only contain ``` on them. Feel free to edit your post above to see how it looks.

Good for you for diving in and learning enough to give this a shot!

One of the best ways to narrow down a strange problem you don’t understand is to comment out (or disable) code until you find the minimal case needed to reproduce it. That’ll tell you what’s necessary to produce the problem, and that can help you narrow your search for the bug (or the missing piece of knowledge you need to learn).

Also if there’s some strange interaction between pieces of your code, that will often point it out.

To your problem… Which 2 of the 6 faces have the problem?

Also, if you rotate your object and render it from a different viewpoint, do those 2 faces never render, or just never appear when rendered from the original viewpoint?

Right off-the-bat without digging through your code, one thing you might try as a test is disabling cullface (glDisable( GL_CULL_FACE )). This just in case the winding order on a few of your faces is incorrect compared to the rest.

i allready have gl_cullface disabled i think it’s something wrong with the std::vectors of data for the mesh

i found what faces arent being drawn it’s the front and back faces

and here is the code i use to create the cube

ChunkMesher::AddFaceToMesh(0, 0, 0, VoxelFace::Left, mesh);
    ChunkMesher::AddFaceToMesh(0, 0, 0, VoxelFace::Right, mesh);
    ChunkMesher::AddFaceToMesh(0, 0, 0, VoxelFace::Bottom, mesh);
    ChunkMesher::AddFaceToMesh(0, 0, 0, VoxelFace::Top, mesh);

    //the faces that arent drawing
    ChunkMesher::AddFaceToMesh(0, 0, 0, VoxelFace::Front, mesh);
    ChunkMesher::AddFaceToMesh(0, 0, 0, VoxelFace::Back, mesh);

i took some vertex data from someone elses non licenced voxel engine on github since i dont understand geometry that well yet and i still have hard time making a single quad it worked on my c# version perfectly but its not working that well in c++

i think its a problem with the glbufferdata calls for the vbo and index buffer but im not sure how i would debug something like that

One thing which stands out is that the buffer parameter to CreateVec3Buffer etc should probably be a reference, i.e.:

void BufferUtil::CreateVec3Buffer(std::vector<glm::vec3> data, unsigned int &buffer, int attrib)

This is equivalent to using ref uint buffer in C#.

As it stands, that parameter doesn’t do anything; if you’re expecting the buffer ID to be stored in the variable (VBO, IBO, TBO or CBO), the parameter needs to be a reference.

I have no idea whether that’s related to the missing faces, though.

i tried adding “&” to my buffer function parameters and that still didn’t fix it

Using sizeof(data) is wrong; this needs to be data.size() as with the other buffer functions.

Also: you should use a const reference for efficiency; passing a std::vector by value will create a deep copy.

void BufferUtil::Vec3BufferData(const std::vector<glm::vec3>& data, int attrib)
1 Like