Skip to content

Commit

Permalink
Render models as client side vertex arrays instead of using immediate…
Browse files Browse the repository at this point in the history
… mode OpenGL calls. Patch reviewed by Cyp.
  • Loading branch information
perim committed Jan 9, 2013
1 parent e333e49 commit 8d5b074
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 27 deletions.
8 changes: 7 additions & 1 deletion lib/ivis_opengl/imd.cpp
Expand Up @@ -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);
}
}
55 changes: 53 additions & 2 deletions lib/ivis_opengl/imdload.cpp
Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions lib/ivis_opengl/ivisdef.h
Expand Up @@ -30,6 +30,7 @@
#define _ivisdef_h

#include "lib/framework/frame.h"
#include "lib/framework/opengl.h"
#include "pietypes.h"

#include <vector>
Expand Down Expand Up @@ -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 !)
};

Expand Down
45 changes: 21 additions & 24 deletions lib/ivis_opengl/piedraw.cpp
Expand Up @@ -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();

Expand Down Expand Up @@ -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))
{
Expand Down

0 comments on commit 8d5b074

Please sign in to comment.