- added handling for cubemapped skyboxes.

This commit is contained in:
Christoph Oelckers 2021-04-08 00:47:07 +02:00
parent b68512ef88
commit 38ecfc8fa5
7 changed files with 110 additions and 80 deletions

View file

@ -20,11 +20,6 @@
#include "hw_voxels.h" #include "hw_voxels.h"
#include "parsefuncs.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 getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
{ {
int32_t i; int32_t i;
@ -409,43 +404,10 @@ static int32_t defsparser(scriptfile *script)
// OLD (DEPRECATED) DEFINITION SYNTAX // OLD (DEPRECATED) DEFINITION SYNTAX
case T_DEFINETEXTURE: case T_DEFINETEXTURE:
{ parseDefineTexture(*script, pos);
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; break;
case T_DEFINESKYBOX: case T_DEFINESKYBOX:
{ parseDefineSkybox(*script, pos);
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; break;
case T_DEFINETINT: case T_DEFINETINT:
{ {
@ -1609,7 +1571,6 @@ static int32_t defsparser(scriptfile *script)
FString fn[6]; FString fn[6];
FScanner::SavedPos modelend; FScanner::SavedPos modelend;
int32_t i, tile = -1, pal = 0, happy = 1; int32_t i, tile = -1, pal = 0, happy = 1;
int flags = 0;
static const tokenlist skyboxtokens[] = static const tokenlist skyboxtokens[] =
{ {
@ -1663,8 +1624,7 @@ static int32_t defsparser(scriptfile *script)
} }
if (!happy) break; 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, fn);
tileSetSkybox(tile, pal, fns, flags);
} }
break; break;
case T_HIGHPALOOKUP: case T_HIGHPALOOKUP:
@ -1901,7 +1861,6 @@ static int32_t defsparser(scriptfile *script)
int32_t pal=-1, xsiz = 0, ysiz = 0; int32_t pal=-1, xsiz = 0, ysiz = 0;
FString fn; FString fn;
double alphacut = -1.0, xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0; 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[] = static const tokenlist texturetokens_pal[] =
{ {
@ -1972,7 +1931,7 @@ static int32_t defsparser(scriptfile *script)
xscale = 1.0f / xscale; xscale = 1.0f / xscale;
yscale = 1.0f / yscale; yscale = 1.0f / yscale;
tileSetHightileReplacement(tile,pal,fn,alphacut,xscale,yscale, specpower, specfactor,flags); tileSetHightileReplacement(tile,pal,fn,alphacut,xscale,yscale, specpower, specfactor);
} }
break; break;
case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL: 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); auto detailpos = scriptfile_getposition(script);
FScanner::SavedPos detailend; FScanner::SavedPos detailend;
int32_t pal = 0; int32_t pal = 0;
char flags = 0;
FString fn; FString fn;
double xscale = 1.0, yscale = 1.0, specpower = 1.0, specfactor = 1.0; 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; pal = NORMALPAL;
break; break;
} }
tileSetHightileReplacement(tile,pal,fn,-1.0f,xscale,yscale, specpower, specfactor,flags); tileSetHightileReplacement(tile,pal,fn,-1.0f,xscale,yscale, specpower, specfactor);
} }
break; break;
default: default:

View file

@ -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) void parseSetupTile(FScanner& sc, FScriptPosition& pos)
{ {
int tile; int tile;

View file

@ -11,6 +11,7 @@
#include "gamefuncs.h" #include "gamefuncs.h"
#include "render.h" #include "render.h"
#include "matrix.h" #include "matrix.h"
#include "gamecontrol.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable:4244) #pragma warning(disable:4244)
@ -357,3 +358,20 @@ inline float sectorVisibility(sectortype* sec)
} }
inline const float hw_density = 0.35f; 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);
}

View file

