Render models as client side vertex arrays instead of using immediate mode OpenGL calls. Patch reviewed by Cyp.

master
per 2013-01-09 23:28:25 +01:00
parent e333e49f19
commit 8d5b07485f
4 changed files with 86 additions and 27 deletions

View File

@ -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);
}
}

View File

@ -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;

View File

@ -30,6 +30,7 @@
#define _ivisdef_h
#include "lib/framework/frame.h"
#include "lib/framework/opengl.h"
#include "pietypes.h"
#include <vector>
@ -103,6 +104,10 @@ struct iIMDShape
float material[LIGHT_MAX][4];
float shininess;
GLfloat *vertices;
GLfloat *normals;
std::vector<GLfloat *> texcoords;
iIMDShape *next; // next pie in multilevel pies (NULL for non multilevel !)
};

View File

@ -143,7 +143,6 @@ static std::vector<TranslucentShape> 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))
{