mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-17 01:41:30 +00:00
2f4725e0f2
git-svn-id: https://svn.eduke32.com/eduke32@301 1a8010ca-5511-0410-912e-c29ae57300e0
449 lines
14 KiB
C
449 lines
14 KiB
C
// blah
|
||
|
||
#include "polymer.h"
|
||
|
||
_prsector* prsectors[MAXSECTORS];
|
||
|
||
float polymostprojmatrix[16];
|
||
float polymostmodelmatrix[16];
|
||
|
||
// tesselation variables
|
||
GLUtesselator* prtess;
|
||
int tempverticescount;
|
||
GLdouble tempvertice[3];
|
||
|
||
// Polymer cvars
|
||
char pr_verbosity = 1; // 0: silent, 1: errors and one-times, 2: multiple-times, 3: flood
|
||
char pr_wireframe = 0;
|
||
|
||
int polymer_init(void)
|
||
{
|
||
int i;
|
||
|
||
if (pr_verbosity >= 1) OSD_Printf("Initalizing Polymer subsystem...\n");
|
||
|
||
i = 0;
|
||
while (i < MAXSECTORS)
|
||
{
|
||
prsectors[i] = NULL;
|
||
i++;
|
||
}
|
||
|
||
prtess = gluNewTess();
|
||
if (prtess == 0)
|
||
{
|
||
if (pr_verbosity >= 1) OSD_Printf("PR : Tesselator initialization failed.\n");
|
||
return (0);
|
||
}
|
||
|
||
if (pr_verbosity >= 1) OSD_Printf("PR : Initialization complete.\n");
|
||
return (1);
|
||
}
|
||
|
||
void polymer_glinit(void)
|
||
{
|
||
GLfloat params[4];
|
||
|
||
bglGetFloatv(GL_PROJECTION_MATRIX, polymostprojmatrix);
|
||
bglGetFloatv(GL_MODELVIEW_MATRIX, polymostmodelmatrix);
|
||
bglClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||
bglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||
bglViewport(0, 0, 1024, 768);
|
||
|
||
// texturing
|
||
bglEnable(GL_TEXTURE_2D);
|
||
bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
|
||
bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
|
||
/*bglEnable(GL_TEXTURE_GEN_S);
|
||
bglEnable(GL_TEXTURE_GEN_T);
|
||
params[0] = GL_OBJECT_LINEAR;
|
||
bglTexGenfv(GL_S, GL_TEXTURE_GEN_MODE, params);
|
||
bglTexGenfv(GL_T, GL_TEXTURE_GEN_MODE, params);
|
||
params[0] = 1.0 / 10000.0;
|
||
params[1] = 1.0 / 10000.0;
|
||
params[2] = 1.0 / 10000.0;
|
||
params[3] = 1.0 / 10000.0;
|
||
bglTexGenfv(GL_S, GL_OBJECT_PLANE, params);
|
||
bglTexGenfv(GL_T, GL_OBJECT_PLANE, params);*/
|
||
|
||
bglDisable(GL_FOG);
|
||
bglEnable(GL_DEPTH_TEST);
|
||
if (pr_wireframe)
|
||
bglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||
else
|
||
bglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||
|
||
bglMatrixMode(GL_PROJECTION);
|
||
bglLoadIdentity();
|
||
bglFrustum(-1.0f, 1.0f, -0.75f, 0.75, 1.0f, 1000000.0f);
|
||
bglMatrixMode(GL_MODELVIEW);
|
||
bglLoadIdentity();
|
||
}
|
||
|
||
int polymer_updategeometry(short sectnum)
|
||
{
|
||
_prsector* s;
|
||
sectortype *sec;
|
||
walltype *wal;
|
||
int i, j;
|
||
long ceilz, florz;
|
||
long tex, tey;
|
||
float secangcos, secangsin, scalecoef;
|
||
long ang;
|
||
short curstat;
|
||
GLfloat* curbuffer;
|
||
|
||
s = prsectors[sectnum];
|
||
sec = §or[sectnum];
|
||
wal = &wall[sec->wallptr];
|
||
|
||
secangcos = secangsin = 0;
|
||
|
||
if (s == NULL)
|
||
{
|
||
if (pr_verbosity >= 1) OSD_Printf("PR : Can't update uninitialized sector %i.\n", sectnum);
|
||
return (-1);
|
||
}
|
||
|
||
if ((sec->floorstat & 64) || (sec->ceilingstat & 64))
|
||
{
|
||
ang = (getangle(wall[wal->point2].x - wal->x, wall[wal->point2].y - wal->y) + 512) & 2047;
|
||
secangcos = (float)(sintable[(ang+512)&2047]) / 16383.0f;
|
||
secangsin = (float)(sintable[ang&2047]) / 16383.0f;
|
||
}
|
||
|
||
i = 0;
|
||
while (i < s->wallcount)
|
||
{
|
||
s->verts[(i*3)+2] = s->floorbuffer[(i*5)+2] = s->ceilbuffer[(i*5)+2] = -wal->x;
|
||
s->verts[i*3] = s->floorbuffer[i*5] = s->ceilbuffer[i*5] = wal->y;
|
||
getzsofslope(sectnum, wal->x, wal->y, &ceilz, &florz);
|
||
s->verts[(i*3)+1] = 0;
|
||
s->floorbuffer[(i*5)+1] = -florz;
|
||
s->ceilbuffer[(i*5)+1] = -ceilz;
|
||
|
||
j = 2;
|
||
curstat = sec->floorstat;
|
||
curbuffer = s->floorbuffer;
|
||
|
||
while (j)
|
||
{
|
||
if (j == 1)
|
||
{
|
||
curstat = sec->ceilingstat;
|
||
curbuffer = s->ceilbuffer;
|
||
}
|
||
|
||
tex = (curstat & 64) ? ((wal->x - wall[sec->wallptr].x) * secangsin) + ((-wal->y - -wall[sec->wallptr].y) * secangcos) : wal->x;
|
||
tey = (curstat & 64) ? ((wal->x - wall[sec->wallptr].x) * secangcos) - ((-wal->y - -wall[sec->wallptr].y) * secangsin) : -wal->y;
|
||
|
||
if (curstat & 4)
|
||
swaplong(&tex, &tey);
|
||
|
||
if (curstat & 16) tex = -tex;
|
||
if (curstat & 32) tey = -tey;
|
||
|
||
scalecoef = (curstat & 8) ? 8.0f : 16.0f;
|
||
|
||
curbuffer[(i*5)+3] = ((float)(tex) / (scalecoef * tilesizx[sec->floorpicnum])) + ((float)(sec->floorxpanning) / 256.0f);
|
||
curbuffer[(i*5)+4] = ((float)(tey) / (scalecoef * tilesizy[sec->floorpicnum])) + ((float)(sec->floorypanning) / 256.0f);
|
||
|
||
j--;
|
||
}
|
||
|
||
i++;
|
||
wal = &wall[sec->wallptr + i];
|
||
}
|
||
|
||
if (pr_verbosity >= 3) OSD_Printf("PR : Updated sector %i.\n", sectnum);
|
||
|
||
return (0);
|
||
}
|
||
|
||
// This callback is called by the tesselator when it detects an intersection between contours (HELLO ROTATING SPOTLIGHT IN E1L1).
|
||
void PR_CALLBACK polymer_tesscombine(GLdouble v[3], GLdouble *data[4], GLfloat weight[4], GLdouble **out)
|
||
{
|
||
GLdouble* ptr;
|
||
|
||
//tempverticescount++;
|
||
//tempvertices = realloc(tempvertices, tempverticescount * sizeof(GLdouble) * 3);
|
||
tempvertice[0] = v[0];
|
||
tempvertice[1] = v[1];
|
||
tempvertice[2] = v[2];
|
||
|
||
ptr = tempvertice;
|
||
*out = tempvertice;
|
||
|
||
if (pr_verbosity >= 2) OSD_Printf("PR : Created additional geometry for sector tesselation.\n");
|
||
}
|
||
|
||
// This callback is called by the tesselator whenever it raises an error.
|
||
void PR_CALLBACK polymer_tesserror(GLenum error)
|
||
{
|
||
if (pr_verbosity >= 1) OSD_Printf("PR : Tesselation error number %i reported : %s.\n", error, gluErrorString(errno));
|
||
}
|
||
|
||
// Passing an edgeflag callback forces the tesselator to output a triangle list
|
||
void PR_CALLBACK polymer_tessedgeflag(GLboolean flag)
|
||
{
|
||
flag = 0;
|
||
return;
|
||
}
|
||
|
||
void PR_CALLBACK polymer_tessbegin(GLenum type)
|
||
{
|
||
if (type != GL_TRIANGLES)
|
||
{
|
||
OSD_Printf("PR : NOT A TRIANGLE LIST !<21>//... !\n");
|
||
}
|
||
}
|
||
|
||
void PR_CALLBACK polymer_tessend(void)
|
||
{
|
||
}
|
||
void PR_CALLBACK polymer_tessvertex(void* vertex, void* sector)
|
||
{
|
||
_prsector* s;
|
||
|
||
s = (_prsector*)sector;
|
||
|
||
if (s->curindice >= s->indicescount)
|
||
{
|
||
if (pr_verbosity >= 2) OSD_Printf("PR : Indice overflow, extending the indices list... !\n");
|
||
s->indicescount++;
|
||
s->indices = realloc(s->indices, s->indicescount * sizeof(GLushort));
|
||
}
|
||
s->indices[s->curindice] = (GLushort)vertex;
|
||
s->curindice++;
|
||
}
|
||
|
||
// This function tesselates the floor/ceiling of a sector and stores the triangles in a display list.
|
||
int polymer_buildfloor(short sectnum)
|
||
{
|
||
_prsector* s;
|
||
sectortype *sec;
|
||
int i;
|
||
|
||
if (pr_verbosity >= 2) OSD_Printf("PR : Tesselating floor of sector %i...\n", sectnum);
|
||
|
||
s = prsectors[sectnum];
|
||
sec = §or[sectnum];
|
||
|
||
if (s == NULL)
|
||
return (-1);
|
||
|
||
if (s->indices != NULL)
|
||
free(s->indices);
|
||
|
||
s->indicescount = (s->wallcount - 2) * 3;
|
||
s->indices = calloc(s->indicescount, sizeof(GLushort));
|
||
s->curindice = 0;
|
||
|
||
//gluTessCallback(prtess, GLU_TESS_BEGIN, polymer_tessbegin);
|
||
//gluTessCallback(prtess, GLU_TESS_END, polymer_tessend);
|
||
gluTessCallback(prtess, GLU_TESS_VERTEX_DATA, polymer_tessvertex);
|
||
gluTessCallback(prtess, GLU_TESS_EDGE_FLAG, polymer_tessedgeflag);
|
||
//gluTessCallback(prtess, GLU_TESS_COMBINE, polymer_tesscombine);
|
||
gluTessCallback(prtess, GLU_TESS_ERROR, polymer_tesserror);
|
||
|
||
gluTessProperty(prtess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
|
||
|
||
gluTessBeginPolygon(prtess, s);
|
||
gluTessBeginContour(prtess);
|
||
|
||
i = 0;
|
||
while (i < sec->wallnum)
|
||
{
|
||
gluTessVertex(prtess, s->verts + (3 * i), (void *)i);
|
||
if ((i != (sec->wallnum - 1)) && ((sec->wallptr + i) > wall[sec->wallptr + i].point2))
|
||
{
|
||
gluTessEndContour(prtess);
|
||
gluTessBeginContour(prtess);
|
||
}
|
||
i++;
|
||
}
|
||
gluTessEndContour(prtess);
|
||
gluTessEndPolygon(prtess);
|
||
|
||
if (pr_verbosity >= 2) OSD_Printf("PR : Tesselated floor of sector %i.\n", sectnum);
|
||
|
||
return (1);
|
||
}
|
||
|
||
int polymer_initsector(short sectnum)
|
||
{
|
||
sectortype *sec;
|
||
_prsector* s;
|
||
|
||
if (pr_verbosity >= 2) OSD_Printf("PR : Initalizing sector %i...\n", sectnum);
|
||
|
||
sec = §or[sectnum];
|
||
s = malloc(sizeof(_prsector));
|
||
if (s == NULL)
|
||
{
|
||
if (pr_verbosity >= 1) OSD_Printf("PR : Cannot initialize sector %i : malloc failed.\n", sectnum);
|
||
return (0);
|
||
}
|
||
|
||
s->invalidate = 0;
|
||
s->wallcount = sec->wallnum;
|
||
|
||
s->verts = calloc(s->wallcount, sizeof(GLdouble) * 3);
|
||
s->floorbuffer = calloc(s->wallcount, sizeof(GLfloat) * 5);
|
||
s->ceilbuffer = calloc(s->wallcount, sizeof(GLfloat) * 5);
|
||
if ((s->verts == NULL) || (s->floorbuffer == NULL) || (s->ceilbuffer == NULL))
|
||
{
|
||
if (pr_verbosity >= 1) OSD_Printf("PR : Cannot initialize geometry of sector %i : malloc failed.\n", sectnum);
|
||
return (0);
|
||
}
|
||
|
||
s->indices = NULL;
|
||
|
||
prsectors[sectnum] = s;
|
||
|
||
if (pr_verbosity >= 2) OSD_Printf("PR : Initalized sector %i.\n", sectnum);
|
||
|
||
return (1);
|
||
}
|
||
|
||
void polymer_drawsector(long daposx, long daposy, long daposz, short daang, long dahoriz, short sectnum)
|
||
{
|
||
sectortype *sec, *nextsec;
|
||
walltype *wal;
|
||
_prsector* s;
|
||
float ang;
|
||
double pos[3];
|
||
int i;
|
||
long zdiff;
|
||
pthtyp* pth;
|
||
|
||
if (pr_verbosity >= 3) OSD_Printf("PR : Drawing sector %i...\n", sectnum);
|
||
|
||
if (prsectors[sectnum] == NULL)
|
||
{
|
||
polymer_initsector(sectnum);
|
||
polymer_updategeometry(sectnum);
|
||
polymer_buildfloor(sectnum);
|
||
}
|
||
else if (prsectors[sectnum]->invalidate)
|
||
{
|
||
if (pr_verbosity >= 2) OSD_Printf("PR : Sector %i invalidated. Tesselating...\n", sectnum);
|
||
polymer_updategeometry(sectnum);
|
||
polymer_buildfloor(sectnum);
|
||
prsectors[sectnum]->invalidate = 0;
|
||
}
|
||
|
||
sec = §or[sectnum];
|
||
wal = &wall[sec->wallptr];
|
||
s = prsectors[sectnum];
|
||
|
||
ang = (float)(daang) / (2048.0f / 360.0f);
|
||
|
||
pos[0] = -daposy;
|
||
pos[1] = daposz;
|
||
pos[2] = daposx;
|
||
|
||
bglEnableClientState(GL_VERTEX_ARRAY);
|
||
bglEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||
|
||
bglMatrixMode(GL_MODELVIEW);
|
||
bglLoadIdentity();
|
||
bglRotatef(ang, 0.0f, 1.0f, 0.0f);
|
||
bglScalef(1.0f, 1.0f / 16.0f, 1.0f);
|
||
bglTranslatef(pos[0], pos[1], pos[2]);
|
||
|
||
// floor
|
||
pth = gltexcache(sec->floorpicnum,sec->floorpal,0);
|
||
bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0);
|
||
bglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||
bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), s->floorbuffer);
|
||
bglTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), &s->floorbuffer[3]);
|
||
bglDrawElements(GL_TRIANGLES, s->indicescount, GL_UNSIGNED_SHORT, s->indices);
|
||
|
||
// ceiling
|
||
pth = gltexcache(sec->ceilingpicnum,sec->ceilingpal,0);
|
||
bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0);
|
||
bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), s->ceilbuffer);
|
||
bglTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), &s->ceilbuffer[3]);
|
||
bglDrawElements(GL_TRIANGLES, s->indicescount, GL_UNSIGNED_SHORT, s->indices);
|
||
|
||
bglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||
bglDisableClientState(GL_VERTEX_ARRAY);
|
||
|
||
/*// walls
|
||
i = 0;
|
||
while (i < sec->wallnum)
|
||
{
|
||
if (wal->nextsector == -1)
|
||
{ // limit of the map
|
||
pth = gltexcache(wal->picnum,wal->pal,0);
|
||
bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0);
|
||
bglColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||
bglBegin(GL_QUADS);
|
||
bglVertex3d(s->verts[i].v[0], s->verts[i].v[1], s->verts[i].v[2]);
|
||
bglVertex3d(s->verts[wal->point2 - sec->wallptr].v[0], s->verts[wal->point2 - sec->wallptr].v[1], s->verts[wal->point2 - sec->wallptr].v[2]);
|
||
bglVertex3d(s->verts[wal->point2 - sec->wallptr].v[0], s->verts[wal->point2 - sec->wallptr].v[1] + (sec->floorz - sec->ceilingz), s->verts[wal->point2 - sec->wallptr].v[2]);
|
||
bglVertex3d(s->verts[i].v[0], s->verts[i].v[1] + (sec->floorz - sec->ceilingz), s->verts[i].v[2]);
|
||
bglEnd();
|
||
}
|
||
else
|
||
{
|
||
nextsec = §or[wal->nextsector];
|
||
zdiff = sec->floorz - nextsec->floorz;
|
||
if (zdiff > 0)
|
||
{ // floor polymerization
|
||
pth = gltexcache(wal->picnum,wal->pal,0);
|
||
bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0);
|
||
bglColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||
bglBegin(GL_QUADS);
|
||
bglVertex3d(s->verts[i].v[0], s->verts[i].v[1], s->verts[i].v[2]);
|
||
bglVertex3d(s->verts[wal->point2 - sec->wallptr].v[0], s->verts[wal->point2 - sec->wallptr].v[1], s->verts[wal->point2 - sec->wallptr].v[2]);
|
||
bglVertex3d(s->verts[wal->point2 - sec->wallptr].v[0], s->verts[wal->point2 - sec->wallptr].v[1] + zdiff, s->verts[wal->point2 - sec->wallptr].v[2]);
|
||
bglVertex3d(s->verts[i].v[0], s->verts[i].v[1] + zdiff, s->verts[i].v[2]);
|
||
bglEnd();
|
||
}
|
||
zdiff = sec->ceilingz - nextsec->ceilingz;
|
||
if (zdiff > 0)
|
||
{ // ceiling polymerization
|
||
pth = gltexcache(wal->picnum,wal->pal,0);
|
||
bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0);
|
||
bglColor4f(1.0f, 0.0f, 1.0f, 1.0f);
|
||
bglBegin(GL_QUADS);
|
||
bglVertex3d(s->verts[i].v[0], s->verts[i].v[1] + (sec->floorz - sec->ceilingz), s->verts[i].v[2]);
|
||
bglVertex3d(s->verts[wal->point2 - sec->wallptr].v[0], s->verts[wal->point2 - sec->wallptr].v[1] + (sec->floorz - sec->ceilingz), s->verts[wal->point2 - sec->wallptr].v[2]);
|
||
bglVertex3d(s->verts[wal->point2 - sec->wallptr].v[0], s->verts[wal->point2 - sec->wallptr].v[1] + zdiff + (sec->floorz - sec->ceilingz), s->verts[wal->point2 - sec->wallptr].v[2]);
|
||
bglVertex3d(s->verts[i].v[0], s->verts[i].v[1] + zdiff + (sec->floorz - sec->ceilingz), s->verts[i].v[2]);
|
||
bglEnd();
|
||
}
|
||
}
|
||
|
||
|
||
i++;
|
||
wal = &wall[sec->wallptr + i];
|
||
}*/
|
||
|
||
if (pr_verbosity >= 3) OSD_Printf("PR : Finished drawing sector %i...\n", sectnum);
|
||
}
|
||
|
||
void polymer_drawrooms(long daposx, long daposy, long daposz, short daang, long dahoriz, short dacursectnum)
|
||
{
|
||
int i;
|
||
|
||
if (pr_verbosity >= 3) OSD_Printf("PR : Drawing rooms...\n");
|
||
|
||
polymer_glinit();
|
||
|
||
i = 0;
|
||
while (i < numsectors)
|
||
{
|
||
polymer_drawsector(daposx, daposy, daposz, daang, dahoriz, i);
|
||
i++;
|
||
}
|
||
|
||
bglMatrixMode(GL_PROJECTION);
|
||
bglLoadMatrixf(polymostprojmatrix);
|
||
bglMatrixMode(GL_MODELVIEW);
|
||
bglLoadMatrixf(polymostmodelmatrix);
|
||
|
||
if (pr_verbosity >= 3) OSD_Printf("PR : Rooms drawn.\n");
|
||
}
|