From 38ecfc8fa55cdc7dffbd20c83d8c3a47d4d985fd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 8 Apr 2021 00:47:07 +0200 Subject: [PATCH] - added handling for cubemapped skyboxes. --- source/build/src/defs.cpp | 56 ++-------------- source/core/parsefuncs.h | 35 ++++++++++ source/core/rendering/scene/hw_drawstructs.h | 18 +++++ source/core/rendering/scene/hw_sky.cpp | 5 +- source/core/rendering/scene/hw_skyportal.cpp | 3 +- source/core/textures/buildtiles.cpp | 4 +- source/core/textures/hightile.cpp | 69 ++++++++++++-------- 7 files changed, 110 insertions(+), 80 deletions(-) diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 55f382431..bf9d48197 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -20,11 +20,6 @@ #include "hw_voxels.h" #include "parsefuncs.h" -int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags); -int tileSetSkybox(int picnum, int palnum, const char** facenames, int flags); -void tileRemoveReplacement(int num); - - int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens) { int32_t i; @@ -409,44 +404,11 @@ static int32_t defsparser(scriptfile *script) // OLD (DEPRECATED) DEFINITION SYNTAX case T_DEFINETEXTURE: - { - int32_t tile,pal,fnoo; - FString fn; - - if (scriptfile_getsymbol(script,&tile)) break; - if (scriptfile_getsymbol(script,&pal)) break; - if (scriptfile_getnumber(script,&fnoo)) break; //x-center - if (scriptfile_getnumber(script,&fnoo)) break; //y-center - if (scriptfile_getnumber(script,&fnoo)) break; //x-size - if (scriptfile_getnumber(script,&fnoo)) break; //y-size - if (scriptfile_getstring(script,&fn)) break; - - if (!fileSystem.FileExists(fn)) - break; - - tileSetHightileReplacement(tile,pal,fn,-1.0,1.0,1.0,1.0,1.0,0); - } - break; + parseDefineTexture(*script, pos); + break; case T_DEFINESKYBOX: - { - int32_t tile,pal,i; - FString fn[6]; - int happy = 1; - - if (scriptfile_getsymbol(script,&tile)) break; - if (scriptfile_getsymbol(script,&pal)) break; - if (scriptfile_getsymbol(script,&i)) break; //future expansion - for (i=0; i<6; i++) - { - if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces - - if (!fileSystem.FileExists(fn[i])) - happy = 0; - } - if (i < 6 || !happy) break; - tileSetSkybox(tile, pal, (const char **)fn, 0); - } - break; + parseDefineSkybox(*script, pos); + break; case T_DEFINETINT: { int32_t pal, r,g,b,f; @@ -1609,7 +1571,6 @@ static int32_t defsparser(scriptfile *script) FString fn[6]; FScanner::SavedPos modelend; int32_t i, tile = -1, pal = 0, happy = 1; - int flags = 0; static const tokenlist skyboxtokens[] = { @@ -1663,8 +1624,7 @@ static int32_t defsparser(scriptfile *script) } if (!happy) break; - const char* fns[] = { fn[0].GetChars(), fn[1].GetChars(), fn[2].GetChars(), fn[3].GetChars(), fn[4].GetChars(), fn[5].GetChars() }; - tileSetSkybox(tile, pal, fns, flags); + tileSetSkybox(tile, pal, fn); } break; case T_HIGHPALOOKUP: @@ -1901,7 +1861,6 @@ static int32_t defsparser(scriptfile *script) int32_t pal=-1, xsiz = 0, ysiz = 0; FString fn; double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0; - uint8_t flags = 0; static const tokenlist texturetokens_pal[] = { @@ -1972,7 +1931,7 @@ static int32_t defsparser(scriptfile *script) xscale = 1.0f / xscale; yscale = 1.0f / yscale; - tileSetHightileReplacement(tile,pal,fn,alphacut,xscale,yscale, specpower, specfactor,flags); + tileSetHightileReplacement(tile,pal,fn,alphacut,xscale,yscale, specpower, specfactor); } break; case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL: @@ -1980,7 +1939,6 @@ static int32_t defsparser(scriptfile *script) auto detailpos = scriptfile_getposition(script); FScanner::SavedPos detailend; int32_t pal = 0; - char flags = 0; FString fn; double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0; @@ -2045,7 +2003,7 @@ static int32_t defsparser(scriptfile *script) pal = NORMALPAL; break; } - tileSetHightileReplacement(tile,pal,fn,-1.0f,xscale,yscale, specpower, specfactor,flags); + tileSetHightileReplacement(tile,pal,fn,-1.0f,xscale,yscale, specpower, specfactor); } break; default: diff --git a/source/core/parsefuncs.h b/source/core/parsefuncs.h index 498f3cdb7..6096bdd2d 100644 --- a/source/core/parsefuncs.h +++ b/source/core/parsefuncs.h @@ -35,6 +35,41 @@ ** */ +int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor); +int tileSetSkybox(int picnum, int palnum, FString* facenames); +void tileRemoveReplacement(int num); + +void parseDefineTexture(FScanner& sc, FScriptPosition& pos) +{ + int tile, palette; + + if (!sc.GetNumber(tile, true)) return; + if (!sc.GetNumber(palette, true)) return; + if (!sc.GetNumber(true)) return; //formerly x-center, unused + if (!sc.GetNumber(true)) return; //formerly y-center, unused + if (!sc.GetNumber(true)) return; //formerly x-size, unused + if (!sc.GetNumber(true)) return; //formerly y-size, unused + if (!sc.GetString()) return; + + tileSetHightileReplacement(tile, palette, sc.String, -1.0, 1.0, 1.0, 1.0, 1.0); +} + +void parseDefineSkybox(FScanner& sc, FScriptPosition& pos) +{ + int tile, palette; + FString fn[6]; + + if (!sc.GetNumber(tile, true)) return; + if (!sc.GetNumber(palette, true)) return; + if (!sc.GetNumber(true)) return; //'future extension' (for what?) + for (int i = 0; i < 6; i++) + { + if (!sc.GetString()) return; + fn[i] = sc.String; + } + tileSetSkybox(tile, palette, fn); +} + void parseSetupTile(FScanner& sc, FScriptPosition& pos) { int tile; diff --git a/source/core/rendering/scene/hw_drawstructs.h b/source/core/rendering/scene/hw_drawstructs.h index 68869f8ea..1c7416553 100644 --- a/source/core/rendering/scene/hw_drawstructs.h +++ b/source/core/rendering/scene/hw_drawstructs.h @@ -11,6 +11,7 @@ #include "gamefuncs.h" #include "render.h" #include "matrix.h" +#include "gamecontrol.h" #ifdef _MSC_VER #pragma warning(disable:4244) @@ -357,3 +358,20 @@ inline float sectorVisibility(sectortype* sec) } inline const float hw_density = 0.35f; + +int checkTranslucentReplacement(FTextureID picnum, int pal); + +inline bool maskWallHasTranslucency(const walltype* wall) +{ + return (wall->cstat & CSTAT_WALL_TRANSLUCENT) || checkTranslucentReplacement(tileGetTexture(wall->picnum)->GetID(), wall->pal); +} + +inline bool spriteHasTranslucency(const spritetype* tspr) +{ + if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || //(tspr->clipdist & TSPR_FLAGS_DRAW_LAST) || + ((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha)) + return true; + + return checkTranslucentReplacement(tileGetTexture(tspr->picnum)->GetID(), tspr->pal); +} + diff --git a/source/core/rendering/scene/hw_sky.cpp b/source/core/rendering/scene/hw_sky.cpp index fead13983..4577ed0b8 100644 --- a/source/core/rendering/scene/hw_sky.cpp +++ b/source/core/rendering/scene/hw_sky.cpp @@ -32,6 +32,7 @@ CVAR(Bool,gl_noskyboxes, false, 0) FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap); +FGameTexture* SkyboxReplacement(FTextureID picnum, int palnum); //========================================================================== // @@ -42,14 +43,14 @@ FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilema void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane, PalEntry FadeColor) { int picnum = plane == plane_ceiling ? sector->ceilingpicnum : sector->floorpicnum; + int palette = plane == plane_ceiling ? sector->ceilingpal : sector->floorpal; int32_t dapyscale = 0, dapskybits = 0, dapyoffs = 0, daptileyscale = 0; - FGameTexture* skytex = nullptr; + FGameTexture* skytex = SkyboxReplacement(tileGetTexture(picnum)->GetID(), palette); int realskybits = 0; // todo: check for skybox replacement. if (!skytex) { - int palette = plane == plane_ceiling ? sector->ceilingpal : sector->floorpal; int remap = TRANSLATION(Translation_Remap + curbasepal, palette); int16_t const* dapskyoff = getpsky(picnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale); diff --git a/source/core/rendering/scene/hw_skyportal.cpp b/source/core/rendering/scene/hw_skyportal.cpp index 0d0e7260b..457b97fe1 100644 --- a/source/core/rendering/scene/hw_skyportal.cpp +++ b/source/core/rendering/scene/hw_skyportal.cpp @@ -26,7 +26,8 @@ #include "hw_renderstate.h" #include "skyboxtexture.h" - CVAR(Float, skyoffsettest, 0, 0) +CVAR(Float, skyoffsettest, 0, 0) + //----------------------------------------------------------------------------- // // diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index 2148b27a7..a515647d6 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -60,7 +60,7 @@ enum BuildTiles TileFiles; -int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags); +int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor); //========================================================================== // @@ -514,7 +514,7 @@ int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istextu TexMan.AddGameTexture(tex); TileFiles.tiledata[tilenum].backup = TileFiles.tiledata[tilenum].texture = tex; if (istexture) - tileSetHightileReplacement(tilenum, 0, fn, (float)(255 - alphacut) * (1.f / 255.f), 1.0f, 1.0f, 1.0, 1.0, 0); + tileSetHightileReplacement(tilenum, 0, fn, (float)(255 - alphacut) * (1.f / 255.f), 1.0f, 1.0f, 1.0, 1.0); return 0; } diff --git a/source/core/textures/hightile.cpp b/source/core/textures/hightile.cpp index f5d240233..e73e72686 100644 --- a/source/core/textures/hightile.cpp +++ b/source/core/textures/hightile.cpp @@ -48,15 +48,17 @@ #include "sc_man.h" #include "gamestruct.h" #include "hw_renderstate.h" +#include "skyboxtexture.h" CVARD(Bool, hw_shadeinterpolate, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable shade interpolation") struct HightileReplacement { - FGameTexture* faces[6]; // only one gets used by a texture, the other 5 are for skyboxes only + FGameTexture* image; FVector2 scale; float alphacut, specpower, specfactor; - uint16_t palnum, flags; + uint16_t palnum; + bool issky; }; static TMap> tileReplacements; @@ -91,7 +93,7 @@ static void AddReplacement(int picnum, const HightileReplacement& replace) auto& Hightiles = tileReplacements[picnum]; for (auto& ht : Hightiles) { - if (replace.palnum == ht.palnum && (replace.faces[1] == nullptr) == (ht.faces[1] == nullptr)) + if (replace.palnum == ht.palnum && replace.issky == ht.issky) { ht = replace; return; @@ -125,7 +127,7 @@ static HightileReplacement* FindReplacement(FTextureID picnum, int palnum, bool { for (auto& rep : *Hightiles) { - if (rep.palnum == palnum && (rep.faces[1] != nullptr) == skybox) return &rep; + if (rep.palnum == palnum && rep.issky == skybox) return &rep; } if (!palnum || palnum >= MAXPALOOKUPS - RESERVEDPALS) break; palnum = 0; @@ -137,11 +139,19 @@ int checkTranslucentReplacement(FTextureID picnum, int pal) { FGameTexture* tex = nullptr; auto si = FindReplacement(picnum, pal, 0); - if (si && hw_hightile) tex = si->faces[0]; + if (si && hw_hightile) tex = si->image; if (!tex || tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false; return tex && tex->GetTranslucency(); } +FGameTexture* SkyboxReplacement(FTextureID picnum, int palnum) +{ + auto hr = FindReplacement(picnum, palnum, true); + if (!hr) return nullptr; + return hr->image; +} + + //========================================================================== // // Processes data from .def files into the textures @@ -163,19 +173,19 @@ void PostLoadSetup() { if (rep.palnum == GLOWPAL) { - glowTex = rep.faces[0]; + glowTex = rep.image; } if (rep.palnum == NORMALPAL) { - normalTex = rep.faces[0]; + normalTex = rep.image; } if (rep.palnum == SPECULARPAL) { - specTex = rep.faces[0]; + specTex = rep.image; } if (rep.palnum == DETAILPAL) { - detailTex = rep.faces[0]; + detailTex = rep.image; scalex = rep.scale.X; scaley = rep.scale.Y; } @@ -185,10 +195,10 @@ void PostLoadSetup() { for (auto& rep : *Hightile) { - if (rep.faces[1]) continue; // do not muck around with skyboxes (yet) + if (rep.issky) continue; // do not muck around with skyboxes (yet) if (rep.palnum < NORMALPAL) { - auto tex = rep.faces[0]; + auto tex = rep.image; // Make a copy so that multiple appearances of the same texture with different layers can be handled. They will all refer to the same internal texture anyway. tex = MakeGameTexture(tex->GetTexture(), "", ETextureType::Any); if (glowTex) tex->SetGlowmap(glowTex->GetTexture()); @@ -196,7 +206,7 @@ void PostLoadSetup() if (normalTex) tex->SetNormalmap(normalTex->GetTexture()); if (specTex) tex->SetSpecularmap(specTex->GetTexture()); tex->SetDetailScale(scalex, scaley); - rep.faces[0] = tex; + rep.image = tex; } } } @@ -237,7 +247,7 @@ void PostLoadSetup() // //========================================================================== -int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags) +int tileSetHightileReplacement(int picnum, int palnum, const char* filename, float alphacut, float xscale, float yscale, float specpower, float specfactor) { if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1; if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1; @@ -257,13 +267,12 @@ int tileSetHightileReplacement(int picnum, int palnum, const char* filename, flo return -1; } - replace.faces[0] = TexMan.GetGameTexture(texid); - if (replace.faces[0] == nullptr) + replace.image = TexMan.GetGameTexture(texid); replace.alphacut = min(alphacut,1.f); replace.scale = { xscale, yscale }; replace.specpower = specpower; // currently unused replace.specfactor = specfactor; // currently unused - replace.flags = flags; + replace.issky = 0; replace.palnum = (uint16_t)palnum; AddReplacement(picnum, replace); return 0; @@ -276,10 +285,10 @@ int tileSetHightileReplacement(int picnum, int palnum, const char* filename, flo // //========================================================================== -int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags ) +int tileSetSkybox(int picnum, int palnum, FString* facenames) { - if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1; - if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1; + if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1; + if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1; auto tex = tileGetTexture(picnum); if (tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) @@ -288,18 +297,26 @@ int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags ) return -1; // cannot add replacements to empty tiles, must create one beforehand } HightileReplacement replace = {}; - - for (auto &face : replace.faces) + + FGameTexture *faces[6]; + const static uint8_t map[] = { 2, 1, 0, 3, 4, 5 }; + for (int i = 0; i < 6; i++) { - FTextureID texid = TexMan.CheckForTexture(*facenames, ETextureType::Any); + FTextureID texid = TexMan.CheckForTexture(facenames[i], ETextureType::Any); if (!texid.isValid()) { - Printf("%s: Skybox image for tile %d does not exist or is invalid\n", *facenames, picnum); + Printf("%s: Skybox image for tile %d does not exist or is invalid\n", facenames[i].GetChars(), picnum); return -1; } - face = TexMan.GetGameTexture(texid); + faces[map[i]] = TexMan.GetGameTexture(texid); } - replace.flags = flags; + FSkyBox* sbtex = new FSkyBox(""); + memcpy(sbtex->faces, faces, sizeof(faces)); + sbtex->previous = faces[0]; // won't ever be used, just to be safe. + sbtex->fliptop = true; + replace.image = MakeGameTexture(sbtex, "", ETextureType::Override); + TexMan.AddGameTexture(replace.image, false); + replace.issky = 1; replace.palnum = (uint16_t)palnum; AddReplacement(picnum, replace); return 0; @@ -341,7 +358,7 @@ bool PickTexture(FRenderState *state, FGameTexture* tex, int paletteid, TextureP if (rep) { - tex = rep->faces[0]; + tex = rep->image; } if (!rep || rep->palnum != hipalswap || (h.tintFlags & TINTF_APPLYOVERALTPAL)) applytint = true;