Frustum clipping and cliplanes for map limits. Performance should be alright now.

git-svn-id: https://svn.eduke32.com/eduke32@311 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
Plagman 2006-10-15 18:51:41 +00:00
parent 9002a68e64
commit 6b635120d4
8 changed files with 225 additions and 97 deletions

View file

@ -63,6 +63,7 @@ extern void (APIENTRY * bglPushMatrix)( void );
extern void (APIENTRY * bglPopMatrix)( void );
extern void (APIENTRY * bglLoadIdentity)( void );
extern void (APIENTRY * bglLoadMatrixf)( const GLfloat *m );
extern void (APIENTRY * bglMultMatrixf)( const GLfloat *m );
extern void (APIENTRY * bglRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
extern void (APIENTRY * bglScalef)(GLfloat x, GLfloat y, GLfloat z);
extern void (APIENTRY * bglTranslatef)(GLfloat x, GLfloat y, GLfloat z);

View file

@ -17,9 +17,11 @@
# include "pragmas.h"
// CVARS
extern unsigned int pr_fov;
extern char pr_verbosity;
extern char pr_wireframe;
extern int pr_cliplanes;
extern int pr_fov;
extern int pr_frustumculling;
extern int pr_verbosity;
extern int pr_wireframe;
// DATA
typedef struct s_prsector {
@ -36,8 +38,7 @@ typedef struct s_prsector {
short curindice;
int indicescount;
short wallcount;
char invalidate;
char controlstate; // bit 1: up-to-date, bit 2: geometry invalidated
char drawingstate; // 0: fcuk, 1: in queue, 2: todraw, 3: drawn
} _prsector;
@ -45,6 +46,7 @@ typedef struct s_prwall {
// geometry
GLfloat* wallbuffer;
GLfloat* overbuffer;
GLfloat* portal;
// attributes
GLfloat wallcolor[4], overcolor[4];
GLfloat wallglpic, overglpic;
@ -56,12 +58,14 @@ typedef struct s_prwall {
typedef struct s_cliplane {
_equation left, right, clip;
_point2d ref;
char clipsign;
} _cliplane;
extern _prsector* prsectors[MAXSECTORS];
extern _prwall* prwalls[MAXWALLS];
// CONTROL
extern int updatesectors;
// EXTERNAL FUNCTIONS
int polymer_init(void);
void polymer_glinit(void);
@ -70,7 +74,7 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho
void polymer_rotatesprite(long sx, long sy, long z, short a, short picnum, signed char dashade, char dapalnum, char dastat, long cx1, long cy1, long cx2, long cy2);
void polymer_drawmaskwall(long damaskwallcnt);
void polymer_drawsprite(long snum);
// SECTOR MANAGEMENT
// SECTORS
int polymer_initsector(short sectnum);
int polymer_updatesector(short sectnum);
void PR_CALLBACK polymer_tesscombine(GLdouble v[3], GLdouble *data[4], GLfloat weight[4], GLdouble **out);
@ -79,11 +83,14 @@ void PR_CALLBACK polymer_tessedgeflag(GLenum error);
void PR_CALLBACK polymer_tessvertex(void* vertex, void* sector);
int polymer_buildfloor(short sectnum);
void polymer_drawsector(short sectnum);
// WALL MANAGEMENT
// WALLS
int polymer_initwall(short wallnum);
void polymer_updatewall(short wallnum);
void polymer_drawwall(short wallnum);
// HSR
int wallincliplane(short wallnum, _cliplane* cliplane);
void polymer_extractfrustum(void);
int polymer_portalinfrustum(short wallnum);
void polymer_addcliplane(_equation clip, _equation left, _equation right, long refx, long refy);
int polymer_wallincliplanes(short wallnum);
#endif // !_polymer_h_

View file

@ -8461,13 +8461,13 @@ void dragpoint(short pointhighlight, long dax, long day)
wall[pointhighlight].x = dax;
wall[pointhighlight].y = day;
if (rendmode == 4)
if ((rendmode == 4) && 0)
{
tempshort = wall[pointhighlight].nextwall;
if (tempshort >= 0)
{
prsectors[wall[pointhighlight].nextsector]->invalidate = 1;
prsectors[wall[tempshort].nextsector]->invalidate = 1;
prsectors[wall[pointhighlight].nextsector]->controlstate |= 2;
prsectors[wall[tempshort].nextsector]->controlstate |= 2;
}
}

View file

@ -47,6 +47,7 @@ void (APIENTRY * bglPushMatrix)( void );
void (APIENTRY * bglPopMatrix)( void );
void (APIENTRY * bglLoadIdentity)( void );
void (APIENTRY * bglLoadMatrixf)( const GLfloat *m );
void (APIENTRY * bglMultMatrixf)( const GLfloat *m );
void (APIENTRY * bglRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void (APIENTRY * bglScalef)(GLfloat x, GLfloat y, GLfloat z);
void (APIENTRY * bglTranslatef)(GLfloat x, GLfloat y, GLfloat z);
@ -223,6 +224,7 @@ int loadgldriver(const char *driver)
bglPopMatrix = GETPROC("glPopMatrix");
bglLoadIdentity = GETPROC("glLoadIdentity");
bglLoadMatrixf = GETPROC("glLoadMatrixf");
bglMultMatrixf = GETPROC("glMultMatrixf");
bglRotatef = GETPROC("glRotatef");
bglScalef = GETPROC("glScalef");
bglTranslatef = GETPROC("glTranslatef");
@ -315,23 +317,23 @@ int unloadgldriver(void)
#endif
bglClearColor = NULL;
bglClear = NULL;
bglClear = NULL;
bglColorMask = NULL;
bglAlphaFunc = NULL;
bglBlendFunc = NULL;
bglCullFace = NULL;
bglCullFace = NULL;
bglFrontFace = NULL;
bglPolygonOffset = NULL;
bglPolygonMode = NULL;
bglEnable = NULL;
bglDisable = NULL;
bglPolygonMode = NULL;
bglEnable = NULL;
bglDisable = NULL;
bglGetFloatv = NULL;
bglGetIntegerv = NULL;
bglPushAttrib = NULL;
bglPopAttrib = NULL;
bglGetError = NULL;
bglGetError = NULL;
bglGetString = NULL;
bglHint = NULL;
bglHint = NULL;
// Depth
bglDepthFunc = NULL;
@ -340,13 +342,17 @@ int unloadgldriver(void)
// Matrix
bglMatrixMode = NULL;
bglOrtho = NULL;
bglFrustum = NULL;
bglViewport = NULL;
bglOrtho = NULL;
bglFrustum = NULL;
bglViewport = NULL;
bglPushMatrix = NULL;
bglPopMatrix = NULL;
bglLoadIdentity = NULL;
bglLoadMatrixf = NULL;
bglMultMatrixf = NULL;
bglRotatef = NULL;
bglScalef = NULL;
bglTranslatef = NULL;
// Drawing
bglBegin = NULL;
@ -354,11 +360,11 @@ int unloadgldriver(void)
bglVertex2f = NULL;
bglVertex2i = NULL;
bglVertex3d = NULL;
bglVertex3fv = NULL;
bglVertex3fv = NULL;
bglColor4f = NULL;
bglColor4ub = NULL;
bglTexCoord2d = NULL;
bglTexCoord2f = NULL;
bglTexCoord2d = NULL;
bglTexCoord2f = NULL;
// Lighting
bglShadeModel = NULL;
@ -367,7 +373,7 @@ int unloadgldriver(void)
bglReadPixels = NULL;
// Texture mapping
bglTexEnvf = NULL;
bglTexEnvf = NULL;
bglGenTextures = NULL;
bglDeleteTextures = NULL;
bglBindTexture = NULL;
@ -385,9 +391,9 @@ int unloadgldriver(void)
bglFogfv = NULL;
// Display Lists
bglNewList = NULL;
bglEndList = NULL;
bglCallList = NULL;
bglNewList = NULL;
bglEndList = NULL;
bglCallList = NULL;
// Vertex Arrays
bglEnableClientState = NULL;

View file

@ -3,15 +3,23 @@
#include "polymer.h"
// CVARS
unsigned int pr_fov = 340; // 60 degrees, appears to be the classic setting.
char pr_verbosity = 1; // 0: silent, 1: errors and one-times, 2: multiple-times, 3: flood
char pr_wireframe = 0;
int pr_cliplanes = 1;
int pr_fov = 426; // appears to be the classic setting.
int pr_frustumculling = 1;
int pr_verbosity = 1; // 0: silent, 1: errors and one-times, 2: multiple-times, 3: flood
int pr_wireframe = 0;
// DATA
_prsector *prsectors[MAXSECTORS];
_prwall *prwalls[MAXWALLS];
_cliplane cliplane;
// CONTROL
float frustum[16]; // left right top bottom
_cliplane *cliplanes;
int cliplanecount, maxcliplanecount;
int updatesectors = 1;
GLUtesselator* prtess;
int tempverticescount;
@ -38,6 +46,9 @@ int polymer_init(void)
i++;
}
cliplanes = NULL;
cliplanecount = maxcliplanecount = 0;
prtess = gluNewTess();
if (prtess == 0)
{
@ -93,7 +104,6 @@ void polymer_loadboard(void)
{
polymer_initsector(i);
polymer_updatesector(i);
polymer_buildfloor(i);
i++;
}
@ -119,24 +129,11 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho
if (pr_verbosity >= 3) OSD_Printf("PR : Drawing rooms...\n");
OSD_Printf("PR : %d\n", dahoriz);
ang = (float)(daang) / (2048.0f / 360.0f);
horizang = (float)(100 - dahoriz) / (512.0f / 180.0f);
tiltang = (gtang * 90.0f);
fov = (pr_fov * (float)xdim / (float)ydim * 1) / 2;
// FOV cliplane
rotatepoint(daposx, daposy, daposx, daposy - 1000, daang, &ref.x, &ref.y);
cliplane.clip = equation(daposx, daposy, ref.x, ref.y);
rotatepoint(daposx, daposy, daposx, daposy - 1000, (daang + 512 - fov) & 2047, &ref.x, &ref.y);
cliplane.left = equation(daposx, daposy, ref.x, ref.y);
rotatepoint(daposx, daposy, daposx, daposy - 1000, (daang + 512 + fov) & 2047, &ref.x, &ref.y);
cliplane.right = equation(daposx, daposy, ref.x, ref.y);
rotatepoint(daposx, daposy, daposx, daposy - 1000, (daang + 512) & 2047, &ref.x, &ref.y);
cliplane.ref = ref;
cliplane.clipsign = 1;
pos[0] = -daposy;
pos[1] = daposz;
pos[2] = daposx;
@ -144,26 +141,45 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho
bglMatrixMode(GL_MODELVIEW);
bglLoadIdentity();
bglRotatef(tiltang, 0.0f, 0.0f, -1.0f);
bglRotatef(horizang, 1.0f, 0.0f, 0.0f);
bglRotatef(ang, 0.0f, 1.0f, 0.0f);
bglRotatef(tiltang, 0.0f, 0.0f, -1.0f);
bglScalef(1.0f, 1.0f / 16.0f, 1.0f);
bglTranslatef(pos[0], pos[1], pos[2]);
if (pr_frustumculling)
polymer_extractfrustum();
cliplanecount = 0;
if (updatesectors)
{
i = 0;
while (i < numsectors)
{
polymer_updatesector(i);
i++;
}
i = 0;
while (i < numwalls)
{
polymer_updatewall(i);
i++;
}
updatesectors = 0;
}
i = 0;
while (i < numsectors)
{
if (prsectors[i])
{
if (i == dacursectnum)
prsectors[i]->drawingstate = 2;
else
prsectors[i]->drawingstate = 0;
}
prsectors[i]->drawingstate = 0;
i++;
}
prsectors[dacursectnum]->drawingstate = 2; // SEED OF LIFE
drawnsectors = 1;
while (drawnsectors > 0)
{
@ -182,11 +198,20 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho
j = 0;
while (j < sec->wallnum)
{
if (wallincliplane(sec->wallptr + j, &cliplane))
if (((pr_frustumculling == 0) || polymer_portalinfrustum(sec->wallptr + j)) &&
((pr_cliplanes == 0) || polymer_wallincliplanes(sec->wallptr + j)))
{
polymer_drawwall(sec->wallptr + j);
if ((wal->nextsector != -1) && (prsectors[wal->nextsector]->drawingstate == 0))
if ((wal->nextsector != -1) && (prsectors[wal->nextsector]) && (prsectors[wal->nextsector]->drawingstate == 0))
prsectors[wal->nextsector]->drawingstate = 1;
if (wal->nextsector == -1 && pr_cliplanes)
{ // add a 2D cliplane for map limits
polymer_addcliplane(equation(wal->x, wal->y, wall[wal->point2].x, wall[wal->point2].y),
equation(daposx, daposy, wal->x, wal->y),
equation(daposx, daposy, wall[wal->point2].x, wall[wal->point2].y),
(daposx + wal->x + wall[wal->point2].x) / 3,
(daposy + wal->y + wall[wal->point2].y) / 3);
}
}
j++;
@ -223,7 +248,7 @@ void polymer_drawsprite(long snum)
{
}
// SECTOR MANAGEMENT
// SECTORS
int polymer_initsector(short sectnum)
{
sectortype *sec;
@ -240,8 +265,6 @@ int polymer_initsector(short sectnum)
return (0);
}
s->invalidate = 0;
s->verts = calloc(sec->wallnum, sizeof(GLdouble) * 3);
s->floorbuffer = calloc(sec->wallnum, sizeof(GLfloat) * 5);
s->ceilbuffer = calloc(sec->wallnum, sizeof(GLfloat) * 5);
@ -253,14 +276,9 @@ int polymer_initsector(short sectnum)
s->floorindices = s->ceilindices = NULL;
prsectors[sectnum] = s;
s->controlstate = s->drawingstate = 0;
/*i = sec->wallptr;
while (i < (sec->wallptr + sec->wallnum))
{
polymer_initwall(i);
i++;
}*/
prsectors[sectnum] = s;
if (pr_verbosity >= 2) OSD_Printf("PR : Initalized sector %i.\n", sectnum);
@ -295,6 +313,8 @@ int polymer_updatesector(short sectnum)
return (-1);
}
s->controlstate = 0;
if ((sec->floorstat & 64) || (sec->ceilingstat & 64))
{
ang = (getangle(wall[wal->point2].x - wal->x, wall[wal->point2].y - wal->y) + 512) & 2047;
@ -306,8 +326,16 @@ int polymer_updatesector(short sectnum)
i = 0;
while (i < sec->wallnum)
{
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;
if ((-wal->x != s->verts[(i*3)+2]) || 0)
{
s->verts[(i*3)+2] = s->floorbuffer[(i*5)+2] = s->ceilbuffer[(i*5)+2] = -wal->x;
s->controlstate |= 2;
}
if ((wal->y != s->verts[i*3]) || 0)
{
s->verts[i*3] = s->floorbuffer[i*5] = s->ceilbuffer[i*5] = wal->y;
s->controlstate |= 2;
}
getzsofslope(sectnum, wal->x, wal->y, &ceilz, &florz);
s->verts[(i*3)+1] = 0;
s->floorbuffer[(i*5)+1] = -florz;
@ -387,6 +415,12 @@ int polymer_updatesector(short sectnum)
wal = &wall[sec->wallptr + i];
}
if (s->controlstate & 2)
{
polymer_buildfloor(sectnum);
s->controlstate ^= 2;
}
if (pr_verbosity >= 3) OSD_Printf("PR : Updated sector %i.\n", sectnum);
return (0);
@ -513,20 +547,6 @@ void polymer_drawsector(short sectnum)
{
polymer_initsector(sectnum);
polymer_updatesector(sectnum);
polymer_buildfloor(sectnum);
}
else if (prsectors[sectnum]->invalidate || 1)
{
if (pr_verbosity >= 2) OSD_Printf("PR : Sector %i invalidated. Tesselating...\n", sectnum);
polymer_updatesector(sectnum);
i = 0;
while (i < sec->wallnum)
{
polymer_updatewall(sec->wallptr + i);
i++;
}
polymer_buildfloor(sectnum);
prsectors[sectnum]->invalidate = 0;
}
// floor
@ -552,7 +572,7 @@ void polymer_drawsector(short sectnum)
if (pr_verbosity >= 3) OSD_Printf("PR : Finished drawing sector %i...\n", sectnum);
}
// WALL MANAGEMENT
// WALLS
int polymer_initwall(short wallnum)
{
_prwall *w;
@ -567,7 +587,7 @@ int polymer_initwall(short wallnum)
}
w->invalidate = w->underover = 0;
w->wallbuffer = w->overbuffer = NULL;
w->wallbuffer = w->overbuffer = w->portal = NULL;
prwalls[wallnum] = w;
@ -752,6 +772,14 @@ void polymer_updatewall(short wallnum)
}
}
if (w->portal == NULL)
w->portal = calloc(4, sizeof(GLfloat) * 3);
memcpy(w->portal, &s->floorbuffer[(wallnum - sec->wallptr) * 5], sizeof(GLfloat) * 3);
memcpy(&w->portal[3], &s->floorbuffer[(wal->point2 - sec->wallptr) * 5], sizeof(GLfloat) * 3);
memcpy(&w->portal[6], &s->ceilbuffer[(wal->point2 - sec->wallptr) * 5], sizeof(GLfloat) * 3);
memcpy(&w->portal[9], &s->ceilbuffer[(wallnum - sec->wallptr) * 5], sizeof(GLfloat) * 3);
if (pr_verbosity >= 3) OSD_Printf("PR : Updated wall %i.\n", wallnum);
}
@ -784,10 +812,79 @@ void polymer_drawwall(short wallnum)
}
// HSR
int wallincliplane(short wallnum, _cliplane* cliplane)
void polymer_extractfrustum(void)
{
GLfloat matrix[16];
int i;
bglMatrixMode(GL_TEXTURE);
bglGetFloatv(GL_PROJECTION_MATRIX, matrix);
bglLoadMatrixf(matrix);
bglGetFloatv(GL_MODELVIEW_MATRIX, matrix);
bglMultMatrixf(matrix);
bglGetFloatv(GL_TEXTURE_MATRIX, matrix);
bglLoadIdentity();
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
i++;
}
}
int polymer_portalinfrustum(short wallnum)
{
int i, j, k;
float sqdist;
_prwall *w;
w = prwalls[wallnum];
i = 0;
while (i < 4)
{
j = k = 0;
while (j < 4)
{
sqdist = frustum[(i * 4) + 0] * w->portal[(j * 3) + 0] +
frustum[(i * 4) + 1] * w->portal[(j * 3) + 1] +
frustum[(i * 4) + 2] * w->portal[(j * 3) + 2] +
frustum[(i * 4) + 3];
if (sqdist < 0)
k++;
j++;
}
if (k == 4)
return (0); // OUT !
i++;
}
return (1);
}
void polymer_addcliplane(_equation clip, _equation left, _equation right, long refx, long refy)
{
if (cliplanecount == maxcliplanecount)
cliplanes = realloc(cliplanes, sizeof(_cliplane) * ++maxcliplanecount);
cliplanes[cliplanecount].clip = clip;
cliplanes[cliplanecount].left = left;
cliplanes[cliplanecount].right = right;
cliplanes[cliplanecount].ref.x = refx;
cliplanes[cliplanecount].ref.y = refy;
cliplanecount++;
}
int polymer_wallincliplanes(short wallnum)
{
walltype *wal;
_point2d p1, p2;
int i, j;
wal = &wall[wallnum];
@ -797,14 +894,25 @@ int wallincliplane(short wallnum, _cliplane* cliplane)
p2.x = wall[wal->point2].x;
p2.y = wall[wal->point2].y;
if ((sameside(&cliplane->clip, &cliplane->ref, &p1) != cliplane->clipsign) && (sameside(&cliplane->clip, &cliplane->ref, &p2) != cliplane->clipsign))
return (0);
i = 0;
while (i < cliplanecount)
{
j = 0;
/*if ((sameside(&cliplane->left, &cliplane->ref, &p1) == 0) && (sameside(&cliplane->left, &cliplane->ref, &p2) == 0))
return (0);
if ((sameside(&cliplanes[i].clip, &cliplanes[i].ref, &p1) == 0) && (sameside(&cliplanes[i].clip, &cliplanes[i].ref, &p2) == 0))
j++;
if ((sameside(&cliplane->right, &cliplane->ref, &p1) == 0) && (sameside(&cliplane->right, &cliplane->ref, &p2) == 0))
return (0);*/
if ((sameside(&cliplanes[i].left, &cliplanes[i].ref, &p1) == 1) && (sameside(&cliplanes[i].left, &cliplanes[i].ref, &p2) == 1))
j++;
if ((sameside(&cliplanes[i].right, &cliplanes[i].ref, &p1) == 1) && (sameside(&cliplanes[i].right, &cliplanes[i].ref, &p2) == 1))
j++;
if (j == 3)
return (0);
i++;
}
return (1);
}

View file

@ -30,6 +30,9 @@ extern "C" {
#include "compat.h"
#include "a.h"
#include "build.h"
#if defined(POLYMOST) && defined(USE_OPENGL)
# include "polymer.h"
#endif
#include "cache1d.h"
#include "pragmas.h"
#include "mmulti.h"

View file

@ -10562,6 +10562,10 @@ char domovethings(void)
movecyclers();
pan3dsound();
}
//polymer invalidate
updatesectors = 1;
return 0;
}

