From 1146cf9e08b52517f9a344c299058b74bbcfaf13 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Apr 2020 23:50:57 +0200 Subject: [PATCH] - use FGameTexture instead of FMaterial for texture tracking in HWWall. The FMaterial object is only needed when finally binding the texture to the render state. --- src/common/textures/texture.cpp | 24 ++-- src/common/textures/textures.h | 7 ++ src/rendering/hwrenderer/scene/hw_decal.cpp | 2 +- .../hwrenderer/scene/hw_drawlist.cpp | 2 +- .../hwrenderer/scene/hw_drawlistadd.cpp | 2 +- .../hwrenderer/scene/hw_drawstructs.h | 2 +- src/rendering/hwrenderer/scene/hw_walls.cpp | 105 +++++++++--------- 7 files changed, 76 insertions(+), 68 deletions(-) diff --git a/src/common/textures/texture.cpp b/src/common/textures/texture.cpp index bd97b23505..a1a3c7056e 100644 --- a/src/common/textures/texture.cpp +++ b/src/common/textures/texture.cpp @@ -964,23 +964,23 @@ void FTexture::SetSpriteRect() topOffset += 1; // Reposition the sprite with the frame considered - spi.mSpriteRect.left = -leftOffset / fxScale; - spi.mSpriteRect.top = -topOffset / fyScale; - spi.mSpriteRect.width = spi.spriteWidth / fxScale; - spi.mSpriteRect.height = spi.spriteHeight / fyScale; + spi.mSpriteRect.left = -(float)leftOffset / fxScale; + spi.mSpriteRect.top = -(float)topOffset / fyScale; + spi.mSpriteRect.width = (float)spi.spriteWidth / fxScale; + spi.mSpriteRect.height = (float)spi.spriteHeight / fyScale; if (mTrimResult > 0) { - spi.mSpriteRect.left += spi.trim[0] / fxScale; - spi.mSpriteRect.top += spi.trim[1] / fyScale; + spi.mSpriteRect.left += (float)spi.trim[0] / fxScale; + spi.mSpriteRect.top += (float)spi.trim[1] / fyScale; - spi.mSpriteRect.width -= (oldwidth - spi.trim[2]) / fxScale; - spi.mSpriteRect.height -= (oldheight - spi.trim[3]) / fyScale; + spi.mSpriteRect.width -= float(oldwidth - spi.trim[2]) / fxScale; + spi.mSpriteRect.height -= float(oldheight - spi.trim[3]) / fyScale; - spi.mSpriteU[0] = spi.trim[0] / spi.spriteWidth; - spi.mSpriteV[0] = spi.trim[1] / spi.spriteHeight; - spi.mSpriteU[1] -= (oldwidth - spi.trim[0] - spi.trim[2]) / spi.spriteWidth; - spi.mSpriteV[1] -= (oldheight - spi.trim[1] - spi.trim[3]) / spi.spriteHeight; + spi.mSpriteU[0] = (float)spi.trim[0] / (float)spi.spriteWidth; + spi.mSpriteV[0] = (float)spi.trim[1] / (float)spi.spriteHeight; + spi.mSpriteU[1] -= float(oldwidth - spi.trim[0] - spi.trim[2]) / (float)spi.spriteWidth; + spi.mSpriteV[1] -= float(oldheight - spi.trim[1] - spi.trim[3]) / (float)spi.spriteHeight; } } } diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index 487d041d01..90de86eae0 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -643,6 +643,7 @@ public: bool isValid() { return wrapped.isValid(); } bool isWarped() { return wrapped.isWarped(); } + bool isMasked() { return wrapped.isMasked(); } bool isHardwareCanvas() const { return wrapped.isHardwareCanvas(); } // There's two here so that this can deal with software canvases in the hardware renderer later. bool isSoftwareCanvas() const { return wrapped.isCanvas(); } bool isMiscPatch() const { return wrapped.GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not. @@ -710,6 +711,12 @@ public: void SetSpriteRect() { wrapped.SetSpriteRect(); } const SpritePositioningInfo& GetSpritePositioning() { if (wrapped.mTrimResult == -1) wrapped.SetupSpriteData(); return wrapped.spi; } + int GetAreas(FloatRect** pAreas) const { return wrapped.GetAreas(pAreas); } + + bool GetTranslucency() + { + return wrapped.GetTranslucency(); + } }; diff --git a/src/rendering/hwrenderer/scene/hw_decal.cpp b/src/rendering/hwrenderer/scene/hw_decal.cpp index a505894aed..d112d5aeec 100644 --- a/src/rendering/hwrenderer/scene/hw_decal.cpp +++ b/src/rendering/hwrenderer/scene/hw_decal.cpp @@ -200,7 +200,7 @@ void HWWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &nor if (decal->RenderFlags & RF_INVISIBLE) return; - if (type == RENDERWALL_FFBLOCK && gltexture->isMasked()) return; // No decals on 3D floors with transparent textures. + if (type == RENDERWALL_FFBLOCK && texture->isMasked()) return; // No decals on 3D floors with transparent textures. if (seg == nullptr) return; diff --git a/src/rendering/hwrenderer/scene/hw_drawlist.cpp b/src/rendering/hwrenderer/scene/hw_drawlist.cpp index 37ff4006be..54f5db6a56 100644 --- a/src/rendering/hwrenderer/scene/hw_drawlist.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawlist.cpp @@ -722,7 +722,7 @@ void HWDrawList::SortWalls() HWWall * w1 = walls[a.index]; HWWall * w2 = walls[b.index]; - if (w1->gltexture != w2->gltexture) return w1->gltexture < w2->gltexture; + if (w1->texture != w2->texture) return w1->texture < w2->texture; return (w1->flags & 3) < (w2->flags & 3); }); diff --git a/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp b/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp index 851c2e1488..646f52279b 100644 --- a/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawlistadd.cpp @@ -44,7 +44,7 @@ void HWDrawInfo::AddWall(HWWall *wall) } else { - bool masked = HWWall::passflag[wall->type] == 1 ? false : (wall->gltexture && wall->gltexture->isMasked()); + bool masked = HWWall::passflag[wall->type] == 1 ? false : (wall->texture && wall->texture->isMasked()); int list; if ((wall->flags & HWWall::HWF_SKYHACK && wall->type == RENDERWALL_M2S)) diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 036811fa09..236d45332a 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -151,7 +151,7 @@ public: friend class HWPortal; vertex_t * vertexes[2]; // required for polygon splitting - FMaterial *gltexture; + FGameTexture *texture; TArray *lightlist; HWSeg glseg; diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index cab8ca6ef7..b96634c7bf 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -156,7 +156,8 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) state.SetGlowParams(topglowcolor, bottomglowcolor); state.SetGlowPlanes(frontsector->ceilingplane, frontsector->floorplane); } - state.SetMaterial(gltexture, flags & 3, 0, -1); + auto mat = FMaterial::ValidateTexture(texture->GetTexture(), false, true); + state.SetMaterial(mat, flags & 3, 0, -1); if (type == RENDERWALL_M2SNF) { @@ -262,9 +263,9 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state) { state.SetRenderStyle(RenderStyle); - if (gltexture) + if (texture) { - if (!gltexture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); + if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); else state.AlphaFunc(Alpha_GEqual, 0.f); RenderTexturedWall(di, state, HWWall::RWF_TEXTURED | HWWall::RWF_NOSPLIT); } @@ -289,7 +290,7 @@ void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent) { if (screen->BuffersArePersistent()) { - if (di->Level->HasDynamicLights && !di->isFullbrightScene() && gltexture != nullptr) + if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr) { SetupLights(di, lightdata); } @@ -442,7 +443,7 @@ const char HWWall::passflag[] = { //========================================================================== void HWWall::PutWall(HWDrawInfo *di, bool translucent) { - if (gltexture && gltexture->GetTranslucency() && passflag[type] == 2) + if (texture && texture->GetTranslucency() && passflag[type] == 2) { translucent = true; } @@ -455,7 +456,7 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent) if (di->isFullbrightScene()) { // light planes don't get drawn with fullbright rendering - if (gltexture == NULL) return; + if (texture == NULL) return; Colormap.Clear(); } @@ -464,7 +465,7 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent) if (!screen->BuffersArePersistent()) { - if (di->Level->HasDynamicLights && !di->isFullbrightScene() && gltexture != nullptr) + if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr) { SetupLights(di, lightdata); } @@ -474,7 +475,7 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent) bool solid; if (passflag[type] == 1) solid = true; - else if (type == RENDERWALL_FFBLOCK) solid = gltexture && !gltexture->isMasked(); + else if (type == RENDERWALL_FFBLOCK) solid = texture && !texture->isMasked(); else solid = false; if (solid) ProcessDecals(di); @@ -914,7 +915,7 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto float l_ul; float texlength; - if (gltexture) + if (texture) { float length = seg->sidedef ? seg->sidedef->TexelLength : Dist2(glseg.x1, glseg.y1, glseg.x2, glseg.y2); @@ -1007,10 +1008,10 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto tcs[UPLFT].u = tcs[LOLFT].u = l_ul + texlength * glseg.fracleft; tcs[UPRGT].u = tcs[LORGT].u = l_ul + texlength * glseg.fracright; - if (gltexture != NULL) + if (texture != NULL) { bool normalize = false; - if (gltexture->isHardwareCanvas()) normalize = true; + if (texture->isHardwareCanvas()) normalize = true; else if (flags & HWF_CLAMPY) { // for negative scales we can get negative coordinates here. @@ -1039,7 +1040,7 @@ void HWWall::CheckTexturePosition(FTexCoordInfo *tci) { float sub; - if (gltexture->isHardwareCanvas()) return; + if (texture->isHardwareCanvas()) return; // clamp texture coordinates to a reasonable range. // Extremely large values can cause visual problems @@ -1104,9 +1105,9 @@ void HWWall::CheckTexturePosition(FTexCoordInfo *tci) } -static void GetTexCoordInfo(FMaterial *tex, FTexCoordInfo *tci, side_t *side, int texpos) +static void GetTexCoordInfo(FGameTexture *tex, FTexCoordInfo *tci, side_t *side, int texpos) { - tci->GetFromTexture(tex->Source(), (float)side->GetTextureXScale(texpos), (float)side->GetTextureYScale(texpos), !!(side->GetLevel()->flags3 & LEVEL3_FORCEWORLDPANNING)); + tci->GetFromTexture(tex, (float)side->GetTextureXScale(texpos), (float)side->GetTextureYScale(texpos), !!(side->GetLevel()->flags3 & LEVEL3_FORCEWORLDPANNING)); } //========================================================================== @@ -1143,7 +1144,7 @@ void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg, FTexCoordInfo tci; - GetTexCoordInfo(gltexture, &tci, seg->sidedef, texpos); + GetTexCoordInfo(texture, &tci, seg->sidedef, texpos); type = _type; @@ -1199,12 +1200,12 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // Get the base coordinates for the texture // // - if (gltexture) + if (texture) { // Align the texture to the ORIGINAL sector's height!! // At this point slopes don't matter because they don't affect the texture's z-position - GetTexCoordInfo(gltexture, &tci, seg->sidedef, side_t::mid); + GetTexCoordInfo(texture, &tci, seg->sidedef, side_t::mid); if (tci.mRenderHeight < 0) { mirrory = true; @@ -1331,7 +1332,7 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // float t_ofs = seg->sidedef->GetTextureXOffset(side_t::mid); - if (gltexture) + if (texture) { // First adjust the texture offset so that the left edge of the linedef is inside the range [0..1]. float texwidth = tci.TextureAdjustWidth(); @@ -1385,15 +1386,15 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, { flags |= HWF_NOSPLITUPPER|HWF_NOSPLITLOWER; type=RENDERWALL_FOGBOUNDARY; - FMaterial *savetex = gltexture; - gltexture = NULL; + auto savetex = texture; + texture = NULL; PutWall(di, true); if (!savetex) { flags &= ~(HWF_NOSPLITUPPER|HWF_NOSPLITLOWER); return; } - gltexture = savetex; + texture = savetex; type=RENDERWALL_M2SNF; } else type=RENDERWALL_M2S; @@ -1412,7 +1413,7 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, case 0: RenderStyle=STYLE_Translucent; alpha = seg->linedef->alpha; - translucent =alpha < 1. || (gltexture && gltexture->GetTranslucency()); + translucent =alpha < 1. || (texture && texture->GetTranslucency()); break; case ML_ADDTRANS: @@ -1431,7 +1432,7 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // // FloatRect *splitrect; - int v = gltexture->sourcetex->GetAreas(&splitrect); + int v = texture->GetAreas(&splitrect); if (seg->frontsector == seg->backsector) flags |= HWF_NOSPLIT; // we don't need to do vertex splits if a line has both sides in the same sector if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX)) { @@ -1532,7 +1533,7 @@ void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, Colormap.LightColor = light->extra_colormap.FadeColor; // the fog plane defines the light di->Level->, not the front sector lightlevel = hw_ClampLight(*light->p_lightlevel); - gltexture = NULL; + texture = NULL; type = RENDERWALL_FFBLOCK; } else return; @@ -1542,21 +1543,21 @@ void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, if (rover->flags&FF_UPPERTEXTURE) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true); - if (!gltexture) return; - GetTexCoordInfo(gltexture, &tci, seg->sidedef, side_t::top); + texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::top), true); + if (!texture || !texture->isValid()) return; + GetTexCoordInfo(texture, &tci, seg->sidedef, side_t::top); } else if (rover->flags&FF_LOWERTEXTURE) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true); - if (!gltexture) return; - GetTexCoordInfo(gltexture, &tci, seg->sidedef, side_t::bottom); + texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::bottom), true); + if (!texture || !texture->isValid()) return; + GetTexCoordInfo(texture, &tci, seg->sidedef, side_t::bottom); } else { - gltexture = FMaterial::ValidateTexture(mastersd->GetTexture(side_t::mid), false, true); - if (!gltexture) return; - GetTexCoordInfo(gltexture, &tci, mastersd, side_t::mid); + texture = TexMan.GetGameTexture(mastersd->GetTexture(side_t::mid), true); + if (!texture || !texture->isValid()) return; + GetTexCoordInfo(texture, &tci, mastersd, side_t::mid); } to = (rover->flags&(FF_UPPERTEXTURE | FF_LOWERTEXTURE)) ? 0 : tci.TextureOffset(mastersd->GetTextureXOffset(side_t::mid)); @@ -1592,7 +1593,7 @@ void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, alpha = rover->alpha / 255.0f; RenderStyle = (rover->flags&FF_ADDITIVETRANS) ? STYLE_Add : STYLE_Translucent; translucent = true; - type = gltexture ? RENDERWALL_M2S : RENDERWALL_COLOR; + type = texture ? RENDERWALL_M2S : RENDERWALL_COLOR; } else { @@ -1959,7 +1960,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ alpha = 1.0f; RenderStyle = STYLE_Normal; - gltexture = NULL; + texture = NULL; if (frontsector->GetWallGlow(topglowcolor, bottomglowcolor)) flags |= HWF_GLOW; @@ -1999,8 +2000,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ else { // normal texture - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true); - if (gltexture) + texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true); + if (texture && texture->isValid()) { DoTexture(di, RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, crefz, frefz, // must come from the original! @@ -2034,8 +2035,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ if (bch1a < fch1 || bch2a < fch2) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true); - if (gltexture) + texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::top), true); + if (texture && texture->isValid()) { DoTexture(di, RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0, crefz, realback->GetPlaneTexZ(sector_t::ceiling), @@ -2047,8 +2048,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ frontsector->GetTexture(sector_t::ceiling) != skyflatnum && backsector->GetTexture(sector_t::ceiling) != skyflatnum) { - gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), false, true); - if (gltexture) + texture = TexMan.GetGameTexture(frontsector->GetTexture(sector_t::ceiling), true); + if (texture && texture->isValid()) { DoTexture(di, RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0, crefz, realback->GetPlaneTexZ(sector_t::ceiling), @@ -2074,17 +2075,17 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ bool drawfogboundary = !di->isFullbrightScene() && di->CheckFog(frontsector, backsec); auto tex = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true); - if (tex != NULL) + if (tex != NULL && tex->isValid()) { if (di->Level->i_compatflags & COMPATF_MASKEDMIDTEX) { tex = tex->GetRawTexture(); } - gltexture = FMaterial::ValidateTexture(tex->GetTexture(), false); + texture = tex; } - else gltexture = NULL; + else texture = nullptr; - if (gltexture || drawfogboundary) + if (texture || drawfogboundary) { DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); @@ -2114,8 +2115,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ if (bfh1 > ffh1 || bfh2 > ffh2) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true); - if (gltexture) + texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::bottom), true); + if (texture && texture->isValid()) { DoTexture(di, RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, realback->GetPlaneTexZ(sector_t::floor), frefz, @@ -2133,8 +2134,8 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ // render it anyway with the sector's floor texture. With a background sky // there are ugly holes otherwise and slopes are simply not precise enough // to mach in any case. - gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true); - if (gltexture) + texture = TexMan.GetGameTexture(frontsector->GetTexture(sector_t::floor), true); + if (texture && texture->isValid()) { DoTexture(di, RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, realback->GetPlaneTexZ(sector_t::floor), frefz, @@ -2203,13 +2204,13 @@ void HWWall::ProcessLowerMiniseg(HWDrawInfo *di, seg_t *seg, sector_t * frontsec zfloor[0] = zfloor[1] = ffh; - gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true); + texture = TexMan.GetGameTexture(frontsector->GetTexture(sector_t::floor), true); - if (gltexture) + if (texture && texture->isValid()) { FTexCoordInfo tci; type = RENDERWALL_BOTTOM; - tci.GetFromTexture(gltexture->Source(), 1, 1, false); + tci.GetFromTexture(texture, 1, 1, false); SetWallCoordinates(seg, &tci, bfh, bfh, bfh, ffh, ffh, 0); PutWall(di, false); }