0
votes

I'm using VC++2010 with GLFW3 and GLEW for openGL. I've made an OBJ-Loader for loading triangulated meshes. At some point i fill the following Arrays in a VBOMesh2-object.

GLfloat *vertices;
GLfloat *normals;
GLuint *indices;

so as result, i get my data which i use for the VBO:

  • Vertices : vertices = [v0x, v0y, v0z, v1x, v1y, v1z, ...]
  • (sorted) Normals : normals = [n0x, n0y, n0z, n1x, n1y, n1z, ...]
  • Indices : inices = {face0i0, face0i1, face0i2, face1i0, face1i1, face1i2, ...]

The next step is to bind the Buffers with the init()-methode from VBOMesh2 object. vertexVBOID, normalsVBOID and indexVBOID are GLuint.

void VBOMesh2::init(void)
{
    vertexVBOID = 0;
    glGenBuffers(1, &vertexVBOID);
    glBindBuffer(GL_ARRAY_BUFFER, vertexVBOID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*numFaces*3*3, vertices, GL_STATIC_DRAW);

    normalsVBOID = 0;
    glGenBuffers(1, &normalsVBOID);
    glBindBuffer(GL_ARRAY_BUFFER, normalsVBOID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*numFaces*3*3, normals, GL_STATIC_DRAW);

    indexVBOID = 0;
    glGenBuffers(1, &indexVBOID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBOID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*numFaces*3, indices, GL_STATIC_DRAW);

}

ok... and i draw with:

void VBOMesh2::draw(void)
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER, vertexVBOID);
    glVertexPointer(3, GL_FLOAT, sizeof(float)*3, 0);

    glEnableClientState(GL_NORMAL_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER, normalsVBOID);
    glNormalPointer(GL_FLOAT, sizeof(float)*3, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBOID);

    glPushMatrix();
    glTranslatef(x, y, z);
    glRotatef(rx, 1, 0, 0);
    glRotatef(ry, 0, 1, 0);
    glRotatef(rz, 0, 0, 1);

    glDrawArrays(GL_TRIANGLES, indices[0], numIndices);

    glPopMatrix();

    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
}

I can load a Mesh with:

OBJLoader objLoader;
MeshData meshData;
objLoader.loadFile("temp/quad_smooth.obj");
meshData = objLoader.getMeshData();
VBOMesh2 tmpMesh(meshData);

and draw it (in openGL-Loop) with :

tmpMesh.draw();

i get the following result:

one Quad

wonderful!

now i thought, lets draw 500 Quads with following Code:

OBJLoader objLoader;
MeshData meshData;
objLoader.loadFile("temp/quad_smooth.obj");
meshData = objLoader.getMeshData();

for(int i = 0; i < 500; i++)
{
   VBOMesh2 tmpMesh(meshData);

   meshes.push_back(tmpMesh);
   meshes[i].init();

 // Do stuff for position and rotation like meshes[i].setX(x); and so on
}

and in openGL-loop i do:

for(int i = 0; i < meshes.size(); i++) 
{
   meshes[i].draw();
}

btw. meshes is a vector:

vector<VBOMesh2> meshes;

and i got the following result:

500 Quads

Oh no!!!

And now i've got no opinion why my meshes (not all, but some) are broken... or what i'm doing wrong.... The code can render one quad without any visualisation-error, but when i create 500 quads with the same meshData (same Data from oneQuad) i got broken quads....

Instead of using

glDrawArrays(GL_TRIANGLES, indices[0], numIndices);

i've tried

glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0);

for that i've filled the Arrays vertices, normals, indices with an other methode (which i can post if necessary), but i got the same problem... i can draw one Quad with no Errors but when i try to draw 500 Quads i got an access violation 0x000005.

Btw. i updated my driver for my graphic-card (but the problem remain)

Can someone give me a hint?

1
Btw better use VBO's which contains a vertex in one place ( pos, norm, ... ) instead of using multiple VBO's. Anyway i dont like the fact you're using deprecated functions ( like glPushMatrixetc ), better go with shaders, own matrices, etc... In my personal opinion this reduces the source of errors a much when everything is setup and maybe even removes this error.Felix K.
Ok i've trim down that wall of text... thx for the comments. I'm relatively new to openGL and unfortunately I've no knowledge about shaders... I want do that later. First i want code which can run and display something.user2602528
@user2602528 Actually there are some differences between the stuff you doing above and the new techniques, so if you get your code above to work there are still a lot of differences you need to learn then. IMHO it does not make sence, especially there are some good tutorials ( db-in.com/blog/2011/01/all-about-opengl-es-2-x-part-13 ).Felix K.
Thx for the comments... you are right i'm mixing openGL 3.3 functions with deprecated stuff. Thx Felix K. for the link and if someone reads this i got some more Tutorials for OpenGL 3.3 [1] [link] (mbsoftworks.sk/index.php?page=tutorials&series=1) [2] [link] (opengl-tutorial.org) [3] [link] (x6itru.web44.net/?page_id=37) and i think that one too [4] [link] (ogldev.atspace.co.uk/index.html)user2602528
There's also this one for 3.3.Andreas Haferburg

1 Answers

0
votes

Don't use std::vector<VBOMesh2>, since vector operates on values. If you've implemented ~VBOMesh2 to delete your arrays, you might be drawing dangling pointers (namely indices[0]). Either use a simple array of VBOMesh2's or std::vector<VBOMesh2*>.

glDrawArrays(GL_TRIANGLES, indices[0], numIndices);

That's not how you draw indexed meshes. The second parameter is an offset into the arrays you bound earlier with glVertexPointer and glNormalPointer. In your case it should always be 0.

You need to decide if you want to use indexed meshes or not, your question isn't clear on that. If you do, you need to use glDrawElements. However, your vertex and normal data doesn't have the right size. But I suspect you know that. It kinda looks like you first implemented code for indexed meshes, and when it didn't work you tried to convert it to non-indexed meshes.