View file

@ -23,9 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "baselayer.h"
#include "duke3d.h"
#include "crc32.h"
#if defined(POLYMOST) && defined(USE_OPENGL)
# include "polymer.h"
#endif
#include <ctype.h>
struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat;
@ -472,9 +469,11 @@ struct cvarmappings {
{ "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_fov", "pr_fov: sets the field of vision in build angle", (void*)&pr_fov, CVAR_UNSIGNEDINT, 0, 0, 1024},
{ "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_fov", "pr_fov: sets the field of vision in build angle", (void*)&pr_fov, CVAR_INT, 0, 0, 1023},
{ "pr_frustumculling", "pr_frustumculling: toggles frustum culling (recommended)", (void*)&pr_frustumculling, CVAR_INT, 0, 0, 1 },
{ "pr_verbosity", "pr_verbosity: verbosity level of the polymer renderer", (void*)&pr_verbosity, CVAR_INT, 0, 0, 3 },
{ "pr_wireframe", "pr_wireframe: toggles wireframe mode", (void*)&pr_wireframe, CVAR_BOOL, 0, 0, 1 },
{ "pr_wireframe", "pr_wireframe: toggles wireframe mode", (void*)&pr_wireframe, CVAR_INT, 0, 0, 1 },
#endif
{ "r_precache", "r_precache: enable/disable the pre-level caching routine", (void*)&useprecache, CVAR_BOOL, 0, 0, 1 }
};