Use stencil buffer in Polymost to restrict mirrors to only render within the region of the screen occupied by the mirror wall.

Additionally, raise minimum number of stencil buffer bits to accomodate future use of the stencil buffer.

git-svn-id: https://svn.eduke32.com/eduke32@7736 1a8010ca-5511-0410-912e-c29ae57300e0

# Conflicts:
#	source/build/include/build.h
#	source/build/src/polymer.cpp
#	source/build/src/polymost.cpp
#	source/kenbuild/src/game.cpp
This commit is contained in:
pogokeen 2019-06-25 18:35:16 +00:00 committed by Christoph Oelckers
parent 1426b3fb4f
commit 8cbdf3a0c4
10 changed files with 105 additions and 21 deletions

View file

@ -1104,8 +1104,8 @@ void plotlines2d(const int32_t *xx, const int32_t *yy, int32_t numpoints, int co
void plotpixel(int32_t x, int32_t y, char col);
void renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz);
void renderRestoreTarget(void);
void renderPrepareMirror(int32_t dax, int32_t day, fix16_t daang, int16_t dawall,
int32_t *tposx, int32_t *tposy, fix16_t *tang);
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, int16_t dawall,
int32_t *tposx, int32_t *tposy, fix16_t *tang);
void renderPrepareMirrorOld(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz,
int16_t dawall, int16_t dasector, int32_t *tposx, int32_t *tposy, fix16_t *tang);
void renderCompleteMirror(void);

View file

@ -49,6 +49,8 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
void polymost_fillpolygon(int32_t npoints);
void polymost_initosdfuncs(void);
void polymost_drawrooms(void);
void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, int16_t mirrorWall);
void polymost_completeMirror();
int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall);
int32_t polymost_spriteHasTranslucency(uspritetype const * const tspr);

View file

