diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index d06076bf6..328d4844e 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1081,6 +1081,7 @@ set (PCH_SOURCES core/rendering/scene/hw_drawinfo.cpp core/rendering/scene/hw_bunchdrawer.cpp core/rendering/scene/hw_portal.cpp + core/rendering/scene/hw_skyportal.cpp core/console/c_notifybuffer.cpp core/console/d_event.cpp diff --git a/source/core/rendering/scene/hw_drawstructs.h b/source/core/rendering/scene/hw_drawstructs.h index f40ddbd81..ea6bd3d2d 100644 --- a/source/core/rendering/scene/hw_drawstructs.h +++ b/source/core/rendering/scene/hw_drawstructs.h @@ -9,6 +9,7 @@ #include "fcolormap.h" #include "build.h" #include "gamefuncs.h" +#include "render.h" #ifdef _MSC_VER #pragma warning(disable:4244) @@ -80,6 +81,7 @@ enum PortalTypes PORTALTYPE_PLANEMIRROR, PORTALTYPE_MIRROR, PORTALTYPE_LINETOLINE, + PORTALTYPE_LINETOSPRITE, }; //========================================================================== @@ -164,18 +166,16 @@ public: int dynlightindex; - /* union { // it's either one of them but never more! - FSectorPortal *secportal; // sector portal (formerly skybox) + //FSectorPortal *secportal; // sector portal (formerly skybox) HWSkyInfo * sky; // for normal sky - HWHorizonInfo * horizon; // for horizon information - FSectorPortalGroup * portal; // stacked sector portals - secplane_t * planemirror; // for plane mirrors - walltype *lineportal; // line-to-line portals + //HWHorizonInfo * horizon; // for horizon information + PortalDesc * portal; // stacked sector portals + //secplane_t * planemirror; // for plane mirrors + spritetype* teleport; // SW's teleport-views }; - */ @@ -198,6 +198,7 @@ public: void SetupLights(HWDrawInfo *di, FDynLightData &lightdata); void MakeVertices(HWDrawInfo *di, bool nosplit); + void SetLightAndFog(FRenderState& state); void SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowmirror); void SkyLine(HWDrawInfo *di, sectortype *sec, walltype *line); diff --git a/source/core/rendering/scene/hw_skyportal.cpp b/source/core/rendering/scene/hw_skyportal.cpp new file mode 100644 index 000000000..b70571c66 --- /dev/null +++ b/source/core/rendering/scene/hw_skyportal.cpp @@ -0,0 +1,95 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2003-2016 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// + +#include "filesystem.h" +#include "hw_skydome.h" +#include "hw_portal.h" +#include "hw_renderstate.h" +#include "skyboxtexture.h" + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- +void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) +{ + bool drawBoth = false; + auto &vp = di->Viewpoint; + + if (di->isSoftwareLighting()) + { + //di->SetFallbackLightMode(); + state.SetNoSoftLightLevel(); + } + + + state.ResetColor(); + state.EnableFog(false); + state.AlphaFunc(Alpha_GEqual, 0.f); + state.SetRenderStyle(STYLE_Translucent); + bool oldClamp = state.SetDepthClamp(true); + + di->SetupView(state, 0, 0, 0, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1)); + + state.SetVertexBuffer(vertexBuffer); + auto skybox = origin->texture[0] ? dynamic_cast(origin->texture[0]->GetTexture()) : nullptr; + if (skybox) + { + vertexBuffer->RenderBox(state, origin->skytexno1, skybox, origin->x_offset[0], origin->sky2, /*di->Level->info->pixelstretch*/1, { 0, 0, 1 }, { 0, 0, 1 }); + } + else + { + if (origin->texture[0]==origin->texture[1] && origin->doublesky) origin->doublesky=false; + + if (origin->texture[0]) + { + state.SetTextureMode(TM_OPAQUE); + vertexBuffer->RenderDome(state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER, false); + state.SetTextureMode(TM_NORMAL); + } + + state.AlphaFunc(Alpha_Greater, 0.f); + + if (origin->doublesky && origin->texture[1]) + { + vertexBuffer->RenderDome(state, origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER, false); + } + + int skyfog = 0; + if (skyfog>0 && /*!di->isFullbrightScene() &&*/ (origin->fadecolor & 0xffffff) != 0) + { + PalEntry FadeColor = origin->fadecolor; + FadeColor.a = clamp(skyfog, 0, 255); + + state.EnableTexture(false); + state.SetObjectColor(FadeColor); + state.Draw(DT_Triangles, 0, 12); + state.EnableTexture(true); + state.SetObjectColor(0xffffffff); + } + } + //di->lightmode = oldlightmode; + state.SetDepthClamp(oldClamp); +} + +const char *HWSkyPortal::GetName() { return "Sky"; } diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index 7d515b03b..2cb5e7dfb 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -27,7 +27,7 @@ #include "hw_clock.h" //#include "hw_lighting.h" #include "hw_drawinfo.h" -//#include "hwrenderer/scene/hw_portal.h" +#include "hw_portal.h" #include "hw_lightbuffer.h" #include "hw_renderstate.h" #include "hw_skydome.h" @@ -101,12 +101,10 @@ void HWWall::RenderWall(HWDrawInfo *di, FRenderState &state, int textured) void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state) { -#if 0 - if (gl_fogmode && !di->isFullbrightScene()) + if (gl_fogmode)// && !di->isFullbrightScene()) { - int rel = rellight + getExtraLight(); state.EnableDrawBufferAttachments(false); - di->SetFog(state, lightlevel, rel, false, &Colormap, false); + SetLightAndFog(state); state.SetEffect(EFF_FOGBOUNDARY); state.AlphaFunc(Alpha_GEqual, 0.f); state.SetDepthBias(-1, -128); @@ -115,53 +113,6 @@ void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state) state.SetEffect(EFF_NONE); state.EnableDrawBufferAttachments(true); } -#endif -} - - -//========================================================================== -// -// -// -//========================================================================== -void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state) -{ -#if 0 - if (!TexMan.mirrorTexture.isValid()) return; - - state.SetDepthFunc(DF_LEqual); - - // we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is. - state.EnableTextureMatrix(true); - - // Use sphere mapping for this - state.SetEffect(EFF_SPHEREMAP); - di->SetColor(state, lightlevel, 0, di->isFullbrightScene(), Colormap, 0.1f); - di->SetFog(state, lightlevel, 0, di->isFullbrightScene(), &Colormap, true); - state.SetRenderStyle(STYLE_Add); - state.AlphaFunc(Alpha_Greater, 0); - - auto tex = TexMan.GetGameTexture(TexMan.mirrorTexture, false); - state.SetMaterial(tex, UF_None, 0, CLAMP_NONE, 0, -1); // do not upscale the mirror texture. - - flags &= ~HWWall::HWF_GLOW; - RenderWall(di, state, HWWall::RWF_BLANK); - - state.EnableTextureMatrix(false); - state.SetEffect(EFF_NONE); - state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold); - - state.SetDepthFunc(DF_Less); - - // This is drawn in the translucent pass which is done after the decal pass - // As a result the decals have to be drawn here, right after the wall they are on, - // because the depth buffer won't get set by translucent items. - if (seg->sidedef->AttachedDecals) - { - DrawDecalsForMirror(di, state, di->Decals[1]); - } - state.SetRenderStyle(STYLE_Translucent); -#endif } //========================================================================== @@ -170,14 +121,8 @@ void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state) // //========================================================================== -void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) +void HWWall::SetLightAndFog(FRenderState& state) { - //int tmode = state.GetTextureMode(); - - state.SetMaterial(texture, UF_Texture, 0, 0/*flags & 3*/, TRANSLATION(Translation_Remap + curbasepal, palette), -1); - - float absalpha = fabsf(alpha); - // Fog must be done before the texture so that the texture selector can override it. bool foggy = (GlobalMapFog || (fade & 0xffffff)); auto ShadeDiv = lookups.tables[palette].ShadeFactor; @@ -200,6 +145,54 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) // The shade rgb from the tint is ignored here. state.SetColor(PalEntry(255, globalr, globalg, globalb)); +} + +//========================================================================== +// +// +// +//========================================================================== +void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state) +{ + if (!TexMan.mirrorTexture.isValid()) return; + + state.SetDepthFunc(DF_LEqual); + + // we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is. + state.EnableTextureMatrix(true); + + // Use sphere mapping for this + state.SetEffect(EFF_SPHEREMAP); + SetLightAndFog(state); + state.SetRenderStyle(STYLE_Add); + state.AlphaFunc(Alpha_Greater, 0); + + auto tex = TexMan.GetGameTexture(TexMan.mirrorTexture, false); + state.SetMaterial(tex, UF_None, 0, CLAMP_NONE, 0, -1); // do not upscale the mirror texture. + + RenderWall(di, state, HWWall::RWF_BLANK); + + state.EnableTextureMatrix(false); + state.SetEffect(EFF_NONE); + state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold); + + state.SetDepthFunc(DF_Less); + state.SetRenderStyle(STYLE_Translucent); +} + +//========================================================================== +// +// +// +//========================================================================== + +void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) +{ + //int tmode = state.GetTextureMode(); + + state.SetMaterial(texture, UF_Texture, 0, 0/*flags & 3*/, TRANSLATION(Translation_Remap + curbasepal, palette), -1); + + SetLightAndFog(state); int h = texture->GetTexelHeight(); int h2 = 1 << sizeToBits(h); @@ -236,13 +229,11 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state) { -#if 0 state.SetRenderStyle(RenderStyle); if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); else state.AlphaFunc(Alpha_GEqual, 0.f); RenderTexturedWall(di, state, HWWall::RWF_TEXTURED); state.SetRenderStyle(STYLE_Translucent); -#endif } //========================================================================== @@ -444,12 +435,12 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent) void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) { -#if 0 HWPortal * portal = nullptr; MakeVertices(di, false); switch (ptype) { +#if 0 // portals don't go into the draw list. // Instead they are added to the portal manager case PORTALTYPE_HORIZON: @@ -477,6 +468,7 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) } portal->AddLine(this); break; +#endif case PORTALTYPE_SECTORSTACK: portal = di->FindPortal(this->portal); @@ -488,6 +480,7 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) portal->AddLine(this); break; +#if 0 case PORTALTYPE_PLANEMIRROR: if (portalState.PlaneMirrorMode * planemirror->fC() <= 0) { @@ -501,14 +494,11 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) portal->AddLine(this); } break; - +#endif case PORTALTYPE_MIRROR: - portal = di->FindPortal(seg->linedef); - if (!portal) - { - portal = new HWMirrorPortal(&portalState, seg->linedef); - di->Portals.Push(portal); - } + // These are unique. No need to look existing ones up. + portal = new HWMirrorPortal(&portalState, seg); + di->Portals.Push(portal); portal->AddLine(this); if (gl_mirror_envmap) { @@ -518,19 +508,9 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) break; case PORTALTYPE_LINETOLINE: - if (!lineportal) - return; - portal = di->FindPortal(lineportal); - if (!portal) - { - line_t *otherside = lineportal->lines[0]->mDestination; - if (otherside != nullptr && otherside->portalindex < di->Level->linePortals.Size()) - { - di->ProcessActorsInPortal(otherside->getPortal()->mGroup, di->in_area); - } - portal = new HWLineToLinePortal(&portalState, lineportal); - di->Portals.Push(portal); - } + // These are also unique. + portal = new HWLineToLinePortal(&portalState, seg, &wall[seg->portalnum]); + di->Portals.Push(portal); portal->AddLine(this); break; @@ -551,7 +531,6 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) { portal->planesused |= (1<linedef->isVisualPortal() && wal->sidedef == wal->linedef->sidedef[0]; + if (seg->portalflags) + { + int ptype = -1; + if (seg->portalflags == PORTAL_WALL_MIRROR) ptype = PORTALTYPE_MIRROR; + else if (seg->portalflags == PORTAL_WALL_VIEW) ptype = PORTALTYPE_LINETOLINE; + else if (seg->portalflags == PORTAL_WALL_TO_SPRITE) ptype = PORTALTYPE_LINETOSPRITE; + if (ptype != -1) + { + ztop[0] = zceil[0]; + ztop[1] = zceil[1]; + zbottom[0] = zfloor[0]; + zbottom[1] = zfloor[1]; + PutPortal(di, ptype, -1); + return; + } + } + + if (!backsector || !backwall) { // sector's sky SkyNormal(di, frontsector, v1, v2); - /* - if (isportal) - { - lineportal = wal->linedef->getPortal()->mGroup; - ztop[0] = zceil[0]; - ztop[1] = zceil[1]; - zbottom[0] = zfloor[0]; - zbottom[1] = zfloor[1]; - PutPortal(di, PORTALTYPE_LINETOLINE, -1); - } - else - */ - { - // normal texture + // normal texture - int tilenum = (wal->cstat & CSTAT_WALL_1WAY) ? wal->overpicnum : wal->picnum; - setgotpic(tilenum); - tileUpdatePicnum(&tilenum, int(wal-wall) + 16384, wal->cstat); - texture = tileGetTexture(tilenum); - if (texture && texture->isValid()) - { - DoOneSidedTexture(di, wal, frontsector, backsector, fch1, fch2, ffh1, ffh2); - } + int tilenum = (wal->cstat & CSTAT_WALL_1WAY) ? wal->overpicnum : wal->picnum; + setgotpic(tilenum); + tileUpdatePicnum(&tilenum, int(wal-wall) + 16384, wal->cstat); + texture = tileGetTexture(tilenum); + if (texture && texture->isValid()) + { + DoOneSidedTexture(di, wal, frontsector, backsector, fch1, fch2, ffh1, ffh2); } } else // two sided @@ -1032,18 +1015,6 @@ void HWWall::Process(HWDrawInfo *di, walltype *wal, sectortype* frontsector, sec } } - /* - if (isportal) - { - lineportal = wal->linedef->getPortal()->mGroup; - ztop[0] = bch1; - ztop[1] = bch2; - zbottom[0] = bfh1; - zbottom[1] = bfh2; - PutPortal(di, PORTALTYPE_LINETOLINE, -1); - } - else*/ - if (wal->cstat & (CSTAT_WALL_MASKED | CSTAT_WALL_1WAY)) { int tilenum = wal->overpicnum; diff --git a/wadsrc/static/glstuff/mirror.png b/wadsrc/static/glstuff/mirror.png new file mode 100644 index 000000000..08a6abcbe Binary files /dev/null and b/wadsrc/static/glstuff/mirror.png differ