dummstah

04-23-2003, 02:24 AM

I'm having a problem with arrays in OpenGL. Until now I've been drawing everything manually as objects weren't too complex. However, now theyre reaching polygon counts of 500+ so I'm implementing opengl vertex/normal/texture arrays.

All the items are static, so I figured that the fastest way to do this would be to build the vertex/normal/texture buffers in the mesh load function, and store it as an array of vertexes on the mesh object. I'm not too worried on memory optimization right now so it just loads into an array of 1000 vertex's. This is the code I've come up with to do this:

--------------------------

void buildvertexbuffer(mesh *themesh)

{

int l;

memset(&themesh->meshvertbuf, 0, sizeof(vertex) * 1000);

memset(&themesh->meshnormbuf, 0, sizeof(vertex) * 1000);

memset(&themesh->meshtextbuf, 0, sizeof(vertex) * 1000);

for (l = 0; l < themesh->facecount; l++)

{

//Vertices buffer (themesh->vertexlist[themeshfacelist[l].a].x)

themesh->meshvertbuf[(l * 3) + 0].x = themesh->vertexlist [themesh->facelist[l].a] .x;

themesh->meshvertbuf[(l * 3) + 0].y = themesh->vertexlist [themesh->facelist[l].a] .y;

themesh->meshvertbuf[(l * 3) + 0].z = themesh->vertexlist [themesh->facelist[l].a] .z;

themesh->meshvertbuf[(l * 3) + 1].x = themesh->vertexlist [themesh->facelist[l].b] .x;

themesh->meshvertbuf[(l * 3) + 1].y = themesh->vertexlist [themesh->facelist[l].b] .y;

themesh->meshvertbuf[(l * 3) + 1].z = themesh->vertexlist [themesh->facelist[l].b] .z;

themesh->meshvertbuf[(l * 3) + 2].x = themesh->vertexlist [themesh->facelist[l].c] .x;

themesh->meshvertbuf[(l * 3) + 2].y = themesh->vertexlist [themesh->facelist[l].c] .y;

themesh->meshvertbuf[(l * 3) + 2].z = themesh->vertexlist [themesh->facelist[l].c] .z;

//Texture buffer

themesh->meshtextbuf[(l * 3) + 0].x = themesh->uvvertexlist [themesh->uvfacelist[l].a] .x;

themesh->meshtextbuf[(l * 3) + 0].y = themesh->uvvertexlist [themesh->uvfacelist[l].a] .y;

themesh->meshtextbuf[(l * 3) + 0].z = themesh->uvvertexlist [themesh->uvfacelist[l].a] .z;

themesh->meshtextbuf[(l * 3) + 1].x = themesh->uvvertexlist [themesh->uvfacelist[l].b] .x;

themesh->meshtextbuf[(l * 3) + 1].y = themesh->uvvertexlist [themesh->uvfacelist[l].b] .y;

themesh->meshtextbuf[(l * 3) + 1].z = themesh->uvvertexlist [themesh->uvfacelist[l].b] .z;

themesh->meshtextbuf[(l * 3) + 2].x = themesh->uvvertexlist [themesh->uvfacelist[l].c] .x;

themesh->meshtextbuf[(l * 3) + 2].y = themesh->uvvertexlist [themesh->uvfacelist[l].c] .y;

themesh->meshtextbuf[(l * 3) + 2].z = themesh->uvvertexlist [themesh->uvfacelist[l].c] .z;

//Normal buffer (themesh->normal[l].vertexnormals[0].x)

themesh->meshnormbuf[(l * 3) + 0].x = themesh->normal[l].vertexnormals[0].x;

themesh->meshnormbuf[(l * 3) + 0].y = themesh->normal[l].vertexnormals[0].y;

themesh->meshnormbuf[(l * 3) + 0].z = themesh->normal[l].vertexnormals[0].z;

themesh->meshnormbuf[(l * 3) + 1].x = themesh->normal[l].vertexnormals[1].x;

themesh->meshnormbuf[(l * 3) + 1].y = themesh->normal[l].vertexnormals[1].y;

themesh->meshnormbuf[(l * 3) + 1].z = themesh->normal[l].vertexnormals[1].z;

themesh->meshnormbuf[(l * 3) + 2].x = themesh->normal[l].vertexnormals[2].x;

themesh->meshnormbuf[(l * 3) + 2].y = themesh->normal[l].vertexnormals[2].y;

themesh->meshnormbuf[(l * 3) + 2].z = themesh->normal[l].vertexnormals[2].z;

}

}

--------------------------

I'm then replacing my rendering function below:

--------------------------

for (l = 0; l < worldModel[x].facecount; l++)

{

glBegin(GL_TRIANGLES); // Drawing Using Triangles

glNormal3f(worldModel[x].normal[l].facenormal.x, worldModel[x].normal[l].facenormal.y, worldModel[x].normal[l].facenormal.z);

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[0].x, worldModel[x].normal[l].vertexnormals[0].y, worldModel[x].normal[l].vertexnormals[0].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].a)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].a)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].a)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].a].x, worldModel[x].vertexlist[worldModel[x].facelist[l].a].y, worldModel[x].vertexlist[worldModel[x].facelist[l].a].z);