@ -11697,7 +11697,7 @@ void squarerotatetile(int16_t tilenume)
//
// preparemirror
//
void renderPrepareMirror(int32_t dax, int32_t day, fix16_t daang, int16_t dawall,
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, int16_t dawall,
int32_t *tposx, int32_t *tposy, fix16_t *tang)
{
const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x-x;
@ -11714,6 +11714,11 @@ void renderPrepareMirror(int32_t dax, int32_t day, fix16_t daang, int16_t dawall
*tang = (fix16_from_int(getangle(dx, dy) << 1) - daang) & 0x7FFFFFF;
inpreparemirror = 1;
#ifdef USE_OPENGL
if (videoGetRenderMode() != REND_CLASSIC)
polymost_prepareMirror(dax, day, daz, daang, dahoriz, dawall);
#endif
}
static int32_t mirthoriz, mirbakdaz;
@ -11762,6 +11767,11 @@ void renderPrepareMirrorOld(int32_t dax, int32_t day, int32_t daz, fix16_t daang
//
void renderCompleteMirror(void)
{
#ifdef USE_OPENGL
if (videoGetRenderMode() != REND_CLASSIC)
polymost_completeMirror();
#endif
// Don't try to complete a mirror if we haven't drawn the reflection for one
if (!inpreparemirror) { return; }
inpreparemirror = 0;

View file

@ -5659,12 +5659,11 @@ void polymost_drawrooms()
videoEndDrawing();
}
void polymost_drawmaskwall(int32_t damaskwallcnt)
static void polymost_drawmaskwallinternal(int32_t wallIndex)
{
int const z = maskwall[damaskwallcnt];
auto const wal = (uwalltype *)&wall[thewall[z]];
auto const wal2 = (uwalltype *)&wall[wal->point2];
int32_t const sectnum = thesector[z];
auto const wal = (uwallptr_t)&wall[wallIndex];
auto const wal2 = (uwallptr_t)&wall[wal->point2];
int32_t const sectnum = wall[wal->nextwall].nextsector;
auto const sec = (usectortype *)&sector[sectnum];
// if (wal->nextsector < 0) return;
@ -5673,14 +5672,14 @@ void polymost_drawmaskwall(int32_t damaskwallcnt)
auto const nsec = (usectortype *)&sector[wal->nextsector];
polymost_outputGLDebugMessage(3, "polymost_drawmaskwall(damaskwallcnt:%d)", damaskwallcnt);
polymost_outputGLDebugMessage(3, "polymost_drawmaskwallinternal(wallIndex:%d)", wallIndex);
globalpicnum = wal->overpicnum;
if ((uint32_t)globalpicnum >= MAXTILES)
globalpicnum = 0;
globalorientation = (int32_t)wal->cstat;
tileUpdatePicnum(&globalpicnum, (int16_t)thewall[z]+16384);
tileUpdatePicnum(&globalpicnum, (int16_t)wallIndex+16384);
globvis = globalvisibility;
globvis = (sector[sectnum].visibility != 0) ? mulscale4(globvis, (uint8_t)(sector[sectnum].visibility + 16)) : globalvisibility;
@ -5772,7 +5771,7 @@ void polymost_drawmaskwall(int32_t damaskwallcnt)
#ifdef NEW_MAP_FORMAT
uint8_t const blend = wal->blend;
#else
uint8_t const blend = wallext[thewall[z]].blend;
uint8_t const blend = wallext[wallIndex].blend;
#endif
handle_blend(!!(wal->cstat & 128), blend, !!(wal->cstat & 512));
@ -5871,6 +5870,79 @@ void polymost_drawmaskwall(int32_t damaskwallcnt)
polymost_identityrotmat();
}
void polymost_drawmaskwall(int32_t damaskwallcnt)
{
int const z = maskwall[damaskwallcnt];
polymost_drawmaskwallinternal(thewall[z]);
}
void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, int16_t mirrorWall)
{
polymost_outputGLDebugMessage(3, "polymost_prepareMirror(%u)", mirrorWall);
//POGO: prepare necessary globals for drawing, as we intend to call this outside of drawrooms
set_globalpos(dax, day, daz);
set_globalang(daang);
globalhoriz = mulscale16(fix16_to_int(dahoriz)-100,divscale16(xdimenscale,viewingrange))+(ydimen>>1);
qglobalhoriz = mulscale16(dahoriz-F16(100), divscale16(xdimenscale, viewingrange))+fix16_from_int(ydimen>>1);
gyxscale = ((float)xdimenscale)*(1.0f/131072.f);
gxyaspect = ((double)xyaspect*fviewingrange)*(5.0/(65536.0*262144.0));
gviewxrange = fviewingrange * fxdimen * (1.f/(32768.f*1024.f));
gcosang = fcosglobalang*(1.0f/262144.f);
gsinang = fsinglobalang*(1.0f/262144.f);
gcosang2 = gcosang * (fviewingrange * (1.0f/65536.f));
gsinang2 = gsinang * (fviewingrange * (1.0f/65536.f));
ghalfx = (float)(xdimen>>1);
ghalfy = (float)(ydimen>>1);
grhalfxdown10 = 1.f/(ghalfx*1024.f);
ghoriz = fix16_to_float(qglobalhoriz);
gvisibility = ((float)globalvisibility)*FOGSCALE;
resizeglcheck();
if (r_yshearing)
{
gshang = 0.f;
gchang = 1.f;
ghoriz2 = (float)(ydimen >> 1) - ghoriz;
}
else
{
float r = (float)(ydimen >> 1) - ghoriz;
gshang = r / Bsqrtf(r * r + ghalfx * ghalfx);
gchang = Bsqrtf(1.f - gshang * gshang);
ghoriz2 = 0.f;
}
ghoriz = (float)(ydimen>>1);
gctang = cosf(gtang);
gstang = sinf(gtang);
if (Bfabsf(gstang) < .001f)
{
gstang = 0.f;
gctang = (gctang > 0.f) ? 1.f : -1.f;
}
grhalfxdown10x = grhalfxdown10;
//POGO: write the mirror region to the stencil buffer to allow showing mirrors & skyboxes at the same time
glEnable(GL_STENCIL_TEST);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
polymost_drawmaskwallinternal(mirrorWall);
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
//POGO: render only to the mirror region
glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
}
void polymost_completeMirror()
{
polymost_outputGLDebugMessage(3, "polymost_completeMirror()");
glDisable(GL_STENCIL_TEST);
}
typedef struct
{
uint32_t wrev;

View file

@ -1545,7 +1545,7 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs)
{ SDL_GL_MULTISAMPLEBUFFERS, glmultisample > 0 },
{ SDL_GL_MULTISAMPLESAMPLES, glmultisample },
#endif
{ SDL_GL_STENCIL_SIZE, 1 },
{ SDL_GL_STENCIL_SIZE, 8 },
{ SDL_GL_ACCELERATED_VISUAL, 1 },
};

