- initial palette shader work.

This commit is contained in:
Christoph Oelckers 2020-06-15 20:09:49 +02:00
parent b753ea5db7
commit 95b4340eec
6 changed files with 110 additions and 87 deletions

View file

@ -69,13 +69,11 @@ void PaletteManager::DeleteAll()
if (pal) delete pal; if (pal) delete pal;
pal = nullptr; pal = nullptr;
} }
for (auto& pal : palswaptextures) for (auto& pal : lookuptextures)
{ {
if (pal) delete pal; if (pal) delete pal;
pal = nullptr; pal = nullptr;
} }
lastindex = ~0u;
lastsindex = ~0u;
} }
//=========================================================================== //===========================================================================
@ -84,7 +82,7 @@ void PaletteManager::DeleteAll()
// //
//=========================================================================== //===========================================================================
void PaletteManager::BindPalette(int index) IHardwareTexture *PaletteManager::GetPalette(int index)
{ {
auto palettedata = GPalette.GetTranslation(Translation_BasePalettes, index); auto palettedata = GPalette.GetTranslation(Translation_BasePalettes, index);
if (palettedata == nullptr) if (palettedata == nullptr)
@ -95,20 +93,16 @@ void PaletteManager::BindPalette(int index)
if (palettedata) if (palettedata)
{ {
if (index != lastindex) if (palettetextures[index] == nullptr)
{ {
lastindex = index; auto p = screen->CreateHardwareTexture(4);
p->CreateTexture((uint8_t*)palettedata->Palette, 256, 1, 15, false, "Palette");
if (palettetextures[index] == nullptr) palettetextures[index] = p;
{
auto p = screen->CreateHardwareTexture(4);
p->CreateTexture((uint8_t*)palettedata->Palette, 256, 1, 15, false, "Palette");
palettetextures[index] = p;
}
inst->SetPaletteTexture(palettetextures[index]);
} }
return palettetextures[index];
} }
I_FatalError("palette not initialized for palette emulated render mode"); // we cannot continue if this happens.
return nullptr;
} }
//=========================================================================== //===========================================================================
@ -117,35 +111,31 @@ void PaletteManager::BindPalette(int index)
// //
//=========================================================================== //===========================================================================
void PaletteManager::BindPalswap(int index) IHardwareTexture* PaletteManager::GetLookup(int index)
{ {
if (!lookups.checkTable(index)) index = 0; if (!lookups.checkTable(index)) index = 0;
if (lookups.checkTable(index)) if (lookups.checkTable(index))
{ {
if (index != lastsindex) if (lookuptextures[index] == nullptr)
{ {
lastsindex = index; auto p = screen->CreateHardwareTexture(1);
if (palswaptextures[index] == nullptr)
// Perform a 0<->255 index swap. The lookup tables are still the original data.
TArray<uint8_t> lookup(numshades * 256, true);
memcpy(lookup.Data(), lookups.getTable(index), lookup.Size());
for (int i = 0; i < numshades; i++)
{ {
auto p = screen->CreateHardwareTexture(1); auto p = &lookup[i * 256];
p[255] = p[0];
// Perform a 0<->255 index swap. The lookup tables are still the original data. p[0] = 0;
TArray<uint8_t> lookup(numshades * 256, true);
memcpy(lookup.Data(), lookups.getTable(index), lookup.Size());
for (int i = 0; i < numshades; i++)
{
auto p = &lookup[i * 256];
p[255] = p[0];
p[0] = 0;
}
p->CreateTexture(lookup.Data(), 256, numshades, 15, false, "Palette");
palswaptextures[index] = p;
} }
inst->SetLookupTexture(palswaptextures[index]); p->CreateTexture(lookup.Data(), 256, numshades, 15, false, "PaletteLookup");
inst->SetFadeColor(lookups.getFade(index)); lookuptextures[index] = p;
} }
return lookuptextures[index];
} }
I_FatalError("palette lookups not initialized for palette emulated render mode"); // we cannot continue if this happens.
return nullptr;
} }

View file