if (glFlipNormals == FALSE)

{

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[1].x, worldModel[x].normal[l].vertexnormals[1].y, worldModel[x].normal[l].vertexnormals[1].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].b].x, worldModel[x].vertexlist[worldModel[x].facelist[l].b].y, worldModel[x].vertexlist[worldModel[x].facelist[l].b].z);

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[2].x, worldModel[x].normal[l].vertexnormals[2].y, worldModel[x].normal[l].vertexnormals[2].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].c].x, worldModel[x].vertexlist[worldModel[x].facelist[l].c].y, worldModel[x].vertexlist[worldModel[x].facelist[l].c].z);

}

else

{

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[2].x, worldModel[x].normal[l].vertexnormals[2].y, worldModel[x].normal[l].vertexnormals[2].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].c].x, worldModel[x].vertexlist[worldModel[x].facelist[l].c].y, worldModel[x].vertexlist[worldModel[x].facelist[l].c].z);

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[1].x, worldModel[x].normal[l].vertexnormals[1].y, worldModel[x].normal[l].vertexnormals[1].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].b].x, worldModel[x].vertexlist[worldModel[x].facelist[l].b].y, worldModel[x].vertexlist[worldModel[x].facelist[l].b].z);

}

glEnd();

}

--------------------------

With this one that utilizes the arrays:

--------------------------

//Enable vertex array so we can stream polygons straight in

glEnable(GL_VERTEX_ARRAY);

glEnable(GL_TEXTURE_COORD_ARRAY);

glEnable(GL_NORMAL_ARRAY);

//Set the pointers to this current model

glVertexPointer (3, GL_FLOAT, 0, worldModel[x].meshvertbuf);

glTexCoordPointer (3, GL_FLOAT, 0, worldModel[x].meshtextbuf);

glNormalPointer (GL_FLOAT, 0, worldModel[x].meshnormbuf);

glDrawArrays(GL_TRIANGLES, 0, worldModel[x].facecount * 3);

--------------------------------

Hopefully I'm not confusing anybody with the code above. The whole thing works perfectly, except now my textures seem to align incorrectly on a few of my objects (so far its just high polygon ones).

Here are before and after shots of the engine. You can clearly see the distortion in the second, after shot:

http://games.paradum.com/before.jpg

http://games.paradum.com/after.jpg

Does anyone know what is causing this, either from looking at my code or from experience?

All the items are static, so I figured that the fastest way to do this would be to build the vertex/normal/texture buffers in the mesh load function, and store it as an array of vertexes on the mesh object. I'm not too worried on memory optimization right now so it just loads into an array of 1000 vertex's. This is the code I've come up with to do this:

--------------------------

void buildvertexbuffer(mesh *themesh)

{

int l;

memset(&themesh->meshvertbuf, 0, sizeof(vertex) * 1000);

memset(&themesh->meshnormbuf, 0, sizeof(vertex) * 1000);

memset(&themesh->meshtextbuf, 0, sizeof(vertex) * 1000);

for (l = 0; l < themesh->facecount; l++)

{

//Vertices buffer (themesh->vertexlist[themeshfacelist[l].a].x)

themesh->meshvertbuf[(l * 3) + 0].x = themesh->vertexlist [themesh->facelist[l].a] .x;

themesh->meshvertbuf[(l * 3) + 0].y = themesh->vertexlist [themesh->facelist[l].a] .y;

themesh->meshvertbuf[(l * 3) + 0].z = themesh->vertexlist [themesh->facelist[l].a] .z;

themesh->meshvertbuf[(l * 3) + 1].x = themesh->vertexlist [themesh->facelist[l].b] .x;

themesh->meshvertbuf[(l * 3) + 1].y = themesh->vertexlist [themesh->facelist[l].b] .y;

themesh->meshvertbuf[(l * 3) + 1].z = themesh->vertexlist [themesh->facelist[l].b] .z;

themesh->meshvertbuf[(l * 3) + 2].x = themesh->vertexlist [themesh->facelist[l].c] .x;

themesh->meshvertbuf[(l * 3) + 2].y = themesh->vertexlist [themesh->facelist[l].c] .y;

themesh->meshvertbuf[(l * 3) + 2].z = themesh->vertexlist [themesh->facelist[l].c] .z;

//Texture buffer

themesh->meshtextbuf[(l * 3) + 0].x = themesh->uvvertexlist [themesh->uvfacelist[l].a] .x;

themesh->meshtextbuf[(l * 3) + 0].y = themesh->uvvertexlist [themesh->uvfacelist[l].a] .y;

themesh->meshtextbuf[(l * 3) + 0].z = themesh->uvvertexlist [themesh->uvfacelist[l].a] .z;

themesh->meshtextbuf[(l * 3) + 1].x = themesh->uvvertexlist [themesh->uvfacelist[l].b] .x;

themesh->meshtextbuf[(l * 3) + 1].y = themesh->uvvertexlist [themesh->uvfacelist[l].b] .y;

themesh->meshtextbuf[(l * 3) + 1].z = themesh->uvvertexlist [themesh->uvfacelist[l].b] .z;

themesh->meshtextbuf[(l * 3) + 2].x = themesh->uvvertexlist [themesh->uvfacelist[l].c] .x;

themesh->meshtextbuf[(l * 3) + 2].y = themesh->uvvertexlist [themesh->uvfacelist[l].c] .y;

themesh->meshtextbuf[(l * 3) + 2].z = themesh->uvvertexlist [themesh->uvfacelist[l].c] .z;

//Normal buffer (themesh->normal[l].vertexnormals[0].x)

themesh->meshnormbuf[(l * 3) + 0].x = themesh->normal[l].vertexnormals[0].x;

themesh->meshnormbuf[(l * 3) + 0].y = themesh->normal[l].vertexnormals[0].y;

themesh->meshnormbuf[(l * 3) + 0].z = themesh->normal[l].vertexnormals[0].z;

themesh->meshnormbuf[(l * 3) + 1].x = themesh->normal[l].vertexnormals[1].x;

themesh->meshnormbuf[(l * 3) + 1].y = themesh->normal[l].vertexnormals[1].y;

themesh->meshnormbuf[(l * 3) + 1].z = themesh->normal[l].vertexnormals[1].z;

themesh->meshnormbuf[(l * 3) + 2].x = themesh->normal[l].vertexnormals[2].x;

themesh->meshnormbuf[(l * 3) + 2].y = themesh->normal[l].vertexnormals[2].y;

themesh->meshnormbuf[(l * 3) + 2].z = themesh->normal[l].vertexnormals[2].z;

}

}

