kbz
kbz

Reputation: 1006

Alternative ways of drawing/rendering using openGL, C++

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?

Upvotes: 0

Views: 604

Answers (1)

chbaker0
chbaker0

Reputation: 1788

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.

Upvotes: 3

Related Questions