diff --git a/lib/ivis_opengl/imd.cpp b/lib/ivis_opengl/imd.cpp index ca0d83743..2c148c55d 100644 --- a/lib/ivis_opengl/imd.cpp +++ b/lib/ivis_opengl/imd.cpp @@ -61,8 +61,14 @@ void iV_IMDRelease(iIMDShape *s) free(s->shadowEdgeList); s->shadowEdgeList = NULL; } + free(s->vertices); + free(s->normals); + for (i = 0; i < s->texcoords.size(); i++) + { + free(s->texcoords[i]); + } d = s->next; - free(s); + delete s; iV_IMDRelease(d); } } diff --git a/lib/ivis_opengl/imdload.cpp b/lib/ivis_opengl/imdload.cpp index eccf31f94..7047b5b14 100644 --- a/lib/ivis_opengl/imdload.cpp +++ b/lib/ivis_opengl/imdload.cpp @@ -507,7 +507,7 @@ static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataE i = sscanf(pFileData, "%255s %n", buffer, &cnt); ASSERT_OR_RETURN(NULL, i == 1, "Bad directive following LEVEL"); - s = (iIMDShape*)malloc(sizeof(iIMDShape)); + s = new iIMDShape; if (s == NULL) { /* Failed to allocate memory for s */ @@ -581,7 +581,6 @@ static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataE _imd_load_polys( &pFileData, s, pieVersion); - // NOW load optional stuff while (!AtEndOfFile(pFileData, FileDataEnd)) // check for end of file (give or take white space) { @@ -612,6 +611,58 @@ static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataE } } + // FINALLY, massage the data into what can stream directly to OpenGL + s->vertices = (GLfloat *)malloc(sizeof(GLfloat) * 3 * s->npolys * 3); + s->normals = (GLfloat *)malloc(sizeof(GLfloat) * 3 * s->npolys * 3); + for (i = 0; i < MAX(1, s->numFrames); i++) + { + GLfloat *ptr = (GLfloat *)malloc(sizeof(GLfloat) * 2 * s->npolys * 3); + s->texcoords.push_back(ptr); + } + i = 0; + for (iIMDPoly *pPolys = s->polys; pPolys < s->polys + s->npolys; pPolys++) + { + // each of the 3 vertices has one normal coordinate in 3 dimensions (increment of 9) + s->normals[i * 9 + 0] = pPolys->normal.x; + s->normals[i * 9 + 1] = pPolys->normal.y; + s->normals[i * 9 + 2] = pPolys->normal.z; + s->normals[i * 9 + 3] = pPolys->normal.x; + s->normals[i * 9 + 4] = pPolys->normal.y; + s->normals[i * 9 + 5] = pPolys->normal.z; + s->normals[i * 9 + 6] = pPolys->normal.x; + s->normals[i * 9 + 7] = pPolys->normal.y; + s->normals[i * 9 + 8] = pPolys->normal.z; + + // each polygon has 3 texel coordinates in 2 dimensions (increment of 6) + for (int j = 0; j < s->texcoords.size(); j++) + { + // if texture animation flag is present, fetch animation coordinates for this polygon + // otherwise just show the first set of texel coordinates + int k = (pPolys->flags & iV_IMD_TEXANIM) ? j : 0; + + GLfloat *texcoords = s->texcoords[j]; + texcoords[i * 6 + 0] = pPolys->texCoord[k * 3 + 0].x; + texcoords[i * 6 + 1] = pPolys->texCoord[k * 3 + 0].y; + texcoords[i * 6 + 2] = pPolys->texCoord[k * 3 + 1].x; + texcoords[i * 6 + 3] = pPolys->texCoord[k * 3 + 1].y; + texcoords[i * 6 + 4] = pPolys->texCoord[k * 3 + 2].x; + texcoords[i * 6 + 5] = pPolys->texCoord[k * 3 + 2].y; + } + + // each polygon has 3 texture coordinates in 3 dimensions (increment of 9) + s->vertices[i * 9 + 0] = s->points[pPolys->pindex[0]].x; + s->vertices[i * 9 + 1] = s->points[pPolys->pindex[0]].y; + s->vertices[i * 9 + 2] = s->points[pPolys->pindex[0]].z; + s->vertices[i * 9 + 3] = s->points[pPolys->pindex[1]].x; + s->vertices[i * 9 + 4] = s->points[pPolys->pindex[1]].y; + s->vertices[i * 9 + 5] = s->points[pPolys->pindex[1]].z; + s->vertices[i * 9 + 6] = s->points[pPolys->pindex[2]].x; + s->vertices[i * 9 + 7] = s->points[pPolys->pindex[2]].y; + s->vertices[i * 9 + 8] = s->points[pPolys->pindex[2]].z; + + i++; + } + *ppFileData = pFileData; return s; diff --git a/lib/ivis_opengl/ivisdef.h b/lib/ivis_opengl/ivisdef.h index 7a8918c4e..55f4f4e24 100644 --- a/lib/ivis_opengl/ivisdef.h +++ b/lib/ivis_opengl/ivisdef.h @@ -30,6 +30,7 @@ #define _ivisdef_h #include "lib/framework/frame.h" +#include "lib/framework/opengl.h" #include "pietypes.h" #include @@ -103,6 +104,10 @@ struct iIMDShape float material[LIGHT_MAX][4]; float shininess; + GLfloat *vertices; + GLfloat *normals; + std::vector texcoords; + iIMDShape *next; // next pie in multilevel pies (NULL for non multilevel !) }; diff --git a/lib/ivis_opengl/piedraw.cpp b/lib/ivis_opengl/piedraw.cpp index 772f7f011..59b374971 100644 --- a/lib/ivis_opengl/piedraw.cpp +++ b/lib/ivis_opengl/piedraw.cpp @@ -143,7 +143,6 @@ static std::vector tshapes; static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData) { - iIMDPoly *pPolys; bool light = true; bool shaders = pie_GetShaderUsage(); @@ -232,31 +231,29 @@ static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELI frame %= MAX(1, shape->numFrames); - glBegin(GL_TRIANGLES); - for (pPolys = shape->polys; pPolys < shape->polys + shape->npolys; pPolys++) + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, shape->vertices); + glNormalPointer(GL_FLOAT, 0, shape->normals); + glTexCoordPointer(2, GL_FLOAT, 0, shape->texcoords[frame]); + if (!shaders) { - unsigned int frameidx = frame; - - if (!(pPolys->flags & iV_IMD_TEXANIM)) - { - frameidx = 0; - } - - polyCount++; - - glNormal3fv((GLfloat*)&pPolys->normal); - for (int n = 0; n < 3; n++) - { - GLfloat* texCoord = (GLfloat*)&pPolys->texCoord[frameidx * 3 + n]; - glTexCoord2fv(texCoord); - if (!shaders) - { - glMultiTexCoord2fv(GL_TEXTURE1, texCoord); - } - glVertex3fv((GLfloat*)&shape->points[pPolys->pindex[n]]); - } + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, shape->texcoords[frame]); } - glEnd(); + glDrawArrays(GL_TRIANGLES, 0, shape->npolys * 3); + if (!shaders) + { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + } + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + polyCount += shape->npolys; if (light || (pieFlag & pie_BUTTON)) {