pixelcity/Mesh.cpp

216 lines
5.7 KiB
C++
Raw Normal View History

2009-05-03 12:05:03 +01:00
/*-----------------------------------------------------------------------------
Mesh.cpp
2009 Shamus Young
-------------------------------------------------------------------------------
This class is used to make constructing objects easier. It handles
allocating vertex lists, polygon lists, and suchlike.
If you were going to implement vertex buffers, this would be the place to
do it. Take away the _vertex member variable and store verts for ALL meshes
in a common list, which could then be unloaded onto the good 'ol GPU.
-----------------------------------------------------------------------------*/
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include "glTypes.h"
#include "mesh.h"
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
CMesh::CMesh ()
{
_vertex_count = 0;
_triangle_count = 0;
_quad_strip_count = 0;
_fan_count = 0;
_cube_count = 0;
_polycount = 0;
_list = 0;
_compiled = false;
_vertex = NULL;
_normal = NULL;
_triangle = NULL;
_cube = NULL;
_quad_strip = NULL;
_fan = NULL;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
CMesh::~CMesh ()
{
unsigned i;
if (_vertex)
free (_vertex);
if (_normal)
free (_normal);
if (_triangle)
free (_triangle);
if (_cube)
free (_cube);
for (i = 0; i < _quad_strip_count; i++)
delete _quad_strip[i].index_list;
delete _quad_strip;
for (i = 0; i < _fan_count; i++)
delete _fan[i].index_list;
delete _fan;
if (_list)
glDeleteLists (_list, 1);
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void CMesh::VertexAdd (GLvertex v)
{
_vertex = (GLvertex*)realloc (_vertex, sizeof (GLvertex) * (_vertex_count + 1));
_vertex[_vertex_count] = v;
_vertex_count++;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void CMesh::CubeAdd (int* index)
{
_cube = (cube*)realloc (_cube, sizeof (cube) * (_cube_count + 1));
memcpy (&_cube[_cube_count].index_list[0], index, sizeof (int) * 10);
_cube_count++;
_polycount += 5;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void CMesh::QuadStripAdd (int* index, int count)
{
_quad_strip = (quad_strip*)realloc (_quad_strip, sizeof (quad_strip) * (_quad_strip_count + 1));
_quad_strip[_quad_strip_count].index_list = (int*)malloc (sizeof (int) * count);
_quad_strip[_quad_strip_count].count = count;
memcpy (&_quad_strip[_quad_strip_count].index_list[0], &index[0], sizeof (int) * count);
_quad_strip_count++;
_polycount += (count - 2) / 2;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void CMesh::FanAdd (int* index, int count)
{
_fan = (fan*)realloc (_fan, sizeof (fan) * (_fan_count + 1));
_fan[_fan_count].index_list = (int*)malloc (sizeof (int) * count);
_fan[_fan_count].count = count;
memcpy (&_fan[_fan_count].index_list[0], &index[0], sizeof (int) * count);
_fan_count++;
_polycount += count - 2;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void CMesh::Render ()
{
unsigned i, n;
int* index;
if (_compiled) {
glCallList (_list);
return;
}
for (i = 0; i < _quad_strip_count; i++) {
index = &_quad_strip[i].index_list[0];
glBegin (GL_QUAD_STRIP);
for (n = 0; n < _quad_strip[i].count; n++) {
glTexCoord2fv (&_vertex[index[n]].uv.x);
glVertex3fv (&_vertex[index[n]].position.x);
}
glEnd ();
}
for (i = 0; i < _cube_count; i++) {
index = &_cube[i].index_list[0];
glBegin (GL_QUAD_STRIP);
for (n = 0; n < 10; n++) {
glTexCoord2fv (&_vertex[index[n]].uv.x);
glVertex3fv (&_vertex[index[n]].position.x);
}
glEnd ();
glBegin (GL_QUADS);
glTexCoord2fv (&_vertex[index[7]].uv.x);
glVertex3fv (&_vertex[index[7]].position.x);
glVertex3fv (&_vertex[index[5]].position.x);
glVertex3fv (&_vertex[index[3]].position.x);
glVertex3fv (&_vertex[index[1]].position.x);
glEnd ();
glBegin (GL_QUADS);
glTexCoord2fv (&_vertex[index[6]].uv.x);
glVertex3fv (&_vertex[index[0]].position.x);
glVertex3fv (&_vertex[index[2]].position.x);
glVertex3fv (&_vertex[index[4]].position.x);
glVertex3fv (&_vertex[index[6]].position.x);
glEnd ();
}
for (i = 0; i < _fan_count; i++) {
index = &_fan[i].index_list[0];
glBegin (GL_TRIANGLE_FAN);
for (n = 0; n < _fan[i].count; n++) {
glTexCoord2fv (&_vertex[index[n]].uv.x);
glVertex3fv (&_vertex[index[n]].position.x);
}
glEnd ();
}
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void CMesh::Compile ()
{
if (!_list)
_list = glGenLists(1);
glNewList (_list, GL_COMPILE);
Render ();
glEndList();
_compiled = true;
}