View file

@ -364,7 +364,7 @@ int32_t videoSetMode(int32_t x, int32_t y, int32_t c, int32_t fs)
{ SDL_GL_DOUBLEBUFFER, 1 },
{ SDL_GL_MULTISAMPLEBUFFERS, glmultisample > 0 },
{ SDL_GL_MULTISAMPLESAMPLES, glmultisample },
{ SDL_GL_STENCIL_SIZE, 1 },
{ SDL_GL_STENCIL_SIZE, 8 },
{ SDL_GL_ACCELERATED_VISUAL, 1 },
{ SDL_GL_SWAP_CONTROL, vsync_renderlayer },
};

View file

@ -2623,8 +2623,8 @@ static int32_t SetupOpenGL(int32_t width, int32_t height, int32_t bitspp)
0, //Shift Bit Ignored
0, //No Accumulation Buffer
0,0,0,0, //Accumulation Bits Ignored
32, //16/24/32 Z-Buffer depth
1, //No Stencil Buffer
24, //16/24/32 Z-Buffer depth
8, //8-bit Stencil Buffer
0, //No Auxiliary Buffer
PFD_MAIN_PLANE, //Main Drawing Layer
0, //Reserved

View file

@ -628,7 +628,7 @@ void G_HandleMirror(int32_t x, int32_t y, int32_t z, fix16_t a, fix16_t q16horiz
fix16_t tang;
//prepare to render any scripted EVENT_DISPLAYROOMS extras as mirrored
renderPrepareMirror(x, y, a, g_mirrorWall[i], &tposx, &tposy, &tang);
renderPrepareMirror(x, y, z, a, q16horiz, g_mirrorWall[i], &tposx, &tposy, &tang);
int32_t j = g_visibility;
g_visibility = (j>>1) + (j>>2);
@ -660,7 +660,7 @@ void G_HandleMirror(int32_t x, int32_t y, int32_t z, fix16_t a, fix16_t q16horiz
VM_OnEvent(EVENT_RESETGOTPICS, -1, -1);
//prepare to render the mirror
renderPrepareMirror(x, y, a, g_mirrorWall[i], &tposx, &tposy, &tang);
renderPrepareMirror(x, y, z, a, q16horiz, g_mirrorWall[i], &tposx, &tposy, &tang);
if (videoGetRenderMode() != REND_POLYMER)
{

View file

@ -4019,9 +4019,9 @@ void drawscreen(short snum, int dasmoothratio)
//Prepare drawrooms for drawing mirror and calculate reflected
//position into tposx, tposy, and tang (tpos.z == cpos.z)
//Must call preparemirror before drawrooms and
// completemirror after drawrooms
preparemirror(cpos.x,cpos.y,/*cpos.z,*/ cang, /*choriz,*/
//Must call renderPrepareMirror before drawrooms and
// renderCompleteMirror after drawrooms
renderPrepareMirror(cpos.x,cpos.y,cpos.z,fix16_from_int(cang),choriz,
mirrorwall[i],/*mirrorsector[i],*/ &tposx,&tposy,&tang);
ovisibility = g_visibility;

View file

@ -889,7 +889,7 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
// Must call preparemirror before drawrooms and
// completemirror after drawrooms
renderPrepareMirror(tx, ty, /*tz,*/ fix16_from_int(tpang), /*tphoriz,*/
renderPrepareMirror(tx, ty, tz, fix16_from_int(tpang), tphoriz,
mirror[cnt].mirrorwall, /*mirror[cnt].mirrorsector,*/ &tposx, &tposy, &tang);
drawrooms(tposx, tposy, tz, fix16_to_int(tang), tphoriz, mirror[cnt].mirrorsector + MAXSECTORS);