@ -64,17 +64,8 @@ bool GLInstance::SetTexture(int picnum, FGameTexture* tex, int paletteid, int sa
// This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors. // This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors.
SetTinting(texpick.tintFlags, texpick.tintColor, texpick.tintColor); SetTinting(texpick.tintFlags, texpick.tintColor, texpick.tintColor);
if (texpick.translation != 0) int lookuppal = texpick.translation & 0x7fffffff;
{ SetPalswap(GetTranslationIndex(lookuppal));
int lookuppal = texpick.translation & 0x7fffffff;
SetPalette(GetTranslationType(lookuppal) - Translation_Remap);
SetPalswap(GetTranslationIndex(lookuppal));
}
else
{
SetPalette(0);
SetPalswap(0);
}
SetBasepalTint(texpick.basepalTint); SetBasepalTint(texpick.basepalTint);
auto &mat = renderState.mMaterial; auto &mat = renderState.mMaterial;

View file

@ -78,8 +78,18 @@ GLInstance::GLInstance()
//ImGuiContext* im_ctx; //ImGuiContext* im_ctx;
TArray<uint8_t> ttf; TArray<uint8_t> ttf;
IHardwareTexture *setpalettelayer(int layer, int translation)
{
if (layer == 1)
return GLInterface.palmanager.GetPalette(GetTranslationType(translation) - Translation_Remap);
else if (layer == 2)
return GLInterface.palmanager.GetLookup(GetTranslationIndex(translation));
else return nullptr;
}
void GLInstance::Init(int ydim) void GLInstance::Init(int ydim)
{ {
FMaterial::SetLayerCallback(setpalettelayer);
new(&renderState) PolymostRenderState; // reset to defaults. new(&renderState) PolymostRenderState; // reset to defaults.
} }
@ -143,17 +153,10 @@ void GLInstance::SetIdentityMatrix(int num)
renderState.matrixIndex[num] = -1; renderState.matrixIndex[num] = -1;
} }
void GLInstance::SetPalette(int index)
{
palmanager.BindPalette(index);
}
void GLInstance::SetPalswap(int index) void GLInstance::SetPalswap(int index)
{ {
palmanager.BindPalswap(index);
renderState.ShadeDiv = lookups.tables[index].ShadeFactor; renderState.ShadeDiv = lookups.tables[index].ShadeFactor;
renderState.FogColor = lookups.getFade(index);
} }
void PolymostRenderState::Apply(FRenderState& state, GLState& oldState) void PolymostRenderState::Apply(FRenderState& state, GLState& oldState)

View file

@ -29,10 +29,7 @@ enum
class PaletteManager class PaletteManager
{ {
IHardwareTexture* palettetextures[256] = {}; IHardwareTexture* palettetextures[256] = {};
IHardwareTexture* palswaptextures[256] = {}; IHardwareTexture* lookuptextures[256] = {};
uint32_t lastindex = ~0u;
uint32_t lastsindex = ~0u;
GLInstance* const inst; GLInstance* const inst;
@ -43,8 +40,8 @@ public:
{} {}
~PaletteManager(); ~PaletteManager();
void DeleteAll(); void DeleteAll();
void BindPalette(int index); IHardwareTexture *GetPalette(int index);
void BindPalswap(int index); IHardwareTexture* GetLookup(int index);
}; };
@ -80,6 +77,8 @@ struct GLState
class GLInstance class GLInstance
{ {
friend IHardwareTexture* setpalettelayer(int layer, int translation);
public: public:
TArray<PolymostRenderState> rendercommands; TArray<PolymostRenderState> rendercommands;
PaletteManager palmanager; PaletteManager palmanager;
@ -121,8 +120,6 @@ public:
renderState.matrixIndex[num] = index; renderState.matrixIndex[num] = index;
} }
void SetPalette(int palette);
void SetTextureMode(int m) void SetTextureMode(int m)
{ {
renderState.TextureMode = m; renderState.TextureMode = m;
@ -307,11 +304,6 @@ public:
else renderState.Flags &= ~RF_ShadeInterpolate; else renderState.Flags &= ~RF_ShadeInterpolate;
} }
void SetFadeColor(PalEntry color)
{
renderState.FogColor = color;
};
void SetFadeDisable(bool yes) void SetFadeDisable(bool yes)
{ {
if (yes) renderState.Flags |= RF_FogDisabled; if (yes) renderState.Flags |= RF_FogDisabled;
@ -359,20 +351,7 @@ public:
renderState.AlphaThreshold = al; renderState.AlphaThreshold = al;
} }
void SetPaletteTexture(IHardwareTexture* tex)
{
renderState.PaletteTexture = tex;
}
void SetLookupTexture(IHardwareTexture* tex)
{
renderState.LookupTexture = tex;
}
bool SetTexture(int globalpicnum, FGameTexture* tex, int palette, int sampleroverride); bool SetTexture(int globalpicnum, FGameTexture* tex, int palette, int sampleroverride);
void RenderScene(FRenderState& state);
void DrawScene(int drawmode);
}; };
extern GLInstance GLInterface; extern GLInstance GLInterface;

