From a0a530945d3399cbfbf75fdc2f4b2dce4947f468 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers <coelckers@zdoom.fake> Date: Thu, 14 Apr 2016 13:22:15 +0200 Subject: [PATCH] - added new sector type 90 which designates a sector that is being used as a cubemapped skybox, in case someone wants to make one of those without using an actual sky for this. --- src/gl/scene/gl_flats.cpp | 90 ++++++++++++++++++++++++++++++++++++--- src/gl/scene/gl_sky.cpp | 10 +---- src/gl/scene/gl_wall.h | 6 +++ src/gl/scene/gl_walls.cpp | 36 ++++++++++++---- 4 files changed, 119 insertions(+), 23 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 6dd611cdd..2a5ef712e 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -178,8 +178,8 @@ void GLFlat::DrawSubsector(subsector_t * sub) { vertex_t *vt = sub->firstline[k].v1; ptr->x = vt->fX(); - ptr->y = vt->fY(); ptr->z = plane.plane.ZatPoint(vt) + dz; + ptr->y = vt->fY(); ptr->u = vt->fX() / 64.f; ptr->v = -vt->fY() / 64.f; ptr++; @@ -252,7 +252,7 @@ void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans) if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); DrawSubsector(sub); } - else + else { if (vboindex >= 0) { @@ -305,6 +305,76 @@ void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans) } +//========================================================================== +// +// special handling for skyboxes which need texture clamping. +// This will find the bounding rectangle of the sector and just +// draw one single polygon filling that rectangle with a clamped +// texture. +// +//========================================================================== + +void GLFlat::DrawSkyboxSector(int pass, bool processlights) +{ + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + + float minx = FLT_MAX, miny = FLT_MAX; + float maxx = -FLT_MAX, maxy = -FLT_MAX; + + for (int i = 0; i < sector->linecount; i++) + { + line_t *ln = sector->lines[i]; + float x = ln->v1->fX(); + float y = ln->v1->fY(); + if (x < minx) minx = x; + if (y < miny) miny = y; + if (x > maxx) maxx = x; + if (y > maxy) maxy = y; + x = ln->v2->fX(); + y = ln->v2->fY(); + if (x < minx) minx = x; + if (y < miny) miny = y; + if (x > maxx) maxx = x; + if (y > maxy) maxy = y; + } + + float z = plane.plane.ZatPoint(0., 0.) + dz; + + ptr->x = minx; + ptr->z = z; + ptr->y = miny; + ptr->u = 0; + ptr->v = 1; + ptr++; + + ptr->x = minx; + ptr->z = z; + ptr->y = maxy; + ptr->u = 0; + ptr->v = 0; + ptr++; + + ptr->x = maxx; + ptr->z = z; + ptr->y = maxy; + ptr->u = 1; + ptr->v = 0; + ptr++; + + ptr->x = maxx; + ptr->z = z; + ptr->y = miny; + ptr->u = 1; + ptr->v = 1; + ptr++; + + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + + flatvertices += 4; + flatprimitives++; +} + + //========================================================================== // // @@ -328,10 +398,18 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG case GLPASS_ALL: gl_SetColor(lightlevel, rel, Colormap,1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); - gl_SetPlaneTextureRotation(&plane, gltexture); - DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false); - gl_RenderState.EnableTextureMatrix(false); + if (sector->special != GLSector_Skybox) + { + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); + gl_SetPlaneTextureRotation(&plane, gltexture); + DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false); + gl_RenderState.EnableTextureMatrix(false); + } + else + { + gl_RenderState.SetMaterial(gltexture, CLAMP_XY, 0, -1, false); + DrawSkyboxSector(pass, (pass == GLPASS_ALL || dynlightindex > -1)); + } break; case GLPASS_LIGHTSONLY: diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index 2826236b2..6f6039c00 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -58,12 +58,6 @@ CVAR(Bool,gl_noskyboxes, false, 0) extern int skyfog; -enum -{ - NoSkyDraw = 89 -}; - - //========================================================================== // // Set up the skyinfo struct @@ -254,7 +248,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex { if (fs->GetTexture(sector_t::ceiling)==skyflatnum) { - if (bs->special == NoSkyDraw) return; + if (bs->special == GLSector_NoSkyDraw) return; if (bs->GetTexture(sector_t::ceiling)==skyflatnum) { // if the back sector is closed the sky must be drawn! @@ -344,7 +338,7 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver { if (fs->GetTexture(sector_t::floor)==skyflatnum) { - if (bs->special == NoSkyDraw) return; + if (bs->special == GLSector_NoSkyDraw) return; FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom)); // For lower skies the normal logic only applies to walls with no lower texture! diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 8bd39b372..890ba980d 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -23,6 +23,11 @@ struct FPortal; struct FFlatVertex; struct FGLLinePortal; +enum +{ + GLSector_NoSkyDraw = 89, + GLSector_Skybox = 90, +}; enum WallTypes { @@ -290,6 +295,7 @@ public: void SetupSubsectorLights(int pass, subsector_t * sub, int *dli = NULL); void DrawSubsector(subsector_t * sub); void DrawSubsectorLights(subsector_t * sub, int pass); + void DrawSkyboxSector(int pass, bool processlights); void DrawSubsectors(int pass, bool processlights, bool istrans); void ProcessLights(bool istrans); diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 5d13a0720..8f91b59cd 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -583,7 +583,23 @@ void GLWall::CheckTexturePosition() if ((uplft.v == 0.f && uprgt.v == 0.f && lolft.v <= 1.f && lorgt.v <= 1.f) || (uplft.v >= 0.f && uprgt.v >= 0.f && lolft.v == 1.f && lorgt.v == 1.f)) { - flags|=GLT_CLAMPY; + flags |= GLT_CLAMPY; + } + + // Check if this is marked as a skybox and if so, do the same for x. + // This intentionally only tests the seg's frontsector. + if (seg->frontsector->special == GLSector_Skybox) + { + sub = (float)xs_FloorToInt(uplft.u); + uplft.u -= sub; + uprgt.u -= sub; + lolft.u -= sub; + lorgt.u -= sub; + if ((uplft.u == 0.f && lolft.u == 0.f && uprgt.u <= 1.f && lorgt.u <= 1.f) || + (uplft.u >= 0.f && lolft.u >= 0.f && uprgt.u == 1.f && lorgt.u == 1.f)) + { + flags |= GLT_CLAMPX; + } } } @@ -604,6 +620,7 @@ void GLWall::DoTexture(int _type,seg_t * seg, int peg, GLSeg glsave=glseg; float flh=ceilingrefheight-floorrefheight; int texpos; + BYTE savedflags = flags; switch (_type) { @@ -636,16 +653,17 @@ void GLWall::DoTexture(int _type,seg_t * seg, int peg, } else { - CheckTexturePosition(); - // Add this wall to the render list - sector_t * sec = sub? sub->sector : seg->frontsector; + CheckTexturePosition(); + + // Add this wall to the render list + sector_t * sec = sub ? sub->sector : seg->frontsector; if (sec->e->XFloor.lightlist.Size()==0 || gl_fixedcolormap) PutWall(false); else SplitWall(sec, false); } - glseg=glsave; - flags&=~GLT_CLAMPY; + glseg = glsave; + flags = savedflags; } @@ -837,11 +855,11 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, } else { - flags&=~GLT_CLAMPX; + flags &= ~GLT_CLAMPX; } if (!wrap) { - flags|=GLT_CLAMPY; + flags |= GLT_CLAMPY; } } if (mirrory) @@ -1330,7 +1348,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) sector_t * segback; #ifdef _DEBUG - if (seg->linedef - lines == 904) + if (seg->linedef - lines < 4) { int a = 0; }