0
\$\begingroup\$

As the title says…. :( nothing is drawn on screen… is there something I'm missing?

Mesh *Mesh_Create(GLfloat vertices[], GLuint indices[], GLfloat uvs[], GLfloat colors[])
{


Mesh *mesh = (Mesh*)malloc(sizeof(Mesh));


mesh->vertices = (GLfloat*)malloc(sizeof(vertices));
memcpy(mesh->vertices, vertices, sizeof(vertices));

mesh->indices = (GLuint*)malloc(sizeof(indices));
memcpy(mesh->indices, indices, sizeof(indices));

mesh->elementCount = sizeof(indices) / sizeof(GLuint);

glGenVertexArrays(1, &mesh->vao);
glBindVertexArray(mesh->vao);

glGenBuffers(1, &mesh->vbo[VERTEXBUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo[VERTEXBUFFER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(mesh->vertices), &mesh->vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);

/*glGenBuffers(1, &mesh->vbo[TEXTUREBUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo[TEXTUREBUFFER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(1);
*/
glGenBuffers(1, &mesh->vbo[INDICESBUFFER]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->vbo[INDICESBUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(mesh->indices), &mesh->indices, GL_STATIC_DRAW);

/*glGenBuffers(1, &mesh->vbo[COLORBUFFER]);
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo[COLORBUFFER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
glVertexAttribPointer(3, 4, GL_FLOAT, false, 4 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(3);*/

/*glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);*/


return mesh;
}

Mesh *Mesh_CreateQuad()
{

GLfloat vertices[] = { -0.5,  -0.5,
                        0.5,  -0.5,
                        0.5,   0.5,
                       -0.5,   0.5 };

GLuint indices[] = { 0,1,2,
                      0,2,3 };

GLfloat uvs[] = {   0 , 1,
                    1,  1,
                    1,  0,
                    0,  0 };

GLfloat colors[] = {    1, 1, 1, 1,
                        1, 1, 1, 1,
                        1, 1, 1, 1,
                        1, 1, 1, 1 };

return Mesh_Create(vertices, indices, uvs, colors);
}

void Mesh_Render(Mesh *mesh)
{
    glBindVertexArray(mesh->vao);
    glDrawElements(GL_TRIANGLES, mesh->elementCount, GL_UNSIGNED_INT, &mesh->indices);
}
\$\endgroup\$
  • \$\begingroup\$ What are your model, view, and projection matrices set to? \$\endgroup\$ – user1118321 Nov 30 '18 at 2:55
  • \$\begingroup\$ I've added it now…. please help \$\endgroup\$ – David Neves Nov 30 '18 at 10:08
  • 2
    \$\begingroup\$ Hi and welcome to gamedev! You might want to include just the code you think it's relevant to your question, instead of providing a whole lot of code that we need to read and test. Also, do you have some sort of way to debug opengl? One example would be to call glGetError() or to use tools like RenderDoc. \$\endgroup\$ – Gabriele Vierti Nov 30 '18 at 10:40
  • 1
    \$\begingroup\$ Please don't change your code after you received an answer! It will confuse future readers. Instead, if you really want to post fixed code, post it as an answer. \$\endgroup\$ – HolyBlackCat Nov 30 '18 at 19:58
  • \$\begingroup\$ yeah… Sorry… Just one thing! I'm having problems with memcpy… \$\endgroup\$ – David Neves Nov 30 '18 at 22:27
1
\$\begingroup\$

Your main problem is that you're unbinding:

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Because your VAO is still active when you unbind, you're actually setting the bindings stored in the VAO to 0 when you do this.

So your VAO has 0 bound to GL_ELEMENT_ARRAY_BUFFER meaning that no element array buffer will be used during your glDrawElements call - the actual outcome of which will vary depending on whether you use a core profile (GL_INVALID_OPERATION will be generated) or not (you might get no output, you might get garbage output, you might get a random crash).


Your element array buffer setup also makes no sense:

    glGenBuffers(1, &mesh->vbo[INDICESBUFFER]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->vbo[INDICESBUFFER]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * sizeof(GLubyte), indices, GL_STATIC_DRAW);
    glVertexAttribPointer(2, 3, GL_UNSIGNED_BYTE, false, 0, 0);
    glEnableVertexAttribArray(2);

There's no need to use either glVertexAttribPointer or glEnableVertexAttribArray here, and in fact vertex attrib pointer setup only latches the most recently bound GL_ARRAY_BUFFER, so these pointers will in fact use your mesh->vbo[TEXTUREBUFFER].

That shouldn't affect the glDrawElements call working or not, however, although - depending on your vertex shader - the output might not be what you expect.


Finally...

glDrawElements(GL_TRIANGLES, mesh->elementCount, GL_UNSIGNED_BYTE, mesh->indices);

Where:

mesh->indices = (GLubyte*)malloc(sizeof(indices));
mesh->indices = indices;

And:

GLubyte indices[] = { 0,1,2,
                      0,2,3 };

There are lots of things wrong with this.

First of all, "indices" is a local variable declared on the stack, meaning that it will go out of scope when Mesh_CreateQuad exits, meaning that it will just contain stack garbage any future time you might reference that memory location.

So then you malloc mesh->indices, but "mesh->indices = indices" doesn't copy the data; it just copies the pointer assignment. In other words, "the memory location pointed to mesh->indices is set to be the memory location pointed to by indices". But, as we've seen, the memory location pointed to by indices will go out of scope and potentially contain random garbage, so mesh->indices likewise contains random garbage after indices goes out of scope.

This is obviously all wrong, and you really need to work a lot on your understanding of memory management and pointers in C/C++ here.


And one last note is that you really shouldn't use GL_UNSIGNED_BYTE with glDrawElements because it's unlikely to be hardware accelerated. So even though it might be appealing because it saves memory, it will actually run slower than using a larger type.


So, in summary:

  • Set up your ELEMENT_ARRAY_BUFFER correctly.
  • Copy memory correctly using memcpy instead of just copying pointer assignments.
  • Always draw from buffer objects if using a core profile; this includes both your ARRAY_BUFFER(s) and your ELEMENT_ARRAY_BUFFER.
  • If you unbind your ELEMENT_ARRAY_BUFFER while a VAO is bound, you'll unbind it from that VAO and that VAO will be unable to draw with indices. This applies even if you do everything else correctly - unbinding is evil - don't do it, even if it's what a tutorial teaches (it's a bad tutorial if it unbinds).
\$\endgroup\$
  • \$\begingroup\$ Yes I'm getting random crashed…. I'm not interested in CORE. This is a simple 2D app. but yeah I've changed it but still... nothing is drawn… You can see on top \$\endgroup\$ – David Neves Nov 30 '18 at 19:25
  • \$\begingroup\$ IIRC, VBO binding is not a part of VAO state. It's a part of global state. VAO remembers currently bound VBO when you call glVertexAttribPointer, you can safely unbind your VBO after that. \$\endgroup\$ – HolyBlackCat Nov 30 '18 at 19:56
  • \$\begingroup\$ You can unbind GL_ARRAY_BUFFER, you can't unbind GL_ELEMENT_ARRAY_BUFFER. \$\endgroup\$ – Maximus Minimus Nov 30 '18 at 21:05
0
\$\begingroup\$

Something is appearing but not working entirely. Can someone help?

Mesh *Mesh_Create(GLfloat vertices[], unsigned int vertexElements, GLuint indices[], unsigned int indexElements, GLfloat uvs[], unsigned int uvElements, GLfloat colors[], unsigned int colorElements)
{
    Mesh *mesh = (Mesh*)malloc(sizeof(Mesh));

    mesh->vertices = (GLfloat*)malloc(sizeof(GLfloat) * vertexElements);
    memcpy(mesh->vertices, vertices, sizeof(GLfloat) * vertexElements);

    mesh->uvs = (GLfloat*)malloc(sizeof(GLfloat) * uvElements);
    memcpy(mesh->uvs, uvs, sizeof(GLfloat) * uvElements);

    mesh->indices = (GLuint*)malloc(sizeof(GLuint) * indexElements);
    memcpy(mesh->indices, indices, sizeof(GLuint) * indexElements);

    mesh->elementCount = vertexElements * 3;

    glGenVertexArrays(1, &mesh->vao);
    glBindVertexArray(mesh->vao);

    glGenBuffers(1, &mesh->vbo[VERTEXBUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo[VERTEXBUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertexElements, &mesh->vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, NULL);
    glEnableVertexAttribArray(0);

    glGenBuffers(1, &mesh->vbo[TEXTUREBUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo[TEXTUREBUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * uvElements, &mesh->uvs, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, NULL);
    glEnableVertexAttribArray(1);

    glGenBuffers(1, &mesh->vbo[INDICESBUFFER]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->vbo[INDICESBUFFER]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexElements, &mesh->indices, GL_STATIC_DRAW);

    /*glGenBuffers(1, &mesh->vbo[COLORBUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo[COLORBUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * colorElements, &mesh->colors, GL_STATIC_DRAW);
    glVertexAttribPointer(2, 4, GL_FLOAT, false, 0, NULL);
    glEnableVertexAttribArray(2);*/

    return mesh;
}

Mesh *Mesh_CreateQuad()
{
    GLfloat vertices[8] = { -0.5,  -0.5,//   0,
                              0.5,  -0.5,//   0,
                              0.5,   0.5,//   0,
                             -0.5,   0.5 };//,   0 };

    GLuint indices[6] = { 0,1,2,
                          0,2,3 };

    GLfloat uvs[8] = {  0 , 1,
                        1,  1,
                        1,  0,
                        0,  0 };

    GLfloat colors[16] = {  1, 1, 1, 1,
                            1, 1, 1, 1,
                            1, 1, 1, 1,
                            1, 1, 1, 1 };

    return Mesh_Create(vertices, 8, indices, 6, uvs, 8, colors, 16);
}

void Mesh_Render(Mesh *mesh)
{
    glBindVertexArray(mesh->vao);
    glDrawElements(GL_TRIANGLES, mesh->elementCount, GL_UNSIGNED_INT, NULL);
}

Screenshot

\$\endgroup\$
  • \$\begingroup\$ If this didn't solve your problem, do not post it as an Answer. Use the edit link to add it as a further detail in your Question. \$\endgroup\$ – DMGregory Nov 30 '18 at 23:57

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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