--------------------------

I'm then replacing my rendering function below:

--------------------------

for (l = 0; l < worldModel[x].facecount; l++)

{

glBegin(GL_TRIANGLES); // Drawing Using Triangles

glNormal3f(worldModel[x].normal[l].facenormal.x, worldModel[x].normal[l].facenormal.y, worldModel[x].normal[l].facenormal.z);

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[0].x, worldModel[x].normal[l].vertexnormals[0].y, worldModel[x].normal[l].vertexnormals[0].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].a)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].a)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].a)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].a].x, worldModel[x].vertexlist[worldModel[x].facelist[l].a].y, worldModel[x].vertexlist[worldModel[x].facelist[l].a].z);

if (glFlipNormals == FALSE)

{

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[1].x, worldModel[x].normal[l].vertexnormals[1].y, worldModel[x].normal[l].vertexnormals[1].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].b].x, worldModel[x].vertexlist[worldModel[x].facelist[l].b].y, worldModel[x].vertexlist[worldModel[x].facelist[l].b].z);

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[2].x, worldModel[x].normal[l].vertexnormals[2].y, worldModel[x].normal[l].vertexnormals[2].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].c].x, worldModel[x].vertexlist[worldModel[x].facelist[l].c].y, worldModel[x].vertexlist[worldModel[x].facelist[l].c].z);

}

else

{

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[2].x, worldModel[x].normal[l].vertexnormals[2].y, worldModel[x].normal[l].vertexnormals[2].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].c].x, worldModel[x].vertexlist[worldModel[x].facelist[l].c].y, worldModel[x].vertexlist[worldModel[x].facelist[l].c].z);

if (worldModel[x].rendertype > 0) glNormal3f (worldModel[x].normal[l].vertexnormals[1].x, worldModel[x].normal[l].vertexnormals[1].y, worldModel[x].normal[l].vertexnormals[1].z);

glTexCoord3f(worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].x, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].b)].y, worldModel[x].uvvertexlist[(worldModel[x].uvfacelist[l].c)].z);

glVertex3f (worldModel[x].vertexlist[worldModel[x].facelist[l].b].x, worldModel[x].vertexlist[worldModel[x].facelist[l].b].y, worldModel[x].vertexlist[worldModel[x].facelist[l].b].z);

}

glEnd();

}

--------------------------

With this one that utilizes the arrays:

--------------------------

//Enable vertex array so we can stream polygons straight in

glEnable(GL_VERTEX_ARRAY);

glEnable(GL_TEXTURE_COORD_ARRAY);

glEnable(GL_NORMAL_ARRAY);

//Set the pointers to this current model

glVertexPointer (3, GL_FLOAT, 0, worldModel[x].meshvertbuf);

glTexCoordPointer (3, GL_FLOAT, 0, worldModel[x].meshtextbuf);

glNormalPointer (GL_FLOAT, 0, worldModel[x].meshnormbuf);

glDrawArrays(GL_TRIANGLES, 0, worldModel[x].facecount * 3);

--------------------------------

Hopefully I'm not confusing anybody with the code above. The whole thing works perfectly, except now my textures seem to align incorrectly on a few of my objects (so far its just high polygon ones).

Here are before and after shots of the engine. You can clearly see the distortion in the second, after shot:

http://games.paradum.com/before.jpg

http://games.paradum.com/after.jpg

Does anyone know what is causing this, either from looking at my code or from experience?