View file

@ -61,7 +61,6 @@ struct PolymostRenderState
int hictint_flags = -1; int hictint_flags = -1;
FDepthBiasState mBias{ }; FDepthBiasState mBias{ };
FMaterialState mMaterial; FMaterialState mMaterial;
IHardwareTexture* PaletteTexture = nullptr, * LookupTexture = nullptr;
int StateFlags = STF_COLORMASK|STF_DEPTHMASK; int StateFlags = STF_COLORMASK|STF_DEPTHMASK;
FRenderStyle Style{}; FRenderStyle Style{};

View file

@ -1,10 +1,71 @@
const int RF_ShadeInterpolate = 64;
//===========================================================================
//
//
//
//===========================================================================
vec4 ProcessTexel() vec4 ProcessTexel()
{ {
float index = getTexel(vTexCoord.st).r; int u_flags = RF_ShadeInterpolate;
index = ((index * 255.0) + 0.5) / 256.0; float fullbright = 0.0;
vec4 tex = texture(texture2, vec2(index, 0.5)); vec4 color;
tex.a = 1.0; float coordX = vTexCoord.x;
return tex; float coordY = vTexCoord.y;
} vec2 newCoord;
// z is the depth in view space, positive going into the screen
float z;
if (((uPalLightLevels >> 8) & 0xff) == 2)
{
z = distance(pixelpos.xyz, uCameraPos.xyz);
}
else
{
z = pixelpos.w;
}
// Coordinate adjustment for NPOT textures. It is somehow fitting that Build games exploited this texture wrapping quirk of the software rendering engine...
if (uNpotEmulation.y != 0.0)
{
float period = floor(coordY / uNpotEmulation.y);
coordX += uNpotEmulation.x * floor(mod(coordY, uNpotEmulation.y));
coordY = period + mod(coordY, uNpotEmulation.y);
}
newCoord = vec2(coordX, coordY);
color = texture(tex, newCoord);
float visibility = max(uGlobVis * uLightFactor * z - ((u_flags & RF_ShadeInterpolate) != 0.0? 0.5 : 0.0), 0.0);
float numShades = float(uPalLightLevels & 255);
float shade = clamp((uLightLevel + visibility), 0.0, numShades - 1.0);
int palindex = int(color.r * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
int shadeindex = int(floor(shade));
float colorIndexF = texelFetch(texture3, ivec2(palindex, shadeindex), 0).r;
int colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
vec4 palettedColor = texelFetch(texture2, ivec2(colorIndex, 0), 0);
if ((u_flags & RF_ShadeInterpolate) != 0)
{
// Get the next shaded palette index for interpolation
colorIndexF = texelFetch(texture3, ivec2(palindex, shadeindex+1), 0).r;
colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
vec4 palettedColorNext = texelFetch(texture2, ivec2(colorIndex, 0), 0);
float shadeFrac = mod(shade, 1.0);
palettedColor.rgb = mix(palettedColor.rgb, palettedColorNext.rgb, shadeFrac);
}
palettedColor.a = color.r == 0.0? 0.0 : 1.0;// 1.0-floor(color.r);
color = palettedColor;
if (uFogDensity != 0.0) // fog hack for RRRA E2L1. Needs to be done better, this is gross, but still preferable to the broken original implementation.
{
float fogfactor = 0.55 + 0.3 * exp2 (uFogDensity * abs(z) / 1024.0);
color.rgb = uFogColor.rgb * (1.0-fogfactor) + color.rgb * fogfactor;// mix(vec3(0.6), color.rgb, fogfactor);
}
if (color.a < uAlphaThreshold) discard; // it's only here that we have the alpha value available to be able to perform the alpha test.
return color;
}