@ -32,6 +32,7 @@
CVAR(Bool,gl_noskyboxes, false, 0) CVAR(Bool,gl_noskyboxes, false, 0)
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap); 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) void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane, PalEntry FadeColor)
{ {
int picnum = plane == plane_ceiling ? sector->ceilingpicnum : sector->floorpicnum; 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; int32_t dapyscale = 0, dapskybits = 0, dapyoffs = 0, daptileyscale = 0;
FGameTexture* skytex = nullptr; FGameTexture* skytex = SkyboxReplacement(tileGetTexture(picnum)->GetID(), palette);
int realskybits = 0; int realskybits = 0;
// todo: check for skybox replacement. // todo: check for skybox replacement.
if (!skytex) if (!skytex)
{ {
int palette = plane == plane_ceiling ? sector->ceilingpal : sector->floorpal;
int remap = TRANSLATION(Translation_Remap + curbasepal, palette); int remap = TRANSLATION(Translation_Remap + curbasepal, palette);
int16_t const* dapskyoff = getpsky(picnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale); int16_t const* dapskyoff = getpsky(picnum, &dapyscale, &dapskybits, &dapyoffs, &daptileyscale);

View file

@ -26,7 +26,8 @@
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "skyboxtexture.h" #include "skyboxtexture.h"
CVAR(Float, skyoffsettest, 0, 0) CVAR(Float, skyoffsettest, 0, 0)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// //

View file

@ -60,7 +60,7 @@ enum
BuildTiles TileFiles; 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); TexMan.AddGameTexture(tex);
TileFiles.tiledata[tilenum].backup = TileFiles.tiledata[tilenum].texture = tex; TileFiles.tiledata[tilenum].backup = TileFiles.tiledata[tilenum].texture = tex;
if (istexture) 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; return 0;
} }

View file

@ -48,15 +48,17 @@
#include "sc_man.h" #include "sc_man.h"
#include "gamestruct.h" #include "gamestruct.h"
#include "hw_renderstate.h" #include "hw_renderstate.h"
#include "skyboxtexture.h"
CVARD(Bool, hw_shadeinterpolate, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable shade interpolation") CVARD(Bool, hw_shadeinterpolate, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable shade interpolation")
struct HightileReplacement struct HightileReplacement
{ {
FGameTexture* faces[6]; // only one gets used by a texture, the other 5 are for skyboxes only FGameTexture* image;
FVector2 scale; FVector2 scale;
float alphacut, specpower, specfactor; float alphacut, specpower, specfactor;
uint16_t palnum, flags; uint16_t palnum;
bool issky;
}; };
static TMap<int, TArray<HightileReplacement>> tileReplacements; static TMap<int, TArray<HightileReplacement>> tileReplacements;
@ -91,7 +93,7 @@ static void AddReplacement(int picnum, const HightileReplacement& replace)
auto& Hightiles = tileReplacements[picnum]; auto& Hightiles = tileReplacements[picnum];
for (auto& ht : Hightiles) 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; ht = replace;
return; return;
@ -125,7 +127,7 @@ static HightileReplacement* FindReplacement(FTextureID picnum, int palnum, bool
{ {
for (auto& rep : *Hightiles) 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; if (!palnum || palnum >= MAXPALOOKUPS - RESERVEDPALS) break;
palnum = 0; palnum = 0;
@ -137,11 +139,19 @@ int checkTranslucentReplacement(FTextureID picnum, int pal)
{ {
FGameTexture* tex = nullptr; FGameTexture* tex = nullptr;
auto si = FindReplacement(picnum, pal, 0); 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; if (!tex || tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
return tex && tex->GetTranslucency(); 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 // Processes data from .def files into the textures
@ -163,19 +173,19 @@ void PostLoadSetup()
{ {
if (rep.palnum == GLOWPAL) if (rep.palnum == GLOWPAL)
{ {
glowTex = rep.faces[0]; glowTex = rep.image;
} }
if (rep.palnum == NORMALPAL) if (rep.palnum == NORMALPAL)
{ {
normalTex = rep.faces[0]; normalTex = rep.image;
} }
if (rep.palnum == SPECULARPAL) if (rep.palnum == SPECULARPAL)
{ {
specTex = rep.faces[0]; specTex = rep.image;
} }
if (rep.palnum == DETAILPAL) if (rep.palnum == DETAILPAL)
{ {
detailTex = rep.faces[0]; detailTex = rep.image;
scalex = rep.scale.X; scalex = rep.scale.X;
scaley = rep.scale.Y; scaley = rep.scale.Y;
} }
@ -185,10 +195,10 @@ void PostLoadSetup()
{ {
for (auto& rep : *Hightile) 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) 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. // 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); tex = MakeGameTexture(tex->GetTexture(), "", ETextureType::Any);
if (glowTex) tex->SetGlowmap(glowTex->GetTexture()); if (glowTex) tex->SetGlowmap(glowTex->GetTexture());
@ -196,7 +206,7 @@ void PostLoadSetup()
if (normalTex) tex->SetNormalmap(normalTex->GetTexture()); if (normalTex) tex->SetNormalmap(normalTex->GetTexture());
if (specTex) tex->SetSpecularmap(specTex->GetTexture()); if (specTex) tex->SetSpecularmap(specTex->GetTexture());
tex->SetDetailScale(scalex, scaley); 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)picnum >= (uint32_t)MAXTILES) return -1;
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) 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; return -1;
} }
replace.faces[0] = TexMan.GetGameTexture(texid); replace.image = TexMan.GetGameTexture(texid);
if (replace.faces[0] == nullptr)
replace.alphacut = min(alphacut,1.f); replace.alphacut = min(alphacut,1.f);
replace.scale = { xscale, yscale }; replace.scale = { xscale, yscale };
replace.specpower = specpower; // currently unused replace.specpower = specpower; // currently unused
replace.specfactor = specfactor; // currently unused replace.specfactor = specfactor; // currently unused
replace.flags = flags; replace.issky = 0;
replace.palnum = (uint16_t)palnum; replace.palnum = (uint16_t)palnum;
AddReplacement(picnum, replace); AddReplacement(picnum, replace);
return 0; return 0;
@ -276,7 +285,7 @@ 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)picnum >= (uint32_t)MAXTILES) return -1;
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1; if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
@ -289,17 +298,25 @@ int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags )
} }
HightileReplacement replace = {}; 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()) 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; 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; replace.palnum = (uint16_t)palnum;
AddReplacement(picnum, replace); AddReplacement(picnum, replace);
return 0; return 0;
@ -341,7 +358,7 @@ bool PickTexture(FRenderState *state, FGameTexture* tex, int paletteid, TextureP
if (rep) if (rep)
{ {
tex = rep->faces[0]; tex = rep->image;
} }
if (!rep || rep->palnum != hipalswap || (h.tintFlags & TINTF_APPLYOVERALTPAL)) if (!rep || rep->palnum != hipalswap || (h.tintFlags & TINTF_APPLYOVERALTPAL))
applytint = true; applytint = true;