0

I'm trying to draw my objects using the Pointer methods because at the moment when I'm rendering, my frame rate drops really low when I have multiple objects due to the amount of times I'm looping through the vertices etc. I've heard that using the pointer methods will speed up the processing and make the frame rate better as it's loading quicker.

Here's what I'm using now and I can't spawn over 3 objects without the game lagging horribly.

for (int j = 0; j < mesh->objectParts.size(); j++) {//loop through each object part
    glBindTexture(GL_TEXTURE_2D, textures[j]->getId());
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBegin(GL_TRIANGLES);
    for (int i = 0; i < mesh->objectParts[j]->faces[0].size(); i++) {

        glTexCoord2fv(&mesh->textureCoords[mesh->objectParts[j]->faces[1][i]]->u);
        glNormal3fv(&mesh->normals[mesh->objectParts[j]->faces[2][i]]->x);
        glVertex3fv(&mesh->indexedVertices[mesh->objectParts[j]->faces[0][i]]->x);
    }
    glEnd();

Here's an attempt at converting to the pointer methods

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);


    for (int i = 0; i < mesh->objectParts.size(); i++) {//loop through the amount of parts
        glBindTexture(GL_TEXTURE_2D, textures[i]->getId());
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glVertexPointer(3, GL_FLOAT, 0, &mesh->indexedVertices[0]->x);
        glNormalPointer(GL_FLOAT, 0, &mesh->normals[0]->x);
        glTexCoordPointer(2, GL_FLOAT, 0, &mesh->textureCoords[0]->u);

        for (int j = 0; j < 3; j++) 
        glDrawElements(GL_TRIANGLES, mesh->objectParts[i]->faceCount(), GL_UNSIGNED_SHORT, &mesh->objectParts[i]->faces[j][0]);
    }


    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

I'm not sure how the latter works, and it's definitely not right as it crashes before any objects are drawn.

Edit:

I did try the answer on my old post

C++ .obj parser, issue with parsing, or drawing using OpenGL

I got rid of the index list and stored all the data for the vertices, normals and textures as I parsed the file. Then I passed them straight to the pointer methods and used glDrawArrays to draw. However it made my object distorted and it definitely doesn't come out like the working render code.

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

            glVertexPointer(3, GL_FLOAT, 0, &mesh->unindexedVertices[0]->x);
            glNormalPointer(GL_FLOAT, 0, &mesh->unindexedNormals[0]->x);
            glTexCoordPointer(2, GL_FLOAT, 0, &mesh->unindexedTextureCoords[0]->u);

            glDrawArrays(GL_TRIANGLES, 0, 3);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

Here's how I'm drawing after removing the index list and here's the outcome: enter image description here

Can someone help me convert the top code into the bottom code?

Community
  • 1
  • 1
kbz
  • 984
  • 2
  • 12
  • 30
  • The key to using glDrawElements() is understanding *how your data is stored*. You need to know how this so you can figure out how the different data pointers will be traversed by OpenGL. Can you tell us more about your data structures? – Jonny D Apr 21 '15 at 00:09
  • This is covered in my answer to your previous question: http://stackoverflow.com/questions/29718501/c-obj-parser-issue-with-parsing-or-drawing-using-opengl/29722681#29722681. – Reto Koradi Apr 21 '15 at 02:07
  • @RetoKoradi I did try. If you look at my OP now I've edited it with the attempt and the outcome. If you can spot the problem that'd be great. Also I'm not fussed about efficiency, memory usage or anything like that as long as it's not huge. This is only a small educational project and doesn't need to be spectacular. – kbz Apr 21 '15 at 08:15
  • The only thing that jumps out in the code here is that you're only drawing one triangle, since 3 is passed to `glDrawArrays()` as the number of vertices. – Reto Koradi Apr 22 '15 at 05:13

1 Answers1

3

Changing to the pointer methods likely won't help too much, as the biggest problem here is the fact that you are sending vertex data every frame.

If your meshes are static, you could use VBOs and VAOs: you'd only need to send your vertex data to the OpenGL implementation once and to draw with it you'd only need to bind the VAO for your mesh and then call the proper draw call. This is the "modern" method. You can read a lot more on that here: https://www.opengl.org/wiki/Vertex_Specification

If you are unable to use VBOs then you could try display lists.

chbaker0
  • 1,758
  • 2
  • 13
  • 27
  • Thanks! I don't really have the time to look into VBOs and VAOs for this project but I've gone with display lists and they work perfectly! I'm guessing like you said for the above, they send the data only once? Now I can render multiple objects without lagging. – kbz Apr 21 '15 at 08:28
  • @Kieran Basically, yes, it just sends the data once. There are better ways to do so (hint hint VBOs) but display lists were the first way achieve that sort of optimization in OpenGL as far as I'm aware. – chbaker0 Apr 21 '15 at 19:08