- 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 "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:

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)
{
int tile;

View file

@ -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);
}

View file

@ -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);

View file

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

View file

@ -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;
}

View file

@ -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<int, TArray<HightileReplacement>> 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;