Rework Palette Rendering #86

Merged
alufolie91 merged 24 commits from newpalshader into Saturn-Next 2024-01-18 16:28:19 +01:00
22 changed files with 587 additions and 512 deletions

No files matched your search

+217 -27
View File
@@ -33,12 +33,20 @@ static INT32 blocksize, blockwidth, blockheight;
INT32 patchformat = GR_TEXFMT_AP_88; // use alpha for holes
INT32 textureformat = GR_TEXFMT_P_8; // use chromakey for hole
RGBA_t mapPalette[256] = {0}; // the palette for the currently loaded level or menu etc.
// Returns a pointer to the palette which should be used for caching textures.
RGBA_t *HWR_GetTexturePalette(void)
{
return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette;
}
// sprite, use alpha and chroma key for hole
static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
INT32 pblockwidth, INT32 pblockheight, INT32 blockmodulo,
INT32 ptexturewidth, INT32 ptextureheight,
INT32 originx, INT32 originy, // where to draw patch in surface block
const patch_t *realpatch, INT32 bpp)
const patch_t *realpatch, INT32 bpp, RGBA_t *palette)
{
INT32 x, x1, x2;
INT32 col, ncols;
@@ -67,6 +75,8 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
if (!ptexturewidth)
return;
palette = HWR_GetTexturePalette();
col = x * pblockwidth / ptexturewidth;
ncols = ((x2 - x) * pblockwidth) / ptexturewidth;
@@ -152,10 +162,10 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
case 2 : texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3 : colortemp = V_GetColor(texel);
case 3 : colortemp = palette[texel];
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4 : colortemp = V_GetColor(texel);
case 4 : colortemp = palette[texel];
colortemp.s.alpha = alpha;
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
@@ -329,6 +339,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
INT32 i;
boolean skyspecial = false; //poor hack for Legacy large skies..
RGBA_t *palette;
palette = HWR_GetTexturePalette();
texture = textures[texnum];
@@ -349,7 +362,12 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
HWR_ResizeBlock (texture->width, texture->height, &grtex->mipmap.grInfo);
grtex->mipmap.width = (UINT16)blockwidth;
grtex->mipmap.height = (UINT16)blockheight;
grtex->mipmap.grInfo.format = textureformat;
//grtex->mipmap.grInfo.format = textureformat;
if (skyspecial)
grtex->mipmap.grInfo.format = GR_RGBA; // that skyspecial code below assumes this format ...
else
grtex->mipmap.grInfo.format = textureformat;
grtex->mipmap.colormap = colormaps;
@@ -365,7 +383,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
INT32 j;
RGBA_t col;
col = V_GetColor(HWR_CHROMAKEY_EQUIVALENTCOLORINDEX);
col = palette[HWR_CHROMAKEY_EQUIVALENTCOLORINDEX];
for (j = 0; j < blockheight; j++)
{
for (i = 0; i < blockwidth; i++)
@@ -388,7 +406,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
texture->width, texture->height,
patch->originx, patch->originy,
realpatch,
format2bpp[grtex->mipmap.grInfo.format]);
format2bpp[grtex->mipmap.grInfo.format], palette);
Z_Unlock(realpatch);
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
@@ -412,6 +430,8 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap)
{
INT32 newwidth, newheight;
RGBA_t *palette = HWR_GetTexturePalette();
// don't do it twice (like a cache)
if (grMipmap->width == 0)
@@ -456,7 +476,7 @@ void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, bo
grPatch->width, grPatch->height,
0, 0,
patch,
format2bpp[grMipmap->grInfo.format]);
format2bpp[grMipmap->grInfo.format], palette);
}
grPatch->max_s = (float)newwidth / (float)blockwidth;
@@ -557,25 +577,6 @@ void HWR_PrepLevelCache(size_t pnumtextures)
I_Error("HWR_PrepLevelCache: can't alloc gr_textures");
}
void HWR_SetPalette(RGBA_t *palette)
{
//Hudler: 16/10/99: added for OpenGL gamma correction
RGBA_t gamma_correction = {0x7F7F7F7F};
//Hurdler 16/10/99: added for OpenGL gamma correction
gamma_correction.s.red = (UINT8)cv_grgammared.value;
gamma_correction.s.green = (UINT8)cv_grgammagreen.value;
gamma_correction.s.blue = (UINT8)cv_grgammablue.value;
HWD.pfnSetPalette(palette, &gamma_correction);
// hardware driver will flush there own cache if cache is non paletized
// now flush data texture cache so 32 bit texture are recomputed
if (patchformat == GR_RGBA || textureformat == GR_RGBA)
{
Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE);
Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED);
}
}
// --------------------------------------------------------------------------
// Make sure texture is downloaded and set it as the source
// --------------------------------------------------------------------------
@@ -821,6 +822,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
UINT8 *flat;
UINT8 *dest, *src, texel;
RGBA_t col;
RGBA_t *palette = HWR_GetTexturePalette();
// Place the flats data into flat
W_ReadLump(fademasklumpnum, Z_Malloc(W_LumpLength(fademasklumpnum),
@@ -838,7 +840,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
{
// fademask bpp is always 1, and is used just for alpha
texel = src[(posx)>>FRACBITS];
col = V_GetColor(texel);
col = palette[texel];
*dest = col.s.red; // take the red level of the colour and use it for alpha, as fademasks do
dest++;
@@ -914,4 +916,192 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
}
// =================================================
// PALETTE HANDLING
// =================================================
void HWR_SetPalette(RGBA_t *palette)
{
if (HWR_ShouldUsePaletteRendering())
{
// set the palette for palette postprocessing
if (cv_grpalettedepth.value == 16)
{
// crush to 16-bit rgb565, like software currently does in the standard configuration
// Note: Software's screenshots have the 24-bit palette, but the screen gets
// the 16-bit version! For making comparison screenshots either use an external screenshot
// tool or set the palette depth to 24 bits.
RGBA_t crushed_palette[256];
int i;
for (i = 0; i < 256; i++)
{
float fred = (float)(palette[i].s.red >> 3);
float fgreen = (float)(palette[i].s.green >> 2);
float fblue = (float)(palette[i].s.blue >> 3);
crushed_palette[i].s.red = (UINT8)(fred / 31.0f * 255.0f);
crushed_palette[i].s.green = (UINT8)(fgreen / 63.0f * 255.0f);
crushed_palette[i].s.blue = (UINT8)(fblue / 31.0f * 255.0f);
crushed_palette[i].s.alpha = 255;
}
HWD.pfnSetScreenPalette(crushed_palette);
}
else
{
HWD.pfnSetScreenPalette(palette);
}
// this part is responsible for keeping track of the palette OUTSIDE of a level.
if ((!(gamestate == GS_LEVEL)) || (gamestate == GS_TITLESCREEN))
HWR_SetMapPalette();
}
else
{
// set the palette for the textures
HWD.pfnSetTexturePalette(palette);
// reset mapPalette so next call to HWR_SetMapPalette will update everything correctly
memset(mapPalette, 0, sizeof(mapPalette));
// hardware driver will flush there own cache if cache is non paletized
// now flush data texture cache so 32 bit texture are recomputed
//if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA)
if (patchformat == GR_RGBA || textureformat == GR_RGBA)
{
Z_FreeTag(PU_HWRCACHE);
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
}
}
}
static void HWR_SetPaletteLookup(RGBA_t *palette)
{
int r, g, b;
UINT8 *lut = Z_Malloc(
HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE*sizeof(UINT8),
PU_STATIC, NULL);
#define STEP_SIZE (256/HWR_PALETTE_LUT_SIZE)
for (b = 0; b < HWR_PALETTE_LUT_SIZE; b++)
{
for (g = 0; g < HWR_PALETTE_LUT_SIZE; g++)
{
for (r = 0; r < HWR_PALETTE_LUT_SIZE; r++)
{
lut[b*HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE+g*HWR_PALETTE_LUT_SIZE+r] =
NearestPaletteColor(r*STEP_SIZE, g*STEP_SIZE, b*STEP_SIZE, palette);
}
}
}
#undef STEP_SIZE
HWD.pfnSetPaletteLookup(lut);
Z_Free(lut);
}
// Updates mapPalette to reflect the loaded level or other game state.
// Textures are flushed if needed.
// Call this function only in palette rendering mode.
void HWR_SetMapPalette(void)
{
RGBA_t RGBA_converted[256];
RGBA_t *palette;
int i;
if ((!(gamestate == GS_LEVEL)) || (gamestate == GS_TITLESCREEN))
{
// outside of a level, pMasterPalette should have PLAYPAL ready for us
//palette = pMasterPalette; // we dont have this in kart so just use pLocalPalette as before
palette = pLocalPalette;
}
else
{
// in a level pLocalPalette might have a flash palette, but we
// want the map's original palette.
lumpnum_t lumpnum = W_GetNumForName(GetPalette());
size_t palsize = W_LumpLength(lumpnum);
UINT8 *RGB_data;
if (palsize < 768) // 256 * 3
I_Error("HWR_SetMapPalette: A programmer assumed palette lumps are at least 768 bytes long, but apparently this was a wrong assumption!\n");
RGB_data = W_CacheLumpNum(lumpnum, PU_CACHE);
// we got the RGB palette now, but we need it in RGBA format.
for (i = 0; i < 256; i++)
{
RGBA_converted[i].s.red = *(RGB_data++);
RGBA_converted[i].s.green = *(RGB_data++);
RGBA_converted[i].s.blue = *(RGB_data++);
RGBA_converted[i].s.alpha = 255;
}
palette = RGBA_converted;
}
// check if the palette has changed from the previous one
if (memcmp(mapPalette, palette, sizeof(mapPalette)))
{
memcpy(mapPalette, palette, sizeof(mapPalette));
// in palette rendering mode, this means that all rgba textures now have wrong colors
// and the lookup table is outdated
HWR_SetPaletteLookup(mapPalette);
HWD.pfnSetTexturePalette(mapPalette);
//if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA)
if (patchformat == GR_RGBA || textureformat == GR_RGBA)
{
Z_FreeTag(PU_HWRCACHE);
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
}
}
}
// Creates a hardware lighttable from the supplied lighttable.
// Returns the id of the hw lighttable, usable in FSurfaceInfo.
UINT32 HWR_CreateLightTable(UINT8 *lighttable)
{
UINT32 i, id;
RGBA_t *palette = HWR_GetTexturePalette();
RGBA_t *hw_lighttable = Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_STATIC, NULL);
// To make the palette index -> RGBA mapping easier for the shader,
// the hardware lighttable is composed of RGBA colors instead of palette indices.
for (i = 0; i < 256 * 32; i++)
hw_lighttable[i] = palette[lighttable[i]];
id = HWD.pfnCreateLightTable(hw_lighttable);
Z_Free(hw_lighttable);
return id;
}
// get hwr lighttable id for colormap, create it if it doesn't already exist
UINT32 HWR_GetLightTableID(extracolormap_t *colormap)
{
boolean default_colormap = false;
if (!colormap)
{
colormap = &extra_colormaps[num_extra_colormaps]; // a place to store the hw lighttable id
// alternatively could just store the id in a global variable if there are issues
default_colormap = true;
}
// create hw lighttable if there isn't one
if (!colormap->gl_lighttable_id)
{
UINT8 *colormap_pointer;
if (default_colormap)
colormap_pointer = colormaps; // don't actually use the data from the "default colormap"
else
colormap_pointer = colormap->colormap;
colormap->gl_lighttable_id = HWR_CreateLightTable(colormap_pointer);
}
return colormap->gl_lighttable_id;
}
// Note: all hardware lighttable ids assigned before this
// call become invalid and must not be used.
void HWR_ClearLightTables(void)
{
//if (vid.glstate == VID_GL_LIBRARY_LOADED) // we have pfnInit which is essentially the same, but it doesent work here for whatever reason, since this should not be done in software renderer ever!
if (rendermode == render_opengl)
HWD.pfnClearLightTables();
}
#endif //HWRENDER
+6 -1
View File
@@ -25,6 +25,12 @@
#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
#define FAR_ZCLIP_DEFAULT 32768.0f
// The width/height/depth of the palette lookup table used by palette rendering.
// Changing this also requires changing the shader code!
// Also assumed to be a power of two in some parts of the code.
// 64 seems to work perfectly for the vanilla palette.
#define HWR_PALETTE_LUT_SIZE 64
// ==========================================================================
// SIMPLE TYPES
// ==========================================================================
@@ -234,7 +240,6 @@ typedef struct FSurfaceInfo FSurfaceInfo;
enum hwdsetspecialstate
{
HWD_SET_SHADERS,
HWD_PAL_SHADER,
HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE,
+17 -12
View File
@@ -567,12 +567,13 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
}
else // Do TRANSMAP** fade.
{
if (HWR_ShouldUsePaletteRendering())
Surf.PolyColor.rgba = pLocalPalette[color&0xFF].rgba;
else
Surf.PolyColor.rgba = pLocalPalette[color].rgba;
RGBA_t *palette = HWR_GetTexturePalette();
Surf.PolyColor.rgba = palette[color&0xFF].rgba;
Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f);
if (HWR_ShouldUsePaletteRendering())
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
else
Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f);
}
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest, false);
@@ -748,9 +749,10 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
{
F2DCoord v1, v2;
RGBA_t color_rgba;
color_rgba = V_GetColor(color);
RGBA_t *palette = HWR_GetTexturePalette();
color_rgba = palette[color&0xFF];
v1.x = ((float)fl->a.x-(vid.width/2.0f))*(2.0f/vid.width);
v1.y = ((float)fl->a.y-(vid.height/2.0f))*(2.0f/vid.height);
@@ -768,6 +770,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh, fwait = 0;
RGBA_t *palette = HWR_GetTexturePalette();
if (wh < 0)
return; // consistency w/ software
@@ -848,7 +851,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
Surf.PolyColor = V_GetColor(color);
Surf.PolyColor = palette[color&0xFF];
HWD.pfnDrawPolygon(&Surf, v, 4,
PF_Modulated|PF_NoTexture|PF_NoDepthTest, false);
@@ -862,6 +865,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh;
RGBA_t *palette = HWR_GetTexturePalette();
if (w < 0 || h < 0)
return; // consistency w/ software
@@ -882,7 +886,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
RGBA_t rgbaColour = palette[color&0xFF];
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
@@ -972,6 +976,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
FSurfaceInfo Surf;
float fx, fy, fw, fh;
UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT);
RGBA_t *palette = HWR_GetTexturePalette();
if (w < 0 || h < 0)
return; // consistency w/ software
@@ -992,7 +997,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
RGBA_t rgbaColour = palette[color&0xFF];
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
@@ -1066,7 +1071,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
Surf.PolyColor = V_GetColor(color);
Surf.PolyColor = palette[color&0xFF];
if (alphalevel)
{
+10 -12
View File
@@ -29,11 +29,7 @@
EXPORT boolean HWRAPI(Init) (void);
EXPORT void HWRAPI(SetupGLInfo) (void);
#if defined (PURESDL) || defined (macintosh)
EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma);
#else
EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma);
#endif
EXPORT void HWRAPI(SetTexturePalette) (RGBA_t *ppal);
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, boolean horizonSpecial);
@@ -84,9 +80,10 @@ EXPORT boolean HWRAPI(InitCustomShaders) (void);
EXPORT void HWRAPI(StartBatching) (void);
EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, int *sNumPolys, int *sNumVerts, int *sNumCalls, int *sNumShaders, int *sNumTextures, int *sNumPolyFlags, int *sNumColors);
EXPORT void HWRAPI(InitPalette) (int flashnum, boolean skiplut);
EXPORT UINT32 HWRAPI(AddLightTable) (UINT8 *lighttable);
EXPORT void HWRAPI(ClearLightTableCache) (void);
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut);
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable);
EXPORT void HWRAPI(ClearLightTables)(void);
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette);
// ==========================================================================
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
@@ -98,7 +95,7 @@ struct hwdriver_s
{
Init pfnInit;
SetupGLInfo pfnSetupGLInfo;
SetPalette pfnSetPalette;
SetTexturePalette pfnSetTexturePalette;
FinishUpdate pfnFinishUpdate;
Draw2DLine pfnDraw2DLine;
DrawPolygon pfnDrawPolygon;
@@ -139,9 +136,10 @@ struct hwdriver_s
StartBatching pfnStartBatching;
RenderBatches pfnRenderBatches;
InitPalette pfnInitPalette;
AddLightTable pfnAddLightTable;
ClearLightTableCache pfnClearLightTableCache;
SetPaletteLookup pfnSetPaletteLookup;
CreateLightTable pfnCreateLightTable;
ClearLightTables pfnClearLightTables;
SetScreenPalette pfnSetScreenPalette;
};
extern struct hwdriver_s hwdriver;
+5
View File
@@ -68,6 +68,11 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap);
void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
void HWR_SetPalette(RGBA_t *palette);
void HWR_SetMapPalette(void);
UINT32 HWR_CreateLightTable(UINT8 *lighttable);
UINT32 HWR_GetLightTableID(extracolormap_t *colormap);
void HWR_ClearLightTables(void);
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
+77 -69
View File
@@ -57,6 +57,12 @@
// ==========================================================================
struct hwdriver_s hwdriver;
boolean gr_shadersavailable = true;
// Whether the internal state is set to palette rendering or not.
static boolean gr_palette_rendering_state = false;
// ==========================================================================
// Commands and console variables
// ==========================================================================
@@ -66,15 +72,8 @@ static void CV_anisotropic_ONChange(void);
static void CV_screentextures_ONChange(void);
static void CV_useCustomShaders_ONChange(void);
static void CV_grshaders_OnChange(void);
static void CV_Gammaxxx_ONChange(void);
static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
consvar_t cv_grgammared = {"gr_gammared", "127", CV_SAVE|CV_CALL, grgamma_cons_t,
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grgammagreen = {"gr_gammagreen", "127", CV_SAVE|CV_CALL, grgamma_cons_t,
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grgammablue = {"gr_gammablue", "127", CV_SAVE|CV_CALL, grgamma_cons_t,
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
static void CV_grpaletterendering_OnChange(void);
static void CV_grpalettedepth_OnChange(void);
static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "Standard"}, {2, "Smooth"}, {0, NULL}};
@@ -146,7 +145,10 @@ consvar_t cv_grscreentextures = {"gr_screentextures", "On", CV_CALL|CV_SAVE, CV_
consvar_t cv_grshaders = {"gr_shaders", "On", CV_CALL|CV_SAVE, CV_OnOff, CV_grshaders_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grusecustomshaders = {"gr_usecustomshaders", "Yes", CV_CALL|CV_SAVE, CV_OnOff, CV_useCustomShaders_ONChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grpaletteshader = {"gr_paletteshader", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_grshaders_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grpaletterendering = {"gr_paletteshader", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_grpaletterendering_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}};
consvar_t cv_grpalettedepth = {"gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_grpalettedepth_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grflashpal = {"gr_flashpal", "On", CV_CALL|CV_SAVE, CV_OnOff, CV_grshaders_OnChange, 0, NULL, NULL, 0, 0, NULL};
@@ -179,42 +181,36 @@ static void CV_screentextures_ONChange(void)
static void CV_grshaders_OnChange(void)
{
if (rendermode == render_opengl)
if ((rendermode == render_opengl) && (cv_grpaletterendering.value))
{
if (HWR_ShouldUsePaletteRendering())
HWR_InitPalette(0, false);
HWD.pfnSetSpecialState(HWD_PAL_SHADER, HWR_ShouldUsePaletteRendering());
V_SetPalette(0);
// can't do palette rendering without shaders, so update the state if needed
HWR_TogglePaletteRendering();
}
}
static void CV_useCustomShaders_ONChange(void)
static void CV_useCustomShaders_ONChange(void) // should we do a call to HWR_TogglePaletteRendering here aswell in pal rendering mode?
{
if (rendermode == render_opengl)
{
if (HWR_UseShader())
HWD.pfnInitCustomShaders();
if (HWR_ShouldUsePaletteRendering())
HWR_InitPalette(0, false);
}
}
// change the palette directly to see the change
static void CV_Gammaxxx_ONChange(void)
static void CV_grpaletterendering_OnChange(void)
{
if (rendermode == render_opengl)
V_SetPalette(0);
if ((rendermode == render_opengl) && (gr_shadersavailable))
{
HWR_TogglePaletteRendering();
}
}
void HWR_InitPalette(int flashnum, boolean skiplut)
static void CV_grpalettedepth_OnChange(void)
{
HWD.pfnInitPalette(flashnum, skiplut);
if ((rendermode == render_opengl) && (HWR_ShouldUsePaletteRendering()))
HWR_SetPalette(pLocalPalette);
}
// ==========================================================================
// Globals
// ==========================================================================
@@ -246,8 +242,6 @@ static sector_t *gr_backsector;
static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags);
boolean gr_shadersavailable = true;
// Performance stats
ps_metric_t ps_hw_nodesorttime = {0};
ps_metric_t ps_hw_nodedrawtime = {0};
@@ -445,18 +439,17 @@ boolean HWR_UseShader(void)
boolean HWR_ShouldUsePaletteRendering(void)
{
return (cv_grpaletteshader.value && HWR_UseShader());
return (cv_grpaletterendering.value && HWR_UseShader());
}
boolean HWR_PalRenderFlashpal(void)
{
return (cv_grpaletteshader.value && HWR_UseShader() && cv_grflashpal.value);
return (cv_grpaletterendering.value && HWR_UseShader() && cv_grflashpal.value);
}
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap)
{
RGBA_t poly_color, tint_color, fade_color;
boolean default_colormap = false;
poly_color.rgba = 0xFFFFFFFF;
tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : GL_DEFAULTMIX;
@@ -510,35 +503,9 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
if (HWR_ShouldUsePaletteRendering())
{
if (!colormap)
{
colormap = &extra_colormaps[num_extra_colormaps];
default_colormap = true;
}
if (!colormap->gl_lighttable_id)
{
UINT8 *colormap_pointer;
if (default_colormap)
{
colormap_pointer = colormaps;
}
else
{
colormap_pointer = colormap->colormap;
}
colormap->gl_lighttable_id = HWD.pfnAddLightTable(colormap_pointer);
}
Surface->LightTableId = colormap->gl_lighttable_id;
}
}
void HWR_ClearLightTableCache(void)
{
if (rendermode == render_opengl)
HWD.pfnClearLightTableCache();
Surface->LightTableId = HWR_GetLightTableID(colormap);
else
Surface->LightTableId = 0;
}
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
@@ -6342,8 +6309,50 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
HWR_RenderFrame(viewnumber, player, false);
}
// enable or disable palette rendering state depending on settings and availability
// called when relevant settings change
// shader recompilation is done in the cvar callback
void HWR_TogglePaletteRendering(void)
{
// which state should we go to?
if (HWR_ShouldUsePaletteRendering())
{
// are we not in that state already?
if (!gr_palette_rendering_state)
{
gr_palette_rendering_state = true;
// The textures will still be converted to RGBA by r_opengl.
// This however makes hw_cache use paletted blending for composite textures!
// (patchformat is not touched)
textureformat = GR_TEXFMT_P_8;
HWR_SetMapPalette();
HWR_SetPalette(pLocalPalette);
// If the r_opengl "texture palette" stays the same during this switch, these textures
// will not be cleared out. However they are still out of date since the
// composite texture blending method has changed. Therefore they need to be cleared.
//HWD.pfnClearMipMapCache();
HWR_PrepLevelCache(numtextures);
}
}
else
{
// are we not in that state already?
if (gr_palette_rendering_state)
{
gr_palette_rendering_state = false;
textureformat = GR_RGBA;
HWR_SetPalette(pLocalPalette);
// If the r_opengl "texture palette" stays the same during this switch, these textures
// will not be cleared out. However they are still out of date since the
// composite texture blending method has changed. Therefore they need to be cleared.
//HWD.pfnClearMipMapCache();
HWR_PrepLevelCache(numtextures);
}
}
}
//added by Hurdler: console varibale that are saved
void HWR_AddCommands(void)
@@ -6364,9 +6373,6 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_grrenderdistance);
CV_RegisterVar(&cv_grgammablue);
CV_RegisterVar(&cv_grgammagreen);
CV_RegisterVar(&cv_grgammared);
CV_RegisterVar(&cv_grfakecontrast);
CV_RegisterVar(&cv_grslopecontrast);
@@ -6389,7 +6395,8 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_secbright);
CV_RegisterVar(&cv_grpaletteshader);
CV_RegisterVar(&cv_grpaletterendering);
CV_RegisterVar(&cv_grpalettedepth);
CV_RegisterVar(&cv_grflashpal);
}
@@ -6404,21 +6411,22 @@ void HWR_Startup(void)
if (!startupdone)
{
CONS_Printf("HWR_Startup()...\n");
textureformat = patchformat = GR_RGBA;
HWR_InitTextureCache();
HWR_InitMD2();
HWD.pfnSetupGLInfo();
}
if (rendermode == render_opengl)
textureformat = patchformat = GR_RGBA;
startupdone = true;
// jimita
HWD.pfnKillShaders();
if (!HWD.pfnLoadShaders())
gr_shadersavailable = false;
HWR_TogglePaletteRendering();
if (msaa)
{
+5 -8
View File
@@ -92,6 +92,7 @@ void HWR_ClearClipper(void);
boolean HWR_UseShader(void);
boolean HWR_ShouldUsePaletteRendering(void);
boolean HWR_PalRenderFlashpal(void);
void HWR_TogglePaletteRendering(void);
// My original intention was to split hw_main.c
// into files like hw_bsp.c, hw_sprites.c...
@@ -114,7 +115,6 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(int width, int height);
void HWR_InitPalette(int flashnum, boolean skiplut);
// hw_main.c: Planes
void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
@@ -148,8 +148,6 @@ void HWR_AddLine(seg_t *line);
boolean HWR_CheckBBox(fixed_t *bspcoord);
void HWR_RenderDrawNodes(void);
void HWR_ClearLightTableCache(void);
// hw_main.c: Sprites
void HWR_AddSprites(sector_t *sec);
void HWR_ProjectSprite(mobj_t *thing);
@@ -162,6 +160,7 @@ extern boolean gr_maphasportals;
// hw_cache.c
void HWR_PrepLevelCache(size_t pnumtextures);
RGBA_t *HWR_GetTexturePalette(void);
// hw_trick.c
void HWR_CorrectSWTricks(void);
@@ -177,9 +176,6 @@ extern consvar_t cv_grfov;
extern consvar_t cv_grmdls;
extern consvar_t cv_grfog;
extern consvar_t cv_grfogdensity;
extern consvar_t cv_grgammared;
extern consvar_t cv_grgammagreen;
extern consvar_t cv_grgammablue;
extern consvar_t cv_grfiltermode;
extern consvar_t cv_granisotropicmode;
extern consvar_t cv_grcorrecttricks;
@@ -192,9 +188,10 @@ extern consvar_t cv_grfallbackplayermodel;
extern consvar_t cv_grbatching;
extern consvar_t cv_grrenderdistance;
extern consvar_t cv_grusecustomshaders;
extern consvar_t cv_grpaletteshader;
extern consvar_t cv_grscreentextures;
extern consvar_t cv_grpaletterendering;
extern consvar_t cv_grpalettedepth;
extern consvar_t cv_grflashpal;
extern consvar_t cv_grscreentextures;
extern consvar_t cv_grportals;
extern consvar_t cv_nostencil;
extern consvar_t cv_secbright;
+4 -4
View File
@@ -564,15 +564,15 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl)
// : in OpenGL, we store values for conversion of paletted graphics when
// : they are downloaded to the 3D card.
// -----------------+
EXPORT void HWRAPI(SetPalette) (RGBA_t *pal, RGBA_t *gamma)
EXPORT void HWRAPI(SetPalette) (RGBA_t *pal)
{
INT32 i;
for (i = 0; i < 256; i++)
{
myPaletteData[i].s.red = (UINT8)MIN((pal[i].s.red*gamma->s.red)/127, 255);
myPaletteData[i].s.green = (UINT8)MIN((pal[i].s.green*gamma->s.green)/127, 255);
myPaletteData[i].s.blue = (UINT8)MIN((pal[i].s.blue*gamma->s.blue)/127, 255);
myPaletteData[i].s.red = pal[i].s.red;
myPaletteData[i].s.green = pal[i].s.green;
myPaletteData[i].s.blue = pal[i].s.blue;
myPaletteData[i].s.alpha = pal[i].s.alpha;
}
+193 -289
View File
@@ -27,9 +27,6 @@
#include "r_opengl.h"
#include "r_vbo.h"
#include "../../v_video.h" // pLocalPalette
#include "../../r_data.h" // NearestColor
//#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime)
#include "../../i_system.h" // for I_GetPreciseTime (batching time measurements)
@@ -51,13 +48,19 @@ struct GLRGBAFloat
};
typedef struct GLRGBAFloat GLRGBAFloat;
static const GLubyte white[4] = { 255, 255, 255, 255 };
// lighttable list item
struct LTListItem
{
UINT32 id;
struct LTListItem *next;
};
typedef struct LTListItem LTListItem;
// ==========================================================================
// CONSTANTS
// ==========================================================================
static const GLubyte white[4] = { 255, 255, 255, 255 };
// With OpenGL 1.1+, the first texture should be 1
#define NOTEXTURE_NUM 0
@@ -74,24 +77,26 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE;
// GLOBALS
// **************************************************************************
static GLuint tex_downloaded = 0;
// these didnt work with karts batching system, hope this is not an issue
//static GLuint lt_downloaded = 0; // currently bound lighttable texture - currentSurfaceInfo
//static GLuint lt_downloaded2 = 0; // currently bound lighttable texture - nextSurfaceInfo
//static GLuint lt_downloaded3 = 0; // currently bound lighttable texture - pSurf
static GLfloat fov = 90.0f;
static FBITFIELD CurrentPolyFlags;
static FTextureInfo *gr_cachetail = NULL;
static FTextureInfo *gr_cachehead = NULL;
typedef struct LightTableCacheEntry_s
{
GLuint id;
struct LightTableCacheEntry_s *next;
} LightTableCacheEntry_t;
// Linked list of all lighttables.
static LTListItem *LightTablesTail = NULL;
static LTListItem *LightTablesHead = NULL;
LightTableCacheEntry_t *ltcachehead = NULL;
LightTableCacheEntry_t *ltcachetail = NULL;
static RGBA_t screenPalette[256] = {0}; // the palette for the postprocessing step in palette rendering
static GLuint screenPaletteTex = 0; // 1D texture containing the screen palette
static GLuint paletteLookupTex = 0; // 3D texture containing RGB -> palette index lookup table
RGBA_t myPaletteData[256]; // the palette for converting textures to RGBA
RGBA_t myPaletteData[256];
GLint screen_width = 0; // used by Draw2DLine()
GLint screen_height = 0;
GLbyte screen_depth = 0;
@@ -198,7 +203,6 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...)
#endif
}
// -----------------+
// GL_MSG_Warning : Raises a warning.
// :
@@ -250,7 +254,6 @@ static void GL_MSG_Error(const char *format, ...)
#endif
}
#ifdef STATIC_OPENGL
/* 1.0 functions */
/* Miscellaneous */
@@ -429,10 +432,10 @@ typedef void (APIENTRY * PFNglTexEnvi) (GLenum target, GLenum pname, GLint param
static PFNglTexEnvi pglTexEnvi;
typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint param);
static PFNglTexParameteri pglTexParameteri;
typedef void (APIENTRY * PFNglTexImage1D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexImage1D pglTexImage1D;
typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexImage2D pglTexImage2D;
typedef void (APIENTRY * PFNglTexImage3D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexImage3D pglTexImage3D;
typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexSubImage2D pglTexSubImage2D;
@@ -461,6 +464,10 @@ typedef void (APIENTRY * PFNglGenerateMipmap) (GLenum target);
static PFNglGenerateMipmap pglGenerateMipmap;
#endif
/* 1.2 functions for 3D textures */
typedef void (APIENTRY * PFNglTexImage3D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexImage3D pglTexImage3D;
/* 1.3 functions for multitexturing */
typedef void (APIENTRY *PFNglActiveTexture) (GLenum);
static PFNglActiveTexture pglActiveTexture;
@@ -560,6 +567,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglTexEnvi, glTexEnvi)
GETOPENGLFUNC(pglTexParameteri, glTexParameteri)
GETOPENGLFUNC(pglTexImage1D, glTexImage1D)
GETOPENGLFUNC(pglTexImage2D, glTexImage2D)
GETOPENGLFUNC(pglTexSubImage2D , glTexSubImage2D)
@@ -594,7 +602,6 @@ typedef void (APIENTRY *PFNglLinkProgram) (GLuint);
typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*);
typedef void (APIENTRY *PFNglUseProgram) (GLuint);
typedef void (APIENTRY *PFNglUniform1i) (GLint, GLint);
typedef void (APIENTRY *PFNglUniform1iv) (GLint, GLsizei, const GLint*);
typedef void (APIENTRY *PFNglUniform1f) (GLint, GLfloat);
typedef void (APIENTRY *PFNglUniform2f) (GLint, GLfloat, GLfloat);
typedef void (APIENTRY *PFNglUniform3f) (GLint, GLfloat, GLfloat, GLfloat);
@@ -616,7 +623,6 @@ static PFNglLinkProgram pglLinkProgram;
static PFNglGetProgramiv pglGetProgramiv;
static PFNglUseProgram pglUseProgram;
static PFNglUniform1i pglUniform1i;
static PFNglUniform1iv pglUniform1iv;
static PFNglUniform1f pglUniform1f;
static PFNglUniform2f pglUniform2f;
static PFNglUniform3f pglUniform3f;
@@ -640,10 +646,6 @@ static boolean gl_shaderprogramchanged = true;
static boolean gl_batching = false;// are we currently collecting batches?
static GLint gl_palette[768];
boolean gl_palette_initialized = false;
static boolean gl_palshader = false;
static INT32 gl_enable_screen_textures = 1;
static GLint gl_portal_stencil_level = 0;
@@ -662,10 +664,10 @@ typedef enum
gluniform_fade_end,
// palette rendering
gluniform_palette,
gluniform_color_lookup,
gluniform_lighttable_tex,
gluniform_palette_tex, // 1d texture containing a palette
gluniform_palette_lookup_tex, // 3d texture containing the rgb->index lookup table
gluniform_lighttable_tex, // 2d texture containing a light table
// misc.
gluniform_leveltime,
@@ -709,7 +711,8 @@ static float shader_leveltime = 0;
"float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \
"float startmap = (15.0 - lightnum) * 4.0;\n" \
"float scale = 160.0 / (lightz + 1.0);\n" \
"return (startmap * STARTMAP_FUDGE - scale * MULT_FUDGE * SCALE_FUDGE);\n" \
"float cap = (155.0 - light) * 0.26;\n" \
"return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
"}\n"
#define GLSL_DOOM_LIGHT_EQUATION \
@@ -759,15 +762,15 @@ static float shader_leveltime = 0;
"gl_FragColor = final_color;\n" \
"}\n"
// hand tuned adjustments for light level calculation
// do those even work correctly without the preprocessor?
#define GLSL_FLOOR_FUDGES \
"#define STARTMAP_FUDGE 1.06\n" \
"#define MULT_FUDGE 0.5\n" \
"#define SCALE_FUDGE 1.15\n"
#define GLSL_WALL_FUDGES \
"#define STARTMAP_FUDGE 1.05\n" \
"#define MULT_FUDGE 1.0\n" \
"#define SCALE_FUDGE 1.1\n"
"#define SCALE_FUDGE 2.2\n"
#define GLSL_SOFTWARE_FRAGMENT_SHADER_FLOORS \
GLSL_SOFTWARE_UNIFORMS \
@@ -787,21 +790,19 @@ static float shader_leveltime = 0;
#define GLSL_SOFTWARE_PAL_UNIFORMS \
"uniform sampler2D tex;\n" \
"uniform sampler3D palette_lookup_tex;\n" \
"uniform sampler2D lighttable_tex;\n" \
"uniform sampler3D lookup_tex;\n" \
"uniform int palette[768];\n" \
"uniform vec4 poly_color;\n" \
"uniform float lighting;\n" \
#define GLSL_SOFTWARE_PAL_MAIN \
"void main(void) {\n" \
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
"int tex_pal_idx = int(texture3D(lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0);\n" \
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
"int light_y = int(clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0));\n" \
"vec2 lighttable_coord = vec2((float(tex_pal_idx) + 0.5) / 256.0, (float(light_y) + 0.5) / 32.0);\n" \
"int final_idx = int(texture2D(lighttable_tex, lighttable_coord)[0] * 255.0);\n" \
"vec4 final_color = vec4(float(palette[final_idx*3])/255.0, float(palette[final_idx*3+1])/255.0, float(palette[final_idx*3+2])/255.0, 1.0);\n" \
"float light_y = clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0);\n" \
"vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (light_y + 0.5) / 32.0);\n" \
"vec4 final_color = texture2D(lighttable_tex, lighttable_coord);\n" \
"final_color.a = texel.a * poly_color.a;\n" \
"gl_FragColor = final_color;\n" \
"}\n"
@@ -856,7 +857,8 @@ static float shader_leveltime = 0;
"final_color.a = texel.a * poly_color.a;\n" \
"gl_FragColor = final_color;\n" \
"}\0"
//TODO: make this not a hacky copy of two shaders mixed together
#define GLSL_PALETTE_WATER_FRAGMENT_SHADER \
GLSL_FLOOR_FUDGES \
"const float freq = 0.025;\n" \
@@ -864,9 +866,8 @@ static float shader_leveltime = 0;
"const float speed = 2.0;\n" \
"const float pi = 3.14159;\n" \
"uniform sampler2D tex;\n" \
"uniform sampler3D palette_lookup_tex;\n" \
"uniform sampler2D lighttable_tex;\n" \
"uniform sampler3D lookup_tex;\n" \
"uniform int palette[768];\n" \
"uniform vec4 poly_color;\n" \
"uniform float lighting;\n" \
"uniform float leveltime;\n" \
@@ -877,16 +878,15 @@ static float shader_leveltime = 0;
"float sdistort = sin(a) * amp;\n" \
"float cdistort = cos(a) * amp;\n" \
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n" \
"int tex_pal_idx = int(texture3D(lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0);\n" \
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
"int light_y = int(clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0));\n" \
"vec2 lighttable_coord = vec2((float(tex_pal_idx) + 0.5) / 256.0, (float(light_y) + 0.5) / 32.0);\n" \
"int final_idx = int(texture2D(lighttable_tex, lighttable_coord)[0] * 255.0);\n" \
"vec4 final_color = vec4(float(palette[final_idx*3])/255.0, float(palette[final_idx*3+1])/255.0, float(palette[final_idx*3+2])/255.0, 1.0);\n" \
"float light_y = clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0);\n" \
"vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (light_y + 0.5) / 32.0);\n" \
"vec4 final_color = texture2D(lighttable_tex, lighttable_coord);\n" \
"final_color.a = texel.a * poly_color.a;\n" \
"gl_FragColor = final_color;\n" \
"}\0"
//
// Fog block shader
//
@@ -916,12 +916,14 @@ static float shader_leveltime = 0;
#define GLSL_PALETTE_FRAGMENT_SHADER \
"uniform sampler2D tex;\n" \
"uniform sampler3D lookup_tex;\n" \
"uniform int palette[768];\n" \
"uniform sampler3D palette_lookup_tex;\n" \
"uniform sampler1D palette_tex;\n" \
"void main(void) {\n" \
"vec3 texel = vec3(texture2D(tex, gl_TexCoord[0].st));\n" \
"int pal_idx = int(texture3D(lookup_tex, vec3((63.0/64.0) * texel + 1.0 / 128.0))[0] * 255.0);\n" \
"gl_FragColor = vec4(float(palette[pal_idx*3])/255.0, float(palette[pal_idx*3+1])/255.0, float(palette[pal_idx*3+2])/255.0, 1.0);\n" \
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
"float palette_coord = (tex_pal_idx + 0.5) / 256.0;\n" \
"vec4 final_color = texture1D(palette_tex, palette_coord);\n" \
"gl_FragColor = final_color;\n" \
"}\0"
//
@@ -1019,8 +1021,14 @@ static const char *vertex_shaders[] = {
// Palette vertex shader
GLSL_DEFAULT_VERTEX_SHADER,
// Palette floor vertex shader
GLSL_DEFAULT_VERTEX_SHADER,
// Palette wall vertex shader
GLSL_DEFAULT_VERTEX_SHADER,
// Palette water vertex shader
GLSL_DEFAULT_VERTEX_SHADER,
NULL,
@@ -1030,7 +1038,9 @@ static const char *vertex_shaders[] = {
void SetupGLFunc4(void)
{
/* 1.2 funcs */
pglTexImage3D = GetGLFunc("glTexImage3D");
/* 1.3 funcs */
pglActiveTexture = GetGLFunc("glActiveTexture");
pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f");
pglClientActiveTexture = GetGLFunc("glClientActiveTexture");
@@ -1057,7 +1067,6 @@ void SetupGLFunc4(void)
pglGetProgramiv = GetGLFunc("glGetProgramiv");
pglUseProgram = GetGLFunc("glUseProgram");
pglUniform1i = GetGLFunc("glUniform1i");
pglUniform1iv = GetGLFunc("glUniform1iv");
pglUniform1f = GetGLFunc("glUniform1f");
pglUniform2f = GetGLFunc("glUniform2f");
pglUniform3f = GetGLFunc("glUniform3f");
@@ -1199,14 +1208,13 @@ EXPORT boolean HWRAPI(LoadShaders) (void)
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
// misc. (custom shaders)
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
// palette rendering
shader->uniforms[gluniform_palette] = GETUNI("palette");
shader->uniforms[gluniform_color_lookup] = GETUNI("lookup_tex");
shader->uniforms[gluniform_palette_tex] = GETUNI("palette_tex");
shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex");
shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex");
// misc.
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
#undef GETUNI
// set permanent uniform values
@@ -1214,22 +1222,18 @@ EXPORT boolean HWRAPI(LoadShaders) (void)
if (uniform != -1) \
function (uniform, a);
#define UNIFORM_2(uniform, a, b, function) \
if (uniform != -1) \
function (uniform, a, b);
pglUseProgram(shader->program);
// texture unit numbers for the samplers used for palette rendering
UNIFORM_2(shader->uniforms[gluniform_palette], 768, gl_palette, pglUniform1iv);
UNIFORM_1(shader->uniforms[gluniform_color_lookup], 1, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_palette_tex], 2, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_palette_lookup_tex], 1, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 2, pglUniform1i);
pglUseProgram(0);
// restore gl shader state
//pglUseProgram(gl_shaderstate.program);
pglUseProgram(gl_currentshaderprogram);
//pglUseProgram(0); // dont remember why this was here in the first place, but seems fine?
#undef UNIFORM_1
#undef UNIFORM_2
}
#endif
return true;
@@ -1334,130 +1338,6 @@ EXPORT void HWRAPI(KillShaders) (void)
// unused.........................
}
GLuint palette_tex_num;
// length of one side of lookup texture
// smallest separation between all the colors in the srb2 palette is 6, so
// possibly a 64x64x64 lookup texture might be enough for 100% correct colors
// (min separation for 64^3 size is 4)
#define LUT_SIZE 64
#define STEP_SIZE (256/LUT_SIZE)
// the +2 in the NearestColor call also needs to be adjusted if LUT_SIZE is changed!
// the hardcoded values in the shader also need to be adjusted if LUT_SIZE is changed!
EXPORT void HWRAPI(InitPalette) (int flashnum, boolean skiplut)
{
int i, r, g, b;
//Hudler: 16/10/99: added for OpenGL gamma correction
RGBA_t gamma_correction = {0x7F7F7F7F};
//Hurdler 16/10/99: added for OpenGL gamma correction
gamma_correction.s.red = (UINT8)cv_grgammared.value;
gamma_correction.s.green = (UINT8)cv_grgammagreen.value;
gamma_correction.s.blue = (UINT8)cv_grgammablue.value;
// init the palette
int flashoffset = flashnum*256;
for (i = 0+flashoffset; i < 256+flashoffset; i++)
{
int fi = i-flashoffset;
// gamma correction
int pr, pg, pb;
pr = (UINT8)MIN((pLocalPalette[i].s.red*gamma_correction.s.red)/127, 255);
pg = (UINT8)MIN((pLocalPalette[i].s.green*gamma_correction.s.green)/127, 255);
pb = (UINT8)MIN((pLocalPalette[i].s.blue*gamma_correction.s.blue)/127, 255);
// crush to 16-bit rgb565, like software currently does
float fred = (float)(pr >> 3);
float fgreen = (float)(pg >> 2);
float fblue = (float)(pb >> 3);
// restore to rgb888
gl_palette[fi*3] = (GLint)(fred / 31.0f * 255.0f);
gl_palette[fi*3+1] = (GLint)(fgreen / 63.0f * 255.0f);
gl_palette[fi*3+2] = (GLint)(fblue / 31.0f * 255.0f);
}
if (!skiplut)
{
GLenum internalFormat;
if (gl_version[0] == '1' || gl_version[0] == '2')
{
// if the OpenGL version is below 3.0, then the GL_R8 format may not be available.
// so use GL_LUMINANCE8 instead to get a single component 8-bit format
// (it is possible to have access to shaders even in some OpenGL 1.x systems,
// so palette rendering can still possibly be achieved there)
internalFormat = GL_LUMINANCE8;
}
else
{
internalFormat = GL_R8;
}
// init the palette conversion lookup texture
GLubyte *pal_lookup_tex = malloc(LUT_SIZE*LUT_SIZE*LUT_SIZE*sizeof(GLubyte));
if (!pal_lookup_tex)
I_Error("Failed to allocate memory for generating palette lookup texture.");
for (b = 0; b < LUT_SIZE; b++)
{
for (g = 0; g < LUT_SIZE; g++)
{
for (r = 0; r < LUT_SIZE; r++)
{
pal_lookup_tex[b*LUT_SIZE*LUT_SIZE+g*LUT_SIZE+r] = NearestColor(r*STEP_SIZE+0, g*STEP_SIZE+0, b*STEP_SIZE+0);
}
}
}
pglGenTextures(1, &palette_tex_num);
pglBindTexture(GL_TEXTURE_3D, palette_tex_num);
pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (!pglTexImage3D){
GL_MSG_Error("pglTexImage3D is NULL!");
CV_Set(&cv_grpaletteshader, "Off"); // turn that thing off if you cant use it
return;
}
pglTexImage3D(GL_TEXTURE_3D, 0, internalFormat, LUT_SIZE, LUT_SIZE, LUT_SIZE, 0, GL_RED, GL_UNSIGNED_BYTE, pal_lookup_tex);
free(pal_lookup_tex);
}
#undef STEP_SIZE
pglUseProgram(gl_shaderprograms[8].program);
pglUniform1i(gl_shaderprograms[8].uniforms[gluniform_color_lookup], 1); // bind sampler to second texture unit
pglUniform1iv(gl_shaderprograms[8].uniforms[gluniform_palette], 768, gl_palette);
// bind the palette to the fancy shader here
pglUseProgram(gl_shaderprograms[9].program);
pglUniform1iv(gl_shaderprograms[9].uniforms[gluniform_palette], 768, gl_palette);
// bind tex unit 2 to lighttable tex
pglUniform1i(gl_shaderprograms[9].uniforms[gluniform_lighttable_tex], 2);
pglUniform1i(gl_shaderprograms[9].uniforms[gluniform_color_lookup], 1);
// bind the palette to the fancy shader here
pglUseProgram(gl_shaderprograms[10].program);
pglUniform1iv(gl_shaderprograms[10].uniforms[gluniform_palette], 768, gl_palette);
// bind tex unit 2 to lighttable tex
pglUniform1i(gl_shaderprograms[10].uniforms[gluniform_lighttable_tex], 2);
pglUniform1i(gl_shaderprograms[10].uniforms[gluniform_color_lookup], 1);
// bind stuff to wöter shader
pglUseProgram(gl_shaderprograms[11].program);
pglUniform1iv(gl_shaderprograms[11].uniforms[gluniform_palette], 768, gl_palette);
pglUniform1i(gl_shaderprograms[11].uniforms[gluniform_lighttable_tex], 2);
pglUniform1i(gl_shaderprograms[11].uniforms[gluniform_color_lookup], 1);
pglUseProgram(0);
pglBindTexture(GL_TEXTURE_3D, 0);
// bind 3d lookup to unit 1, maybe it can stay there
pglActiveTexture(GL_TEXTURE1);
pglBindTexture(GL_TEXTURE_3D, palette_tex_num);
pglActiveTexture(GL_TEXTURE0);
gl_palette_initialized = true;
}
// -----------------+
// SetNoTexture : Disable texture
// -----------------+
@@ -1645,65 +1525,6 @@ EXPORT void HWRAPI(ClearMipMapCache) (void)
Flush();
}
EXPORT UINT32 HWRAPI(AddLightTable) (UINT8 *lighttable)
{
LightTableCacheEntry_t *cache_entry = malloc(sizeof(LightTableCacheEntry_t));
if (!ltcachetail)
{
ltcachehead = ltcachetail = cache_entry;
}
else
{
ltcachetail->next = cache_entry;
ltcachetail = cache_entry;
}
ltcachetail->next = NULL;
GLenum internalFormat;
if (gl_version[0] == '1' || gl_version[0] == '2')
{
// if the OpenGL version is below 3.0, then the GL_R8 format may not be available.
// so use GL_LUMINANCE8 instead to get a single component 8-bit format
// (it is possible to have access to shaders even in some OpenGL 1.x systems,
// so palette rendering can still possibly be achieved there)
internalFormat = GL_LUMINANCE8;
}
else
{
internalFormat = GL_R8;
}
pglGenTextures(1, &ltcachetail->id);
if (!ltcachetail->id){
GL_MSG_Error("HWR Lighttable cache entry id is zero");
CV_Set(&cv_grpaletteshader, "Off"); // turn that thing off if you cant use it
return;
}
pglBindTexture(GL_TEXTURE_2D, ltcachetail->id);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 256, 32, 0, GL_RED, GL_UNSIGNED_BYTE, lighttable);
// restore previously bound texture
if (!gl_batching)
pglBindTexture(GL_TEXTURE_2D, tex_downloaded);
return ltcachetail->id;
}
// Delete light table textures, ids given before become invalid and must not be used.
EXPORT void HWRAPI(ClearLightTableCache) (void)
{
while (ltcachehead)
{
pglDeleteTextures(1, &ltcachehead->id);
LightTableCacheEntry_t *next = ltcachehead->next;
free(ltcachehead);
ltcachehead = next;
}
ltcachetail = NULL;
}
// -----------------+
// ReadRect : Read a rectangle region of the truecolor framebuffer
// : store pixels as 16bit 565 RGB
@@ -1814,9 +1635,6 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask,
pglClear(ClearMask);
pglEnableClientState(GL_VERTEX_ARRAY); // We always use this one
pglEnableClientState(GL_TEXTURE_COORD_ARRAY); // And mostly this one, too
if ((!gl_palette_initialized) && (gl_palshader))
InitPalette(0, false); // just gonna put this here for now
}
@@ -2033,6 +1851,8 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
w = pTexInfo->width;
h = pTexInfo->height;
if (w*h > 2048*2048 && pTexInfo->grInfo.format != GL_RGBA)
I_Error("Tried to convert too big texture: %dx%d", w, h);
if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) ||
(pTexInfo->grInfo.format == GR_TEXFMT_AP_88))
@@ -2440,7 +2260,7 @@ static int comparePolygons(const void *p1, const void *p2)
diff = poly1->texNum - poly2->texNum;
if (diff != 0) return diff;
if (gl_palshader)
if (HWR_ShouldUsePaletteRendering())
{
diff = poly1->surf.LightTableId - poly2->surf.LightTableId;
if (diff != 0) return diff;
@@ -2585,11 +2405,14 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
if (gl_allowshaders)
{
Shader_Load(&currentSurfaceInfo, &firstPoly, &firstTint, &firstFade);
if (gl_palshader)
//if (currentSurfaceInfo.LightTableId && currentSurfaceInfo.LightTableId != lt_downloaded)
if (HWR_ShouldUsePaletteRendering())
{
pglActiveTexture(GL_TEXTURE2);// this stuff could be done better but gonna do it quick like this for now
pglActiveTexture(GL_TEXTURE2);
pglBindTexture(GL_TEXTURE_2D, currentSurfaceInfo.LightTableId);
pglActiveTexture(GL_TEXTURE0);
//lt_downloaded = currentSurfaceInfo.LightTableId;
}
}
@@ -2702,7 +2525,7 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
changeState = true;
changePolyFlags = true;
}
if (gl_allowshaders && gl_palshader)
if (gl_allowshaders && HWR_ShouldUsePaletteRendering())
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
@@ -2716,7 +2539,7 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
changeSurfaceInfo = true;
}
}
else if ((gl_allowshaders) && (!gl_palshader))
else if ((gl_allowshaders) && (!HWR_ShouldUsePaletteRendering()))
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
@@ -2794,6 +2617,7 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha];
Shader_Load(&nextSurfaceInfo, &poly, &tint, &fade);
currentShader = nextShader;
changeShader = false;
@@ -2846,12 +2670,14 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha];
Shader_Load(&nextSurfaceInfo, &poly, &tint, &fade);
if (gl_palshader)
//if (nextSurfaceInfo.LightTableId && nextSurfaceInfo.LightTableId != lt_downloaded2)
if (HWR_ShouldUsePaletteRendering())
{
pglActiveTexture(GL_TEXTURE2);// this stuff could be done better but gonna do it quick like this for now
pglActiveTexture(GL_TEXTURE2);
pglBindTexture(GL_TEXTURE_2D, nextSurfaceInfo.LightTableId);
pglActiveTexture(GL_TEXTURE0);
//lt_downloaded2 = nextSurfaceInfo.LightTableId;
}
}
@@ -2956,13 +2782,15 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
fade.green = byte2float[pSurf->FadeColor.s.green];
fade.blue = byte2float[pSurf->FadeColor.s.blue];
fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
}
if (gl_palshader && gl_allowshaders)
{
pglActiveTexture(GL_TEXTURE2);
pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId);
pglActiveTexture(GL_TEXTURE0);
//if (pSurf->LightTableId && pSurf->LightTableId != lt_downloaded3)
if (HWR_ShouldUsePaletteRendering())
{
pglActiveTexture(GL_TEXTURE2);
pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId);
pglActiveTexture(GL_TEXTURE0);
//lt_downloaded3 = pSurf->LightTableId;
}
}
}
@@ -3306,10 +3134,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
break;
}
break;
case HWD_PAL_SHADER:
gl_palshader = Value;
break;
case HWD_SET_TEXTUREFILTERMODE:
switch (Value)
@@ -4488,7 +4312,6 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
off[10] = -yoff;
off[11] = 1.0f;
fix[0] = 0.0f;
fix[1] = 0.0f;
fix[2] = 0.0f;
@@ -4503,19 +4326,14 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
clearColour.red = clearColour.green = clearColour.blue = 0;
clearColour.alpha = 1;
ClearBuffer(true, false, false, &clearColour);
if (gl_palshader)
{
SetBlend(PF_NoDepthTest);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
}
else
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (gl_palshader)
{
if (HWR_ShouldUsePaletteRendering())
SetBlend(PF_NoDepthTest);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (HWR_ShouldUsePaletteRendering()) // still quite hacky, but the replacement code in i_video didnt work and killed performance instead. somehow need to figure out whats up with that.
pglUseProgram(gl_shaderprograms[8].program); // palette postprocess shader
pglActiveTexture(GL_TEXTURE2);
}
pglColor4ubv(white);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
@@ -4525,9 +4343,95 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
tex_downloaded = finalScreenTexture;
if (gl_palshader)
{
if (HWR_ShouldUsePaletteRendering())
pglUseProgram(0);
}
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut)
{
GLenum internalFormat;
if (gl_version[0] == '1' || gl_version[0] == '2')
{
// if the OpenGL version is below 3.0, then the GL_R8 format may not be available.
// so use GL_LUMINANCE8 instead to get a single component 8-bit format
// (it is possible to have access to shaders even in some OpenGL 1.x systems,
// so palette rendering can still possibly be achieved there)
internalFormat = GL_LUMINANCE8;
}
else
{
internalFormat = GL_R8;
}
if (!paletteLookupTex)
pglGenTextures(1, &paletteLookupTex);
pglActiveTexture(GL_TEXTURE1);
pglBindTexture(GL_TEXTURE_3D, paletteLookupTex);
pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexImage3D(GL_TEXTURE_3D, 0, internalFormat, HWR_PALETTE_LUT_SIZE, HWR_PALETTE_LUT_SIZE, HWR_PALETTE_LUT_SIZE,
0, GL_RED, GL_UNSIGNED_BYTE, lut); // should there be a safety guard here aswell as the old one had? cant really test since i dont have hardware which doesent support 3D textures
pglActiveTexture(GL_TEXTURE0);
}
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable)
{
LTListItem *item = malloc(sizeof(LTListItem));
if (!LightTablesTail)
{
LightTablesHead = LightTablesTail = item;
}
else
{
LightTablesTail->next = item;
LightTablesTail = item;
}
item->next = NULL;
pglGenTextures(1, &item->id);
pglBindTexture(GL_TEXTURE_2D, item->id);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, hw_lighttable);
// restore previously bound texture
pglBindTexture(GL_TEXTURE_2D, tex_downloaded);
return item->id;
}
// Delete light table textures, ids given before become invalid and must not be used.
EXPORT void HWRAPI(ClearLightTables)(void)
{
while (LightTablesHead)
{
LTListItem *item = LightTablesHead;
pglDeleteTextures(1, (GLuint *)&item->id);
LightTablesHead = item->next;
free(item);
}
LightTablesTail = NULL;
// we no longer have a bound light table (if we had one), we just deleted it!
//lt_downloaded = 0;
//lt_downloaded2 = 0;
//lt_downloaded3 = 0;
}
// This palette is used for the palette rendering postprocessing step.
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette)
{
if (memcmp(screenPalette, palette, sizeof(screenPalette)))
{
memcpy(screenPalette, palette, sizeof(screenPalette));
if (!screenPaletteTex)
pglGenTextures(1, &screenPaletteTex);
pglActiveTexture(GL_TEXTURE2);
pglBindTexture(GL_TEXTURE_1D, screenPaletteTex);
pglTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, palette);
pglActiveTexture(GL_TEXTURE0);
}
}
-3
View File
@@ -133,7 +133,4 @@ typedef enum
GLF_NOTEXENV = 0x02,
} oglflags_t;
// in order for custom playpals n shit to work properly
extern boolean gl_palette_initialized;
#endif
+2 -41
View File
@@ -319,7 +319,7 @@ static void M_ResetControls(INT32 choice);
// Video & Sound
menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ExpOptionsDef;
#ifdef HWRENDER
menu_t OP_OpenGLOptionsDef, OP_OpenGLColorDef;
menu_t OP_OpenGLOptionsDef;
#endif
menu_t OP_SoundOptionsDef;
menu_t OP_SoundAdvancedDef;
@@ -410,9 +410,6 @@ static void M_DrawVideoMenu(void);
static void M_DrawHUDOptions(void);
static void M_DrawVideoMode(void);
static void M_DrawMonitorToggles(void);
#ifdef HWRENDER
static void M_OGL_DrawColorMenu(void);
#endif
static void M_DrawMPMainMenu(void);
#ifndef NONET
static void M_DrawConnectMenu(void);
@@ -1494,7 +1491,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_grfallbackplayermodel, 20},
{IT_STRING | IT_CVAR, NULL, "Shaders", &cv_grshaders, 25},
//{IT_STRING|IT_CVAR, NULL, "Use custom Shaders", &cv_grusecustomshaders, 35},
{IT_STRING | IT_CVAR, NULL, "Palette Rendering", &cv_grpaletteshader, 30},
{IT_STRING | IT_CVAR, NULL, "Palette Rendering", &cv_grpaletterendering, 30},
{IT_STRING | IT_CVAR, NULL, "Flashpals in Palette Renderer", &cv_grflashpal, 35},
{IT_STRING | IT_CVAR, NULL, "Min Shader Brightness", &cv_secbright, 40},
@@ -1508,8 +1505,6 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Sprite Billboarding", &cv_grspritebillboarding, 85},
{IT_STRING|IT_CVAR, NULL, "Software Perspective", &cv_grshearing, 90},
{IT_STRING|IT_CVAR, NULL, "Rendering Distance", &cv_grrenderdistance, 95},
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 105},
};
static const char* OP_OpenGLTooltips[] =
@@ -1529,15 +1524,8 @@ static const char* OP_OpenGLTooltips[] =
"Should sprites always face the camera?",
"Recreates the look of software mode camera perspective.",
"How far the game world should be drawn.",
"Gamma (brightness) of colors.",
};
static menuitem_t OP_OpenGLColorMenu[] =
{
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Red", &cv_grgammared, 10},
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Green", &cv_grgammagreen, 20},
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Blue", &cv_grgammablue, 30},
};
#endif
static menuitem_t OP_SoundOptionsMenu[] =
@@ -2832,19 +2820,6 @@ menu_t OP_MonitorToggleDef =
#ifdef HWRENDER
menu_t OP_OpenGLOptionsDef = DEFAULTSCROLLSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30);
menu_t OP_OpenGLColorDef =
{
"M_VIDEO",
sizeof (OP_OpenGLColorMenu)/sizeof (menuitem_t),
&OP_OpenGLOptionsDef,
OP_OpenGLColorMenu,
M_OGL_DrawColorMenu,
60, 40,
0,
NULL,
NULL
};
#endif
menu_t OP_ExpOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_ExpOptionsMenu, &OP_VideoOptionsDef, 30, 30);
@@ -14291,20 +14266,6 @@ static void M_QuitSRB2(INT32 choice)
// =====================================================================
// OpenGL specific options
// =====================================================================
// =====================
// M_OGL_DrawColorMenu()
// =====================
static void M_OGL_DrawColorMenu(void)
{
INT32 mx, my;
mx = currentMenu->x;
my = currentMenu->y;
M_DrawGenericMenu(); // use generic drawer for cursor, items and title
V_DrawString(mx, my + currentMenu->menuitems[0].alphaKey - 10,
highlightflags, "Gamma correction");
}
#endif
#ifdef HAVE_DISCORDRPC
+4
View File
@@ -3148,7 +3148,11 @@ boolean P_SetupLevel(boolean skipprecip)
// Correct missing sidedefs & deep water trick
HWR_CorrectSWTricks();
HWR_CreatePlanePolygons((INT32)numnodes - 1);
if (HWR_ShouldUsePaletteRendering()) //unsure if this is the right place, but seems to work since we dont have HWR_LoadLevel like srb2
HWR_SetMapPalette();
}
#endif
// oh god I hope this helps
+1 -1
View File
@@ -39,7 +39,7 @@ INT32 doorclosed;
boolean R_NoEncore(sector_t *sector, boolean ceiling)
{
boolean invertencore = (GETSECSPECIAL(sector->special, 2) == 12);
boolean invertencore = (GETSECSPECIAL(sector->special, 2) == 15);
#if 0 // perfect implementation
INT32 val = GETSECSPECIAL(sector->special, 3);
if (val != 1 && val != 3 // spring panel
+12 -6
View File
@@ -28,6 +28,7 @@
#ifdef HWRENDER
#include "hardware/hw_main.h"
#include "hardware/hw_glob.h" // HWR_ClearLightTables
#endif
#ifdef _WIN32
@@ -1139,8 +1140,9 @@ void R_ClearColormaps(void)
memset(extra_colormaps, 0, sizeof (extra_colormaps));
#ifdef HWRENDER
HWR_ClearLightTableCache();
#endif
if (rendermode == render_opengl)
HWR_ClearLightTables();
#endif
}
/*INT32 R_ColormapNumForName(char *name)
@@ -1412,16 +1414,20 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
// Thanks to quake2 source!
// utils3/qdata/images.c
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b)
UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette)
{
int dr, dg, db;
int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i;
// Use local palette if none specified
if (palette == NULL)
palette = pLocalPalette;
for (i = 0; i < 256; i++)
{
dr = r - pLocalPalette[i].s.red;
dg = g - pLocalPalette[i].s.green;
db = b - pLocalPalette[i].s.blue;
dr = r - palette[i].s.red;
dg = g - palette[i].s.green;
db = b - palette[i].s.blue;
distortion = dr*dr + dg*dg + db*db;
if (distortion < bestdistortion)
{
+2 -1
View File
@@ -100,7 +100,8 @@ void R_MakeInvertmap(void);
#endif
const char *R_ColormapNameForNum(INT32 num);
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette);
#define NearestColor(r, g, b) NearestPaletteColor(r, g, b, NULL)
extern INT32 numtextures;
-1
View File
@@ -63,7 +63,6 @@ typedef struct
INT32 fadergba; // The colour the colourmaps fade to
lighttable_t *colormap;
#ifdef HWRENDER
// The id of the hardware lighttable. Zero means it does not exist yet.
+5 -4
View File
@@ -74,7 +74,7 @@ void *hwSym(const char *funcName,void *handle)
{
void *funcPointer = NULL;
#ifdef HWRENDER
if (0 == strcmp("SetPalette", funcName))
if (0 == strcmp("SetTexturePalette", funcName))
funcPointer = &OglSdlSetPalette;
GETFUNC(Init);
@@ -118,9 +118,10 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(StartBatching);
GETFUNC(RenderBatches);
GETFUNC(InitPalette);
GETFUNC(AddLightTable);
GETFUNC(ClearLightTableCache);
GETFUNC(SetPaletteLookup);
GETFUNC(CreateLightTable);
GETFUNC(ClearLightTables);
GETFUNC(SetScreenPalette);
#else //HWRENDER
if (0 == strcmp("FinishUpdate", funcName))
+17 -4
View File
@@ -1483,6 +1483,18 @@ void I_FinishUpdate(void)
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
/*// Final postprocess step of palette rendering, after everything else has been drawn.
if (HWR_ShouldUsePaletteRendering())
{
// not using the function for its original named purpose but can be used like this too
HWR_MakeScreenFinalTexture();
HWD.pfnSetSpecialState(HWD_SET_SHADERS, 1);
HWD.pfnSetShader(8);
HWR_DrawScreenFinalTexture(vid.width, vid.height);
HWD.pfnUnSetShader();
HWD.pfnSetSpecialState(HWD_SET_SHADERS, 0);
}*/ //for some reason this does not work here,so ill keep it in DrawScreenFinalTexture itself for now
OglSdlFinishUpdate(cv_vidwait.value);
}
#endif
@@ -2121,7 +2133,7 @@ void I_StartupGraphics(void)
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
HWD.pfnSetTexturePalette= hwSym("SetTexturePalette",NULL);
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
@@ -2151,9 +2163,10 @@ void I_StartupGraphics(void)
HWD.pfnStartBatching = hwSym("StartBatching",NULL);
HWD.pfnRenderBatches = hwSym("RenderBatches",NULL);
HWD.pfnInitPalette = hwSym("InitPalette",NULL);
HWD.pfnAddLightTable = hwSym("AddLightTable",NULL);
HWD.pfnClearLightTableCache = hwSym("ClearLightTableCache",NULL);
HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL);
HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL);
HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL);
HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL);
if (!HWD.pfnInit()) // load the OpenGL library
rendermode = render_soft;
+5 -7
View File
@@ -236,17 +236,15 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_DrawScreenFinalTexture(realwidth, realheight);
}
EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma)
EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette)
{
INT32 i = -1;
UINT32 redgamma = pgamma->s.red, greengamma = pgamma->s.green,
bluegamma = pgamma->s.blue;
INT32 i;
for (i = 0; i < 256; i++)
{
myPaletteData[i].s.red = (UINT8)MIN((palette[i].s.red * redgamma) /127, 255);
myPaletteData[i].s.green = (UINT8)MIN((palette[i].s.green * greengamma)/127, 255);
myPaletteData[i].s.blue = (UINT8)MIN((palette[i].s.blue * bluegamma) /127, 255);
myPaletteData[i].s.red = palette[i].s.red;
myPaletteData[i].s.green = palette[i].s.green;
myPaletteData[i].s.blue = palette[i].s.blue;
myPaletteData[i].s.alpha = palette[i].s.alpha;
}
Flush();
+1 -1
View File
@@ -30,5 +30,5 @@ extern Uint16 realwidth;
extern Uint16 realheight;
#ifdef _CREATE_DLL_
EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette, RGBA_t *pgamma);
EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette);
#endif
+1 -1
View File
@@ -245,7 +245,7 @@ void ST_doPaletteStuff(void)
palette = 0;
#ifdef HWRENDER
if ((rendermode == render_opengl) && (!HWR_PalRenderFlashpal()))
if (rendermode == render_opengl && !HWR_PalRenderFlashpal())
palette = 0; // No flashpals here in OpenGL
#endif
+3 -20
View File
@@ -201,17 +201,8 @@ void V_SetPalette(INT32 palettenum)
LoadMapPalette();
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none) {
// in palette rendering mode, we already manage our palette ourselves
if (HWR_ShouldUsePaletteRendering())
{
// reset our palette lookups n shit
gl_palette_initialized = false;
HWR_InitPalette(palettenum, true);
}
else
HWR_SetPalette(&pLocalPalette[palettenum*256]);
}
if (rendermode != render_soft && rendermode != render_none)
HWR_SetPalette(&pLocalPalette[palettenum*256]);
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
else
#endif
@@ -224,16 +215,8 @@ void V_SetPaletteLump(const char *pal)
{
LoadPalette(pal);
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none) {
if (HWR_ShouldUsePaletteRendering())
{
// reset our palette lookups n shit
gl_palette_initialized = false;
HWR_InitPalette(0, false);
}
if (rendermode != render_soft && rendermode != render_none)
HWR_SetPalette(pLocalPalette);
}
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
else
#endif