mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 17:01:51 +00:00
More Polymer portal stuff. Renders most stuff correctly and somewhat fast.
- pr_scissors to toggle scissors testing. This should reduce GPU load and prevent normally invisible stuff from being drawn. - pr_showportals to show visportals and scissors if they are enabled. Debugging feature. Issues: - screen may flicker on the edge of some sectors. Probably an accuracy issue somewhere. - some maps make the algorithm loop too much (slow) or indefinitely (hang) for some reason. git-svn-id: https://svn.eduke32.com/eduke32@595 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
2fc1832cab
commit
d94973a174
4 changed files with 273 additions and 109 deletions
|
@ -31,10 +31,8 @@
|
|||
# include "pragmas.h"
|
||||
# include <math.h>
|
||||
|
||||
//# define differentsign(x, y) ((((x) < 0) && ((y) > 0)) || (((x) > 0) && ((y) < 0)))
|
||||
|
||||
// CVARS
|
||||
extern int pr_cliplanes;
|
||||
extern int pr_scissorstest;
|
||||
extern int pr_fov;
|
||||
extern int pr_showportals;
|
||||
extern int pr_verbosity;
|
||||
|
@ -106,15 +104,18 @@ int polymer_initwall(short wallnum);
|
|||
void polymer_updatewall(short wallnum);
|
||||
void polymer_drawwall(short wallnum);
|
||||
// HSR
|
||||
void polymer_portaltofrustum(GLfloat* portal, int portalpointcount, GLfloat* pos, GLfloat* frustum);
|
||||
void polymer_triangletoplane(GLfloat* triangle, GLfloat* plane);
|
||||
void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLfloat* out);
|
||||
void polymer_extractfrustum(GLdouble* modelview, GLdouble* projection);
|
||||
void polymer_drawroom(short sectnum);
|
||||
int polymer_checkportal(short wallnum);
|
||||
int polymer_portalinfrustum(short wallnum);
|
||||
float polymer_pointdistancetoplane(GLfloat* point, GLfloat* plane);
|
||||
float polymer_pointdistancetopoint(GLfloat* point1, GLfloat* point2);
|
||||
void polymer_lineplaneintersection(GLfloat *point1, GLfloat *point2, float dist1, float dist2, GLfloat *output);
|
||||
int polymer_cliptofrustum(short wallnum, int mask);
|
||||
int polymer_cliptofrustum(short wallnum);
|
||||
void polymer_getportal(GLfloat* portalpoints, int portalpointcount, GLint* output);
|
||||
void polymer_drawportal(void);
|
||||
void polymer_drawportal(int *portal);
|
||||
// SKIES
|
||||
void polymer_initskybox(void);
|
||||
void polymer_getsky(void);
|
||||
|
|
|
@ -5819,6 +5819,7 @@ void drawrooms(int daposx, int daposy, int daposz,
|
|||
{
|
||||
polymer_glinit();
|
||||
polymer_drawrooms(daposx, daposy, daposz, daang, dahoriz, dacursectnum, 1);
|
||||
bglDisable(GL_SCISSOR_TEST);
|
||||
bglDisable(GL_CULL_FACE);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "polymer.h"
|
||||
|
||||
// CVARS
|
||||
int pr_cliplanes = 1;
|
||||
int pr_scissorstest = 1;
|
||||
int pr_fov = 426; // appears to be the classic setting.
|
||||
int pr_showportals = 0;
|
||||
int pr_verbosity = 1; // 0: silent, 1: errors and one-times, 2: multiple-times, 3: flood
|
||||
|
@ -16,17 +16,32 @@ _prwall *prwalls[MAXWALLS];
|
|||
GLfloat skybox[16];
|
||||
|
||||
// CONTROL
|
||||
float frustum[20]; // left right top bottom near
|
||||
float frustumnorms[5];
|
||||
float pos[3];
|
||||
|
||||
float *frustumstack;
|
||||
int frustumstacksize = 0;
|
||||
|
||||
char *frustumsizes;
|
||||
GLint *projectedportals;
|
||||
int maxfrustumcount = 0;
|
||||
|
||||
int frustumdepth = 0;
|
||||
int frustumstackposition = 0;
|
||||
|
||||
int *curportal;
|
||||
|
||||
//float frustumnorms[5];
|
||||
|
||||
GLfloat *clippedportalpoints = NULL;
|
||||
float *distances = NULL;
|
||||
int maxclippedportalpointcount = 0;
|
||||
int clippedportalpointcount;
|
||||
|
||||
GLfloat triangle[9];
|
||||
|
||||
GLdouble modelviewmatrix[16];
|
||||
GLdouble projectionmatrix[16];
|
||||
GLint viewport[4];
|
||||
GLint portal[4];
|
||||
|
||||
GLfloat *portalpoints = NULL;
|
||||
float *distances = NULL;
|
||||
int maxportalpointcount = 0;
|
||||
|
||||
int updatesectors = 1;
|
||||
|
||||
|
@ -64,6 +79,44 @@ int polymer_init(void)
|
|||
return (0);
|
||||
}
|
||||
|
||||
if (frustumstacksize == 0)
|
||||
{
|
||||
frustumstacksize = 20; // 5 planes, 4 components
|
||||
frustumstack = malloc(frustumstacksize * sizeof(float));
|
||||
if (!frustumstack)
|
||||
{
|
||||
if (pr_verbosity >= 1) OSD_Printf("PR : Cannot allocate initial frustum stack : malloc failed.\n");
|
||||
frustumstacksize = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxfrustumcount == 0)
|
||||
{
|
||||
maxfrustumcount = 1;
|
||||
frustumsizes = malloc (maxfrustumcount * sizeof(char));
|
||||
projectedportals = malloc(maxfrustumcount * 4 * sizeof(GLint));
|
||||
if (!frustumsizes || !projectedportals)
|
||||
{
|
||||
if (pr_verbosity >= 1) OSD_Printf("PR : Cannot allocate initial frustum size record : malloc failed.\n");
|
||||
maxfrustumcount = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxclippedportalpointcount == 0)
|
||||
{
|
||||
maxclippedportalpointcount = 4;
|
||||
clippedportalpoints = calloc(maxclippedportalpointcount, sizeof(GLfloat) * 3);
|
||||
distances = calloc(maxclippedportalpointcount, sizeof(float));
|
||||
if (!clippedportalpoints || !distances)
|
||||
{
|
||||
if (pr_verbosity >= 1) OSD_Printf("PR : Cannot allocate initial clipping memory : malloc failed.\n");
|
||||
maxclippedportalpointcount = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
polymer_loadboard();
|
||||
|
||||
polymer_initskybox();
|
||||
|
@ -122,6 +175,9 @@ void polymer_glinit(void)
|
|||
|
||||
bglEnable(GL_CULL_FACE);
|
||||
bglCullFace(GL_BACK);
|
||||
|
||||
if (pr_scissorstest)
|
||||
bglEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void polymer_loadboard(void)
|
||||
|
@ -152,7 +208,6 @@ void polymer_drawrooms(int daposx, int daposy, int daposz, short
|
|||
{
|
||||
int i, j;
|
||||
float ang, horizang, tiltang;
|
||||
double pos[3];
|
||||
_point2d ref;
|
||||
sectortype *sec;
|
||||
walltype *wal;
|
||||
|
@ -165,9 +220,9 @@ void polymer_drawrooms(int daposx, int daposy, int daposz, short
|
|||
tiltang = (gtang * 90.0f);
|
||||
fov = (pr_fov * (float)xdim / (float)ydim * 1) / 2;
|
||||
|
||||
pos[0] = -daposy;
|
||||
pos[1] = daposz;
|
||||
pos[2] = daposx;
|
||||
pos[0] = daposy;
|
||||
pos[1] = -daposz;
|
||||
pos[2] = -daposx;
|
||||
|
||||
bglMatrixMode(GL_MODELVIEW);
|
||||
bglLoadIdentity();
|
||||
|
@ -182,18 +237,27 @@ void polymer_drawrooms(int daposx, int daposy, int daposz, short
|
|||
bglEnable(GL_DEPTH_TEST);
|
||||
|
||||
bglScalef(1.0f / 1000.0f, 1.0f / 16000.0f, 1.0f / 1000.0f);
|
||||
bglTranslatef(pos[0], pos[1], pos[2]);
|
||||
bglTranslatef(-pos[0], -pos[1], -pos[2]);
|
||||
|
||||
// get the new modelview
|
||||
bglGetDoublev(GL_MODELVIEW_MATRIX, modelviewmatrix);
|
||||
|
||||
polymer_extractfrustum(modelviewmatrix, projectionmatrix);
|
||||
|
||||
// initialize the portal to the whole viewport
|
||||
memcpy(portal, viewport, sizeof(GLint) * 4);
|
||||
if (pr_scissorstest)
|
||||
{
|
||||
memcpy(projectedportals, viewport, sizeof(GLint) * 4);
|
||||
bglScissor(projectedportals[0],
|
||||
viewport[3] - projectedportals[3],
|
||||
projectedportals[2] - projectedportals[0],
|
||||
projectedportals[3] - projectedportals[1]);
|
||||
}
|
||||
|
||||
frustumsizes[0] = 5;
|
||||
frustumdepth = 0;
|
||||
frustumstackposition = 0;
|
||||
|
||||
// game tic
|
||||
if (updatesectors || 1)
|
||||
if (updatesectors)
|
||||
{
|
||||
i = 0;
|
||||
while (i < numsectors)
|
||||
|
@ -957,6 +1021,51 @@ void polymer_drawwall(short wallnum)
|
|||
}
|
||||
|
||||
// HSR
|
||||
void polymer_portaltofrustum(GLfloat* portal, int portalpointcount, GLfloat* pos, GLfloat* frustum)
|
||||
{
|
||||
int i;
|
||||
|
||||
memcpy(&triangle[3], pos, sizeof(GLfloat) * 3);
|
||||
i = 0;
|
||||
while (i < portalpointcount)
|
||||
{
|
||||
memcpy(&triangle[0], &portal[i * 3], sizeof(GLfloat) * 3);
|
||||
if (i != (portalpointcount - 1))
|
||||
memcpy(&triangle[6], &portal[(i+1) * 3], sizeof(GLfloat) * 3);
|
||||
else
|
||||
memcpy(&triangle[6], &portal[0], sizeof(GLfloat) * 3);
|
||||
polymer_triangletoplane(triangle, &frustum[i*4]);
|
||||
i++;
|
||||
}
|
||||
|
||||
//near
|
||||
memcpy(&triangle[3], &portal[(i-2) * 3], sizeof(GLfloat) * 3);
|
||||
polymer_triangletoplane(triangle, &frustum[i*4]);
|
||||
}
|
||||
|
||||
void polymer_triangletoplane(GLfloat* triangle, GLfloat* plane)
|
||||
{
|
||||
GLfloat vec1[3], vec2[3];
|
||||
|
||||
vec1[0] = triangle[3] - triangle[0];
|
||||
vec1[1] = triangle[4] - triangle[1];
|
||||
vec1[2] = triangle[5] - triangle[2];
|
||||
|
||||
vec2[0] = triangle[6] - triangle[0];
|
||||
vec2[1] = triangle[7] - triangle[1];
|
||||
vec2[2] = triangle[8] - triangle[2];
|
||||
|
||||
polymer_crossproduct(vec1, vec2, plane);
|
||||
|
||||
plane[3] = -(plane[0] * triangle[0] + plane[1] * triangle[1] + plane[2] * triangle[2]);
|
||||
}
|
||||
void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLfloat* out)
|
||||
{
|
||||
out[0] = in_a[1] * in_b[2] - in_a[2] * in_b[1];
|
||||
out[1] = in_a[2] * in_b[0] - in_a[0] * in_b[2];
|
||||
out[2] = in_a[0] * in_b[1] - in_a[1] * in_b[0];
|
||||
}
|
||||
|
||||
void polymer_extractfrustum(GLdouble* modelview, GLdouble* projection)
|
||||
{
|
||||
GLdouble matrix[16];
|
||||
|
@ -971,22 +1080,22 @@ void polymer_extractfrustum(GLdouble* modelview, GLdouble* projec
|
|||
i = 0;
|
||||
while (i < 4)
|
||||
{
|
||||
frustum[i] = matrix[(4 * i) + 3] + matrix[4 * i]; // left
|
||||
frustum[i + 4] = matrix[(4 * i) + 3] - matrix[4 * i]; // right
|
||||
frustum[i + 8] = matrix[(4 * i) + 3] - matrix[(4 * i) + 1]; // top
|
||||
frustum[i + 12] = matrix[(4 * i) + 3] + matrix[(4 * i) + 1]; // bottom
|
||||
frustum[i + 16] = matrix[(4 * i) + 3] + matrix[(4 * i) + 2]; // near
|
||||
frustumstack[i] = matrix[(4 * i) + 3] + matrix[4 * i]; // left
|
||||
frustumstack[i + 4] = matrix[(4 * i) + 3] - matrix[4 * i]; // right
|
||||
frustumstack[i + 8] = matrix[(4 * i) + 3] - matrix[(4 * i) + 1]; // top
|
||||
frustumstack[i + 12] = matrix[(4 * i) + 3] + matrix[(4 * i) + 1]; // bottom
|
||||
frustumstack[i + 16] = matrix[(4 * i) + 3] + matrix[(4 * i) + 2]; // near
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while (i < 5)
|
||||
/*while (i < 5)
|
||||
{
|
||||
// frustum plane norms
|
||||
frustumnorms[i] = sqrt((frustum[(i * 4) + 0] * frustum[(i * 4) + 0]) +
|
||||
(frustum[(i * 4) + 1] * frustum[(i * 4) + 1]) +
|
||||
(frustum[(i * 4) + 2] * frustum[(i * 4) + 2]));
|
||||
i++;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : Frustum extracted.\n");
|
||||
}
|
||||
|
@ -996,38 +1105,100 @@ void polymer_drawroom(short sectnum)
|
|||
int i, j;
|
||||
sectortype *sec;
|
||||
walltype *wal;
|
||||
GLint curportal[4];
|
||||
GLfloat currecursive;
|
||||
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : Drawing room %d.\n", sectnum);
|
||||
|
||||
sec = §or[sectnum];
|
||||
wal = &wall[sec->wallptr];
|
||||
|
||||
memcpy(curportal, portal, sizeof(GLint) * 4);
|
||||
|
||||
// first draw the sector
|
||||
bglScissor(portal[0], viewport[3] - portal[3], portal[2] - portal[0], portal[3] - portal[1]);
|
||||
bglEnable(GL_SCISSOR_TEST);
|
||||
polymer_drawsector(sectnum);
|
||||
prsectors[sectnum]->drawingstate = 1;
|
||||
bglDisable(GL_SCISSOR_TEST);
|
||||
|
||||
i = 0;
|
||||
while (i < sec->wallnum)
|
||||
{
|
||||
if ((prwalls[sec->wallptr + i]->drawn == 0) && (wallvisible(sec->wallptr + i)) && polymer_checkportal(sec->wallptr + i))
|
||||
if ((prwalls[sec->wallptr + i]->drawn == 0) && (wallvisible(sec->wallptr + i)) && (j = polymer_portalinfrustum(sec->wallptr + i)))
|
||||
{
|
||||
polymer_drawwall(sec->wallptr + i);
|
||||
prwalls[sec->wallptr + i]->drawn = 1;
|
||||
|
||||
if ((wal->nextsector != -1) && (prsectors[wal->nextsector]->drawingstate == 0))
|
||||
{
|
||||
if (j > 1)
|
||||
{
|
||||
// the wall intersected at least one plane and needs to be clipped
|
||||
clippedportalpointcount = polymer_cliptofrustum(sec->wallptr + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
clippedportalpointcount = 4;
|
||||
memcpy(clippedportalpoints, prwalls[sec->wallptr + i]->portal, sizeof(float) * clippedportalpointcount * 3);
|
||||
}
|
||||
|
||||
if (pr_showportals)
|
||||
{
|
||||
bglDisable(GL_FOG);
|
||||
bglDisable(GL_TEXTURE_2D);
|
||||
bglColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
bglBegin(GL_LINE_LOOP);
|
||||
j = 0;
|
||||
while (j < clippedportalpointcount)
|
||||
{
|
||||
bglVertex3fv(&clippedportalpoints[j*3]);
|
||||
j++;
|
||||
}
|
||||
bglEnd();
|
||||
bglEnable(GL_FOG);
|
||||
bglEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
if (frustumstacksize <= (frustumstackposition + (frustumsizes[frustumdepth] + clippedportalpointcount + 1) * 4))
|
||||
{
|
||||
frustumstacksize += (clippedportalpointcount + 1) * 4; // don't forget the near plane
|
||||
frustumstack = realloc(frustumstack, sizeof(GLfloat) * frustumstacksize);
|
||||
}
|
||||
if (maxfrustumcount == (frustumdepth + 1))
|
||||
{
|
||||
maxfrustumcount++;
|
||||
frustumsizes = realloc(frustumsizes, sizeof(char) * maxfrustumcount);
|
||||
projectedportals = realloc(projectedportals, maxfrustumcount * 4 * sizeof(GLint));
|
||||
}
|
||||
// push a new frustum on the stack
|
||||
frustumstackposition += frustumsizes[frustumdepth] * 4;
|
||||
frustumdepth++;
|
||||
frustumsizes[frustumdepth] = (clippedportalpointcount + 1); // don't forget the near plane
|
||||
|
||||
// calculate the new frustum data
|
||||
polymer_portaltofrustum(clippedportalpoints, clippedportalpointcount, pos, &frustumstack[frustumstackposition]);
|
||||
|
||||
if (pr_scissorstest)
|
||||
{
|
||||
// project the scissor
|
||||
curportal = &projectedportals[frustumdepth * 4];
|
||||
polymer_getportal(clippedportalpoints, clippedportalpointcount, curportal);
|
||||
bglScissor(curportal[0] - 1, viewport[3] - curportal[3] - 1, curportal[2] - curportal[0] + 2, curportal[3] - curportal[1] + 2);
|
||||
|
||||
// draw the new scissor
|
||||
if (pr_showportals)
|
||||
polymer_drawportal(curportal);
|
||||
}
|
||||
|
||||
// recurse
|
||||
polymer_drawroom(wal->nextsector);
|
||||
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : Popping...\n");
|
||||
frustumdepth--;
|
||||
frustumstackposition -= frustumsizes[frustumdepth] * 4;
|
||||
|
||||
if (pr_scissorstest)
|
||||
{
|
||||
// pop the scissor
|
||||
curportal = &projectedportals[frustumdepth * 4];
|
||||
bglScissor(curportal[0] - 1, viewport[3] - curportal[3] - 1, curportal[2] - curportal[0] + 2, curportal[3] - curportal[1] + 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : Popping portal...\n");
|
||||
memcpy(portal, curportal, sizeof(GLint) * 4);
|
||||
polymer_drawwall(sec->wallptr + i);
|
||||
|
||||
prwalls[sec->wallptr + i]->drawn = 0;
|
||||
}
|
||||
|
@ -1038,56 +1209,17 @@ void polymer_drawroom(short sectnum)
|
|||
prsectors[sectnum]->drawingstate = 0;
|
||||
}
|
||||
|
||||
int polymer_checkportal(short wallnum)
|
||||
{
|
||||
// Returns 1 if the wall is in the current portal and sets the current portal to the wall, returns 0 otherwise
|
||||
GLint wallportal[4], newportal[4];
|
||||
int mask, portalpointcount;
|
||||
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : Checking wall %d.\n", wallnum);
|
||||
|
||||
mask = polymer_portalinfrustum(wallnum);
|
||||
|
||||
if (mask == 0)
|
||||
return (0); // not visible
|
||||
if (mask > 1)
|
||||
{
|
||||
// only some points visible, clip the polygon to the viewport
|
||||
portalpointcount = polymer_cliptofrustum(wallnum, mask);
|
||||
polymer_getportal(portalpoints, portalpointcount, wallportal);
|
||||
}
|
||||
else // all visible
|
||||
polymer_getportal(prwalls[wallnum]->portal, 4, wallportal);
|
||||
|
||||
if ((wallportal[0] > portal[2]) || (wallportal[2] < portal[0]) || (wallportal[1] > portal[3]) || (wallportal[3] < portal[1]))
|
||||
return (0); // the wall is totally outside the current portal
|
||||
|
||||
// we need to find the intersection of the current portal and the wall portal
|
||||
newportal[0] = portal[0] + (klabs(wallportal[0] - portal[0]) + (wallportal[0] - portal[0])) / 2;
|
||||
newportal[1] = portal[1] + (klabs(wallportal[1] - portal[1]) + (wallportal[1] - portal[1])) / 2;
|
||||
newportal[2] = portal[2] + ((wallportal[2] - portal[2]) - klabs(wallportal[2] - portal[2])) / 2;
|
||||
newportal[3] = portal[3] + ((wallportal[3] - portal[3]) - klabs(wallportal[3] - portal[3])) / 2;
|
||||
|
||||
// update the view portal
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : Updating portal...\n");
|
||||
memcpy(portal, newportal, sizeof(GLint) * 4);
|
||||
|
||||
// draw the new portal
|
||||
if (pr_showportals)
|
||||
polymer_drawportal();
|
||||
|
||||
return (1);
|
||||
}
|
||||
int polymer_portalinfrustum(short wallnum)
|
||||
{
|
||||
int i, j, k, result;
|
||||
float sqdist;
|
||||
float sqdist, *frustum;
|
||||
_prwall *w;
|
||||
|
||||
frustum = &frustumstack[frustumstackposition];
|
||||
w = prwalls[wallnum];
|
||||
|
||||
i = result = 0;
|
||||
while (i < 4)
|
||||
while (i < frustumsizes[frustumdepth])
|
||||
{
|
||||
j = k = 0;
|
||||
while (j < 4)
|
||||
|
@ -1121,8 +1253,15 @@ float polymer_pointdistancetoplane(GLfloat* point, GLfloat* plane)
|
|||
plane[1] * point[1] +
|
||||
plane[2] * point[2] +
|
||||
plane[3];
|
||||
|
||||
return (result);
|
||||
}
|
||||
float polymer_pointdistancetopoint(GLfloat* point1, GLfloat* point2)
|
||||
{
|
||||
return ((point2[0] - point1[0]) * (point2[0] - point1[0]) +
|
||||
(point2[1] - point1[1]) * (point2[1] - point1[1]) +
|
||||
(point2[2] - point1[2]) * (point2[2] - point1[2]));
|
||||
}
|
||||
|
||||
void polymer_lineplaneintersection(GLfloat *point1, GLfloat *point2, float dist1, float dist2, GLfloat *output)
|
||||
{
|
||||
|
@ -1138,31 +1277,32 @@ void polymer_lineplaneintersection(GLfloat *point1, GLfloat *poin
|
|||
memcpy(output, result, sizeof(GLfloat) * 3);
|
||||
}
|
||||
|
||||
int polymer_cliptofrustum(short wallnum, int mask)
|
||||
int polymer_cliptofrustum(short wallnum)
|
||||
{
|
||||
// sutherland-hofnman polygon clipping algorithm against all planes of the frustum
|
||||
GLfloat intersect[3];
|
||||
GLfloat intersect[3], *frustum;
|
||||
int i, j, k, l, m, result, exitpoint;
|
||||
|
||||
if (portalpoints == NULL)
|
||||
{
|
||||
// one-time initialization
|
||||
portalpoints = calloc(4, sizeof(GLfloat) * 3);
|
||||
distances = calloc(4, sizeof(float));
|
||||
maxportalpointcount = 4;
|
||||
}
|
||||
frustum = &frustumstack[frustumstackposition];
|
||||
result = 4; // 4 points to start with
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : Clipping wall %d...\n", wallnum);
|
||||
memcpy(portalpoints, prwalls[wallnum]->portal, sizeof(GLfloat) * 3 * 4);
|
||||
memcpy(clippedportalpoints, prwalls[wallnum]->portal, sizeof(GLfloat) * 3 * 4);
|
||||
|
||||
i = 0;
|
||||
while (i < 4)
|
||||
while (i < frustumsizes[frustumdepth])
|
||||
{
|
||||
if ((frustumdepth == 0) && (i == frustumsizes[frustumdepth] - 1))
|
||||
{
|
||||
// don't near-clip with the viewing frustum
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
// frustum planes
|
||||
j = k = 0;
|
||||
m = -1;
|
||||
while (j < result)
|
||||
{
|
||||
distances[j] = polymer_pointdistancetoplane(&portalpoints[j * 3], &frustum[i * 4]);
|
||||
distances[j] = polymer_pointdistancetoplane(&clippedportalpoints[j * 3], &frustum[i * 4]);
|
||||
if (distances[j] < 0)
|
||||
k = 1; // at least one is outside
|
||||
if ((distances[j] > 0) && (m < 0))
|
||||
|
@ -1189,7 +1329,7 @@ int polymer_cliptofrustum(short wallnum, int mask)
|
|||
if ((distances[j] >= 0) && (distances[l] < 0))
|
||||
{
|
||||
// case 1 : line exits the plane -> compute intersection
|
||||
polymer_lineplaneintersection(&portalpoints[j * 3], &portalpoints[l * 3], distances[j], distances[l], intersect);
|
||||
polymer_lineplaneintersection(&clippedportalpoints[j * 3], &clippedportalpoints[l * 3], distances[j], distances[l], intersect);
|
||||
exitpoint = l;
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : %d: EXIT\n", j);
|
||||
}
|
||||
|
@ -1202,7 +1342,7 @@ int polymer_cliptofrustum(short wallnum, int mask)
|
|||
result--;
|
||||
if (j != result)
|
||||
{
|
||||
memmove(&portalpoints[j * 3], &portalpoints[l * 3], (result - j) * sizeof(GLfloat) * 3);
|
||||
memmove(&clippedportalpoints[j * 3], &clippedportalpoints[l * 3], (result - j) * sizeof(GLfloat) * 3);
|
||||
memmove(&distances[j], &distances[l], (result - j) * sizeof(float));
|
||||
if (m >= l)
|
||||
{
|
||||
|
@ -1214,7 +1354,7 @@ int polymer_cliptofrustum(short wallnum, int mask)
|
|||
l = 0;
|
||||
}
|
||||
else
|
||||
memcpy(&portalpoints[j * 3], intersect, sizeof(GLfloat) * 3); // replace point by intersection from previous entry
|
||||
memcpy(&clippedportalpoints[j * 3], intersect, sizeof(GLfloat) * 3); // replace point by intersection from previous entry
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : %d: IN\n", j);
|
||||
}
|
||||
else if ((distances[j] < 0) && (distances[l] >= 0))
|
||||
|
@ -1223,27 +1363,27 @@ int polymer_cliptofrustum(short wallnum, int mask)
|
|||
if (j == exitpoint)
|
||||
{
|
||||
// if we just exited a point is created
|
||||
if (result == maxportalpointcount)
|
||||
if (result == maxclippedportalpointcount)
|
||||
{
|
||||
portalpoints = realloc(portalpoints, sizeof(GLfloat) * 3 * (maxportalpointcount + 1));
|
||||
distances = realloc(distances, sizeof(float) * (maxportalpointcount + 1));
|
||||
maxportalpointcount++;
|
||||
clippedportalpoints = realloc(clippedportalpoints, sizeof(GLfloat) * 3 * (maxclippedportalpointcount + 1));
|
||||
distances = realloc(distances, sizeof(float) * (maxclippedportalpointcount + 1));
|
||||
maxclippedportalpointcount++;
|
||||
}
|
||||
if ((result - 1) != j)
|
||||
{
|
||||
memmove(&portalpoints[(l + 1) * 3], &portalpoints[l * 3], (result - l) * sizeof(GLfloat) * 3);
|
||||
memmove(&clippedportalpoints[(l + 1) * 3], &clippedportalpoints[l * 3], (result - l) * sizeof(GLfloat) * 3);
|
||||
memmove(&distances[l + 1], &distances[l], (result - l) * sizeof(float));
|
||||
if (m >= l)
|
||||
m++;
|
||||
}
|
||||
result++;
|
||||
polymer_lineplaneintersection(&portalpoints[j * 3], &portalpoints[l * 3], distances[j], distances[l], &portalpoints[(j + 1) * 3]);
|
||||
memcpy(&portalpoints[j * 3], intersect, sizeof(GLfloat) * 3); // replace point by intersection from previous entry
|
||||
polymer_lineplaneintersection(&clippedportalpoints[j * 3], &clippedportalpoints[l * 3], distances[j], distances[l], &clippedportalpoints[(j + 1) * 3]);
|
||||
memcpy(&clippedportalpoints[j * 3], intersect, sizeof(GLfloat) * 3); // replace point by intersection from previous entry
|
||||
if ((l) && (l != m))
|
||||
l++; // if not at the end of the list, skip the point we just created
|
||||
}
|
||||
else
|
||||
polymer_lineplaneintersection(&portalpoints[j * 3], &portalpoints[l * 3], distances[j], distances[l], &portalpoints[j * 3]);
|
||||
polymer_lineplaneintersection(&clippedportalpoints[j * 3], &clippedportalpoints[l * 3], distances[j], distances[l], &clippedportalpoints[j * 3]);
|
||||
if (pr_verbosity >= 3) OSD_Printf("PR : %d: ENTER\n", j);
|
||||
}
|
||||
else
|
||||
|
@ -1258,6 +1398,28 @@ int polymer_cliptofrustum(short wallnum, int mask)
|
|||
i++;
|
||||
}
|
||||
|
||||
// pruning duplicates
|
||||
i = 0;
|
||||
while (i < result)
|
||||
{
|
||||
if (i == (result - 1))
|
||||
intersect[0] = polymer_pointdistancetopoint(&clippedportalpoints[i*3], &clippedportalpoints[0]);
|
||||
else
|
||||
intersect[0] = polymer_pointdistancetopoint(&clippedportalpoints[i*3], &clippedportalpoints[(i+1)*3]);
|
||||
if (intersect[0] < 1)
|
||||
{
|
||||
if (i == (result - 1))
|
||||
result--;
|
||||
else
|
||||
{
|
||||
result--;
|
||||
memmove(&clippedportalpoints[i*3], &clippedportalpoints[(i+1)*3], (result - i) * sizeof(GLfloat) * 3);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
@ -1295,7 +1457,7 @@ void polymer_getportal(GLfloat* portalpoints, int portalpointcoun
|
|||
}
|
||||
}
|
||||
|
||||
void polymer_drawportal(void)
|
||||
void polymer_drawportal(int *portal)
|
||||
{
|
||||
bglMatrixMode(GL_PROJECTION);
|
||||
bglPushMatrix();
|
||||
|
@ -1305,7 +1467,7 @@ void polymer_drawportal(void)
|
|||
bglPushMatrix();
|
||||
bglLoadIdentity();
|
||||
|
||||
bglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
bglColor4f(1.0f, (1.0f - 0.1 * (frustumdepth-1)), (1.0f - 0.1 * (frustumdepth-1)), 1.0f);
|
||||
bglDisable(GL_TEXTURE_2D);
|
||||
|
||||
bglBegin(GL_LINE_LOOP);
|
||||
|
|
|
@ -690,7 +690,7 @@ cvar[] =
|
|||
{ "r_anamorphic", "r_anamorphic: enable/disable widescreen mode", (void*)&glwidescreen, CVAR_BOOL, 0, 0, 1 },
|
||||
{ "r_projectionhack", "r_projectionhack: enable/disable projection hack", (void*)&glprojectionhacks, CVAR_BOOL, 0, 0, 1 },
|
||||
// polymer cvars
|
||||
{ "pr_cliplanes", "pr_cliplanes: toggles clipping behind map limits (recommended yet may decrease performance in complex maps)", (void*)&pr_cliplanes, CVAR_INT, 0, 0, 1 },
|
||||
{ "pr_scissorstest", "pr_scissorstest: scissors testing", (void*)&pr_scissorstest, CVAR_INT, 0, 0, 1 },
|
||||
{ "pr_fov", "pr_fov: sets the field of vision in build angle", (void*)&pr_fov, CVAR_INT, 0, 0, 1023},
|
||||
{ "pr_showportals", "pr_showportals: toggles frustum culling (recommended)", (void*)&pr_showportals, CVAR_INT, 0, 0, 1 },
|
||||
{ "pr_verbosity", "pr_verbosity: verbosity level of the polymer renderer", (void*)&pr_verbosity, CVAR_INT, 0, 0, 3 },
|
||||
|
|
Loading…
Reference in a new issue