- use separate textures for the palswap shade tables.

This creates a lot less mess than one big texture and also allows easier use of texelFetch in the server which is preferable for data textures.
This commit is contained in:
Christoph Oelckers 2019-10-08 01:08:08 +02:00
parent 06e9a60190
commit 7131fe6c6e
8 changed files with 37 additions and 71 deletions

View file

@ -384,7 +384,6 @@ void polymost_glinit()
{
GLInterface.SetPalswapData(palookupnum, (uint8_t*)palookup[palookupnum], numshades+1);
}
GLInterface.UpdatePalswaps(256, numshades+1);
}
////////// VISIBILITY FOG ROUTINES //////////
@ -716,7 +715,6 @@ void uploadpalswaps(int count, int32_t* swaps)
{
GLInterface.SetPalswapData(i, (uint8_t*)palookup[i], numshades + 1);
}
GLInterface.UpdatePalswaps(256, numshades + 1);
}

View file

@ -65,6 +65,10 @@ void PaletteManager::DeleteAll()
{
if (pal.paltexture) delete pal.paltexture;
}
for (auto& pal : palswaps)
{
if (pal.swaptexture) delete pal.swaptexture;
}
if (transientpalette.paltexture) delete transientpalette.paltexture;
if (palswapTexture) delete palswapTexture;
palswapTexture = nullptr;
@ -72,7 +76,8 @@ void PaletteManager::DeleteAll()
transientpalette.crc32 = -1;
palettes.Reset();
palswaps.Reset();
lastindex = -1;
lastindex = ~0u;
lastsindex = ~0u;
memset(palettemap, 0, sizeof(palettemap));
memset(palswapmap, 0, sizeof(palswapmap));
memset(addshade, 0, sizeof(addshade));
@ -131,6 +136,7 @@ unsigned PaletteManager::FindPalswap(const uint8_t* paldata)
PalswapData pd;
pd.lookup = paldata;
pd.crc32 = crc32;
pd.swaptexture = nullptr;
return palswaps.Push(pd);
}
@ -214,24 +220,6 @@ void PaletteManager::SetPalswapData(int index, const uint8_t* data, int numshade
if (index < 0 || index > 255) return; // invalid index - ignore.
numshades = numshades_;
palswapmap[index] = FindPalswap(data);
if (palswapTexture == nullptr)
{
palswapTexture = inst->NewTexture();
palswapTexture->CreateTexture(PALSWAP_TEXTURE_SIZE, PALSWAP_TEXTURE_SIZE, true, false);
palswapTexture->SetSampler(Sampler2DNoFilter);
}
int32_t column = index % (PALSWAP_TEXTURE_SIZE / 256);
int32_t row = index / (PALSWAP_TEXTURE_SIZE / 256);
int32_t rowOffset = (numshades + 1) * row;
if (rowOffset > PALSWAP_TEXTURE_SIZE)
{
OSD_Printf("Polymost: palswaps are too large for palswap tilesheet!\n");
return;
}
palswapTexture->LoadTexturePart(data, 256 * column, rowOffset, 256, numshades + 1);
}
//===========================================================================
@ -240,20 +228,25 @@ void PaletteManager::SetPalswapData(int index, const uint8_t* data, int numshade
//
//===========================================================================
void PaletteManager::UpdatePalswaps(int width, int height)
void PaletteManager::BindPalswap(int index)
{
for (auto& pal : palettes)
if (palswapmap[index] < palswaps.Size())
{
pal.shadesdone = false;
auto uindex = palswapmap[index];
if (uindex != lastsindex)
{
lastsindex = uindex;
if (palswaps[uindex].swaptexture == nullptr)
{
auto p = GLInterface.NewTexture();
p->CreateTexture(256, numshades, true, false);
p->LoadTexture((uint8_t*)palswaps[uindex].lookup);
p->SetSampler(Sampler2DNoFilter);
palswaps[uindex].swaptexture = p;
}
inst->BindTexture(1, palswaps[uindex].swaptexture);
}
}
// recreate it
vec2f_t polymost1PalswapSize = { width * (1.f / PALSWAP_TEXTURE_SIZE),
height * (1.f / PALSWAP_TEXTURE_SIZE) };
vec2f_t polymost1PalswapInnerSize = { (width - 1) * (1.f / PALSWAP_TEXTURE_SIZE),
(height - 1) * (1.f / PALSWAP_TEXTURE_SIZE) };
inst->SetPalswapSize(&polymost1PalswapInnerSize.x);
inst->BindTexture(1, palswapTexture);
}

View file

@ -4,9 +4,6 @@ class PolymostShader;
struct PolymostRenderState
{
int PalSwapIndex;
float PalswapPos[2];
float PalswapSize[2];
float Clamp[2];
float Shade;
float NumShades = 64.f;

View file

@ -141,9 +141,7 @@ bool PolymostShader::Load(const char * name, const char * vert_prog, const char
{
if (!FShader::Load(name, vert_prog, frag_prog)) return false;
PalswapPos.Init(hShader, "u_palswapPos");
PalswapSize.Init(hShader, "u_palswapSize");
Clamp.Init(hShader, "u_clamp");
Clamp.Init(hShader, "u_clamp");
Shade.Init(hShader, "u_shade");
NumShades.Init(hShader, "u_numShades");
VisFactor.Init(hShader, "u_visFactor");

View file

@ -35,9 +35,6 @@ public:
class PolymostShader : public FShader
{
public:
FBufferedUniform1f PalswapIndex;
FBufferedUniform2f PalswapPos;
FBufferedUniform2f PalswapSize;
FBufferedUniform2f Clamp;
FBufferedUniform1f Shade;
FBufferedUniform1f NumShades;

View file

@ -441,10 +441,7 @@ void GLInstance::SetPalette(int index)
void GLInstance::SetPalswap(int index)
{
float v1 = index * renderState.PalswapSize[0];
float v2 = floorf(v1);
renderState.PalswapPos[0] = v1 - v2 + (0.5f / PALSWAP_TEXTURE_SIZE);
renderState.PalswapPos[1] = v2 * renderState.PalswapSize[1] + (0.5f / PALSWAP_TEXTURE_SIZE);
palmanager.BindPalswap(index);
}
@ -466,9 +463,6 @@ void PolymostRenderState::Apply(PolymostShader* shader)
shader->Brightness.Set(Brightness);
shader->Fog.Set(Fog);
shader->FogColor.Set(FogColor);
shader->PalswapPos.Set(PalswapPos);
shader->PalswapSize.Set(PalswapSize);
shader->PalswapIndex.Set(PalSwapIndex);
}

View file

@ -36,6 +36,7 @@ struct PalswapData
{
int32_t crc32;
const uint8_t *lookup; // points to the original data. This is static so no need to copy
FHardwareTexture* swaptexture;
};
enum
@ -51,6 +52,7 @@ class PaletteManager
float addshade[256] = {};
float mulshade[256] = {};
uint32_t lastindex = ~0u;
uint32_t lastsindex = ~0u;
int numshades = 1;
// Keep the short lived movie palettes out of the palette list for ease of maintenance.
@ -75,9 +77,9 @@ public:
void DeleteAll();
void SetPalette(int index, const uint8_t *data, bool transient);
void SetPalswapData(int index, const uint8_t* data, int numshades);
void UpdatePalswaps(int w, int h);
void BindPalette(int index);
void BindPalswap(int index);
};
@ -287,19 +289,8 @@ public:
palmanager.SetPalswapData(index, data, numshades);
}
void UpdatePalswaps(int w, int h)
{
palmanager.UpdatePalswaps(w, h);
}
void SetPalswap(int index);
void SetPalswapSize(float* pos)
{
renderState.PalswapSize[0] = pos[0];
renderState.PalswapSize[1] = pos[1];
}
int GetClamp()
{
return int(renderState.Clamp[0] + 2*renderState.Clamp[1]);

View file

@ -10,9 +10,6 @@ uniform sampler2D s_palette;
uniform sampler2D s_detail;
uniform sampler2D s_glow;
uniform vec2 u_palswapPos;
uniform vec2 u_palswapSize;
uniform vec2 u_clamp;
uniform float u_shade;
@ -164,17 +161,18 @@ void main()
if (u_usePalette != 0.0)
{
// Get the shaded palette index
float colorIndex = texture2D(s_palswap, u_palswapPos + u_palswapSize*vec2(color.r, floor(shade)/u_numShades)).r;
colorIndex = c_basepalOffset + c_basepalScale*colorIndex; // this is for compensating roundoff errors.
vec4 palettedColor = texture2D(s_palette, vec2(colorIndex, c_zero));
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(s_palswap, ivec2(palindex, shadeindex), 0).r;
int colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
vec4 palettedColor = texelFetch(s_palette, ivec2(colorIndex, 0), 0);
if (u_shadeInterpolate != 0.0)
{
// Get the next shaded palette index for interpolation
colorIndex = texture2D(s_palswap, u_palswapPos+u_palswapSize*vec2(color.r, (floor(shade)+1.0)/u_numShades)).r;
colorIndex = c_basepalOffset + c_basepalScale*colorIndex; // this is for compensating roundoff errors.
vec4 palettedColorNext = texture2D(s_palette, vec2(colorIndex, c_zero));
colorIndexF = texelFetch(s_palswap, ivec2(palindex, shadeindex+1), 0).r;
colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation.
vec4 palettedColorNext = texelFetch(s_palette, ivec2(colorIndex, 0), 0);
float shadeFrac = mod(shade, 1.0);
palettedColor.rgb = mix(palettedColor.rgb, palettedColorNext.rgb, shadeFrac);
}