mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-27 11:41:16 +00:00
OpenGL palette rendering and related things
This commit is contained in:
parent
118fc58192
commit
ac1b5ae546
14 changed files with 719 additions and 122 deletions
|
@ -32,6 +32,14 @@
|
||||||
INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes
|
INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes
|
||||||
INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole
|
INT32 textureformat = GL_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.
|
||||||
|
static RGBA_t *HWR_GetTexturePalette(void)
|
||||||
|
{
|
||||||
|
return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette;
|
||||||
|
}
|
||||||
|
|
||||||
static INT32 format2bpp(GLTextureFormat_t format)
|
static INT32 format2bpp(GLTextureFormat_t format)
|
||||||
{
|
{
|
||||||
if (format == GL_TEXFMT_RGBA)
|
if (format == GL_TEXFMT_RGBA)
|
||||||
|
@ -49,7 +57,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
||||||
INT32 pblockheight, INT32 blockmodulo,
|
INT32 pblockheight, INT32 blockmodulo,
|
||||||
fixed_t yfracstep, fixed_t scale_y,
|
fixed_t yfracstep, fixed_t scale_y,
|
||||||
texpatch_t *originPatch, INT32 patchheight,
|
texpatch_t *originPatch, INT32 patchheight,
|
||||||
INT32 bpp)
|
INT32 bpp, RGBA_t *palette)
|
||||||
{
|
{
|
||||||
fixed_t yfrac, position, count;
|
fixed_t yfrac, position, count;
|
||||||
UINT8 *dest;
|
UINT8 *dest;
|
||||||
|
@ -121,7 +129,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
||||||
texelu16 = (UINT16)((alpha<<8) | texel);
|
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||||
break;
|
break;
|
||||||
case 3 : colortemp = V_GetColor(texel);
|
case 3 : colortemp = palette[texel];
|
||||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
{
|
{
|
||||||
RGBA_t rgbatexel;
|
RGBA_t rgbatexel;
|
||||||
|
@ -130,7 +138,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
||||||
}
|
}
|
||||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||||
break;
|
break;
|
||||||
case 4 : colortemp = V_GetColor(texel);
|
case 4 : colortemp = palette[texel];
|
||||||
colortemp.s.alpha = alpha;
|
colortemp.s.alpha = alpha;
|
||||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
{
|
{
|
||||||
|
@ -160,7 +168,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
||||||
INT32 pblockheight, INT32 blockmodulo,
|
INT32 pblockheight, INT32 blockmodulo,
|
||||||
fixed_t yfracstep, fixed_t scale_y,
|
fixed_t yfracstep, fixed_t scale_y,
|
||||||
texpatch_t *originPatch, INT32 patchheight,
|
texpatch_t *originPatch, INT32 patchheight,
|
||||||
INT32 bpp)
|
INT32 bpp, RGBA_t *palette)
|
||||||
{
|
{
|
||||||
fixed_t yfrac, position, count;
|
fixed_t yfrac, position, count;
|
||||||
UINT8 *dest;
|
UINT8 *dest;
|
||||||
|
@ -231,7 +239,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
||||||
texelu16 = (UINT16)((alpha<<8) | texel);
|
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||||
break;
|
break;
|
||||||
case 3 : colortemp = V_GetColor(texel);
|
case 3 : colortemp = palette[texel];
|
||||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
{
|
{
|
||||||
RGBA_t rgbatexel;
|
RGBA_t rgbatexel;
|
||||||
|
@ -240,7 +248,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
||||||
}
|
}
|
||||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||||
break;
|
break;
|
||||||
case 4 : colortemp = V_GetColor(texel);
|
case 4 : colortemp = palette[texel];
|
||||||
colortemp.s.alpha = alpha;
|
colortemp.s.alpha = alpha;
|
||||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||||
{
|
{
|
||||||
|
@ -284,10 +292,13 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
|
||||||
UINT8 *block = mipmap->data;
|
UINT8 *block = mipmap->data;
|
||||||
INT32 bpp;
|
INT32 bpp;
|
||||||
INT32 blockmodulo;
|
INT32 blockmodulo;
|
||||||
|
RGBA_t *palette;
|
||||||
|
|
||||||
if (pwidth <= 0 || pheight <= 0)
|
if (pwidth <= 0 || pheight <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
palette = HWR_GetTexturePalette();
|
||||||
|
|
||||||
ncols = pwidth;
|
ncols = pwidth;
|
||||||
|
|
||||||
// source advance
|
// source advance
|
||||||
|
@ -313,7 +324,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
|
||||||
pblockheight, blockmodulo,
|
pblockheight, blockmodulo,
|
||||||
yfracstep, scale_y,
|
yfracstep, scale_y,
|
||||||
NULL, pheight, // not that pheight is going to get used anyway...
|
NULL, pheight, // not that pheight is going to get used anyway...
|
||||||
bpp);
|
bpp, palette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,16 +343,19 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
||||||
INT32 bpp;
|
INT32 bpp;
|
||||||
INT32 blockmodulo;
|
INT32 blockmodulo;
|
||||||
INT32 width, height;
|
INT32 width, height;
|
||||||
|
RGBA_t *palette;
|
||||||
// Column drawing function pointer.
|
// Column drawing function pointer.
|
||||||
static void (*ColumnDrawerPointer)(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
|
static void (*ColumnDrawerPointer)(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
|
||||||
INT32 pblockheight, INT32 blockmodulo,
|
INT32 pblockheight, INT32 blockmodulo,
|
||||||
fixed_t yfracstep, fixed_t scale_y,
|
fixed_t yfracstep, fixed_t scale_y,
|
||||||
texpatch_t *originPatch, INT32 patchheight,
|
texpatch_t *originPatch, INT32 patchheight,
|
||||||
INT32 bpp);
|
INT32 bpp, RGBA_t *palette);
|
||||||
|
|
||||||
if (texture->width <= 0 || texture->height <= 0)
|
if (texture->width <= 0 || texture->height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
palette = HWR_GetTexturePalette();
|
||||||
|
|
||||||
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
|
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
|
||||||
|
|
||||||
x1 = patch->originx;
|
x1 = patch->originx;
|
||||||
|
@ -409,7 +423,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
||||||
pblockheight, blockmodulo,
|
pblockheight, blockmodulo,
|
||||||
yfracstep, scale_y,
|
yfracstep, scale_y,
|
||||||
patch, height,
|
patch, height,
|
||||||
bpp);
|
bpp, palette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,6 +468,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
boolean skyspecial = false; //poor hack for Legacy large skies..
|
boolean skyspecial = false; //poor hack for Legacy large skies..
|
||||||
|
|
||||||
|
RGBA_t *palette;
|
||||||
|
palette = HWR_GetTexturePalette();
|
||||||
|
|
||||||
texture = textures[texnum];
|
texture = textures[texnum];
|
||||||
|
|
||||||
// hack the Legacy skies..
|
// hack the Legacy skies..
|
||||||
|
@ -472,7 +489,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
||||||
|
|
||||||
grtex->mipmap.width = (UINT16)texture->width;
|
grtex->mipmap.width = (UINT16)texture->width;
|
||||||
grtex->mipmap.height = (UINT16)texture->height;
|
grtex->mipmap.height = (UINT16)texture->height;
|
||||||
grtex->mipmap.format = textureformat;
|
if (skyspecial)
|
||||||
|
grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
|
||||||
|
else
|
||||||
|
grtex->mipmap.format = textureformat;
|
||||||
|
|
||||||
blockwidth = texture->width;
|
blockwidth = texture->width;
|
||||||
blockheight = texture->height;
|
blockheight = texture->height;
|
||||||
|
@ -484,7 +504,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
||||||
INT32 j;
|
INT32 j;
|
||||||
RGBA_t col;
|
RGBA_t col;
|
||||||
|
|
||||||
col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX);
|
col = palette[HWR_PATCHES_CHROMAKEY_COLORINDEX];
|
||||||
for (j = 0; j < blockheight; j++)
|
for (j = 0; j < blockheight; j++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < blockwidth; i++)
|
for (i = 0; i < blockwidth; i++)
|
||||||
|
@ -759,19 +779,6 @@ void HWR_LoadMapTextures(size_t pnumtextures)
|
||||||
gl_maptexturesloaded = true;
|
gl_maptexturesloaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWR_SetPalette(RGBA_t *palette)
|
|
||||||
{
|
|
||||||
HWD.pfnSetPalette(palette);
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
Z_FreeTag(PU_HWRCACHE);
|
|
||||||
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Make sure texture is downloaded and set it as the source
|
// Make sure texture is downloaded and set it as the source
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -1111,6 +1118,7 @@ static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheig
|
||||||
UINT16 texelu16;
|
UINT16 texelu16;
|
||||||
INT32 picbpp;
|
INT32 picbpp;
|
||||||
RGBA_t col;
|
RGBA_t col;
|
||||||
|
RGBA_t *palette = HWR_GetTexturePalette();
|
||||||
|
|
||||||
stepy = ((INT32)SHORT(pic->height)<<FRACBITS)/pblockheight;
|
stepy = ((INT32)SHORT(pic->height)<<FRACBITS)/pblockheight;
|
||||||
stepx = ((INT32)SHORT(pic->width)<<FRACBITS)/pblockwidth;
|
stepx = ((INT32)SHORT(pic->width)<<FRACBITS)/pblockwidth;
|
||||||
|
@ -1137,12 +1145,12 @@ static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheig
|
||||||
dest += sizeof(UINT16);
|
dest += sizeof(UINT16);
|
||||||
break;
|
break;
|
||||||
case 3 :
|
case 3 :
|
||||||
col = V_GetColor(texel);
|
col = palette[texel];
|
||||||
memcpy(dest, &col, sizeof(RGBA_t)-sizeof(UINT8));
|
memcpy(dest, &col, sizeof(RGBA_t)-sizeof(UINT8));
|
||||||
dest += sizeof(RGBA_t)-sizeof(UINT8);
|
dest += sizeof(RGBA_t)-sizeof(UINT8);
|
||||||
break;
|
break;
|
||||||
case 4 :
|
case 4 :
|
||||||
memcpy(dest, &V_GetColor(texel), sizeof(RGBA_t));
|
memcpy(dest, &palette[texel], sizeof(RGBA_t));
|
||||||
dest += sizeof(RGBA_t);
|
dest += sizeof(RGBA_t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1252,6 +1260,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
|
||||||
UINT8 *flat;
|
UINT8 *flat;
|
||||||
UINT8 *dest, *src, texel;
|
UINT8 *dest, *src, texel;
|
||||||
RGBA_t col;
|
RGBA_t col;
|
||||||
|
RGBA_t *palette = HWR_GetTexturePalette();
|
||||||
|
|
||||||
// Place the flats data into flat
|
// Place the flats data into flat
|
||||||
W_ReadLump(fademasklumpnum, Z_Malloc(W_LumpLength(fademasklumpnum),
|
W_ReadLump(fademasklumpnum, Z_Malloc(W_LumpLength(fademasklumpnum),
|
||||||
|
@ -1269,7 +1278,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
|
||||||
{
|
{
|
||||||
// fademask bpp is always 1, and is used just for alpha
|
// fademask bpp is always 1, and is used just for alpha
|
||||||
texel = src[(posx)>>FRACBITS];
|
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 = col.s.red; // take the red level of the colour and use it for alpha, as fademasks do
|
||||||
|
|
||||||
dest++;
|
dest++;
|
||||||
|
@ -1341,4 +1350,159 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
|
||||||
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
|
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =================================================
|
||||||
|
// PALETTE HANDLING
|
||||||
|
// =================================================
|
||||||
|
|
||||||
|
void HWR_SetPalette(RGBA_t *palette)
|
||||||
|
{
|
||||||
|
if (HWR_ShouldUsePaletteRendering())
|
||||||
|
{
|
||||||
|
// set the palette for palette postprocessing
|
||||||
|
|
||||||
|
if (cv_glpalettedepth.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 && titlemapinaction)))
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 && titlemapinaction)))
|
||||||
|
{
|
||||||
|
// outside of a level, pMasterPalette should have PLAYPAL ready for us
|
||||||
|
palette = pMasterPalette;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// in a level pMasterPalette 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
HWD.pfnClearLightTables();
|
||||||
|
}
|
||||||
|
|
||||||
#endif //HWRENDER
|
#endif //HWRENDER
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
#define ZCLIP_PLANE 4.0f // Used for the actual game drawing
|
#define ZCLIP_PLANE 4.0f // Used for the actual game drawing
|
||||||
#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
|
#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
|
||||||
|
|
||||||
|
// 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
|
// SIMPLE TYPES
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -146,6 +152,7 @@ enum
|
||||||
SHADER_WATER,
|
SHADER_WATER,
|
||||||
SHADER_FOG,
|
SHADER_FOG,
|
||||||
SHADER_SKY,
|
SHADER_SKY,
|
||||||
|
SHADER_PALETTE_POSTPROCESS,
|
||||||
|
|
||||||
NUMSHADERTARGETS,
|
NUMSHADERTARGETS,
|
||||||
};
|
};
|
||||||
|
@ -275,6 +282,7 @@ struct FSurfaceInfo
|
||||||
RGBA_t PolyColor;
|
RGBA_t PolyColor;
|
||||||
RGBA_t TintColor;
|
RGBA_t TintColor;
|
||||||
RGBA_t FadeColor;
|
RGBA_t FadeColor;
|
||||||
|
UINT32 LightTableId;
|
||||||
FLightInfo LightInfo;
|
FLightInfo LightInfo;
|
||||||
};
|
};
|
||||||
typedef struct FSurfaceInfo FSurfaceInfo;
|
typedef struct FSurfaceInfo FSurfaceInfo;
|
||||||
|
@ -282,7 +290,7 @@ typedef struct FSurfaceInfo FSurfaceInfo;
|
||||||
#define GL_DEFAULTMIX 0x00000000
|
#define GL_DEFAULTMIX 0x00000000
|
||||||
#define GL_DEFAULTFOG 0xFF000000
|
#define GL_DEFAULTFOG 0xFF000000
|
||||||
|
|
||||||
//Hurdler: added for backward compatibility
|
// Various settings and states for the rendering backend.
|
||||||
enum hwdsetspecialstate
|
enum hwdsetspecialstate
|
||||||
{
|
{
|
||||||
HWD_SET_MODEL_LIGHTING = 1,
|
HWD_SET_MODEL_LIGHTING = 1,
|
||||||
|
|
|
@ -32,7 +32,7 @@ EXPORT void HWRAPI(Shutdown) (void);
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes);
|
EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes);
|
||||||
#endif
|
#endif
|
||||||
EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal);
|
EXPORT void HWRAPI(SetTexturePalette) (RGBA_t *ppal);
|
||||||
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
|
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
|
||||||
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
|
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
|
||||||
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
|
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
|
||||||
|
@ -47,10 +47,8 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32
|
||||||
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
|
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
|
||||||
EXPORT void HWRAPI(ClearMipMapCache) (void);
|
EXPORT void HWRAPI(ClearMipMapCache) (void);
|
||||||
|
|
||||||
//Hurdler: added for backward compatibility
|
|
||||||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
||||||
|
|
||||||
//Hurdler: added for new development
|
|
||||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
|
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
|
||||||
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
||||||
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
||||||
|
@ -76,6 +74,11 @@ EXPORT void HWRAPI(UnSetShader) (void);
|
||||||
|
|
||||||
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
|
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
|
||||||
|
|
||||||
|
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
|
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -85,7 +88,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
|
||||||
struct hwdriver_s
|
struct hwdriver_s
|
||||||
{
|
{
|
||||||
Init pfnInit;
|
Init pfnInit;
|
||||||
SetPalette pfnSetPalette;
|
SetTexturePalette pfnSetTexturePalette;
|
||||||
FinishUpdate pfnFinishUpdate;
|
FinishUpdate pfnFinishUpdate;
|
||||||
Draw2DLine pfnDraw2DLine;
|
Draw2DLine pfnDraw2DLine;
|
||||||
DrawPolygon pfnDrawPolygon;
|
DrawPolygon pfnDrawPolygon;
|
||||||
|
@ -99,7 +102,7 @@ struct hwdriver_s
|
||||||
ReadRect pfnReadRect;
|
ReadRect pfnReadRect;
|
||||||
GClipRect pfnGClipRect;
|
GClipRect pfnGClipRect;
|
||||||
ClearMipMapCache pfnClearMipMapCache;
|
ClearMipMapCache pfnClearMipMapCache;
|
||||||
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
|
SetSpecialState pfnSetSpecialState;
|
||||||
DrawModel pfnDrawModel;
|
DrawModel pfnDrawModel;
|
||||||
CreateModelVBOs pfnCreateModelVBOs;
|
CreateModelVBOs pfnCreateModelVBOs;
|
||||||
SetTransform pfnSetTransform;
|
SetTransform pfnSetTransform;
|
||||||
|
@ -127,6 +130,11 @@ struct hwdriver_s
|
||||||
UnSetShader pfnUnSetShader;
|
UnSetShader pfnUnSetShader;
|
||||||
|
|
||||||
SetShaderInfo pfnSetShaderInfo;
|
SetShaderInfo pfnSetShaderInfo;
|
||||||
|
|
||||||
|
SetPaletteLookup pfnSetPaletteLookup;
|
||||||
|
CreateLightTable pfnCreateLightTable;
|
||||||
|
ClearLightTables pfnClearLightTables;
|
||||||
|
SetScreenPalette pfnSetScreenPalette;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct hwdriver_s hwdriver;
|
extern struct hwdriver_s hwdriver;
|
||||||
|
|
|
@ -128,6 +128,9 @@ void HWR_FreeColormapCache(void);
|
||||||
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
|
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
|
||||||
|
|
||||||
void HWR_SetPalette(RGBA_t *palette);
|
void HWR_SetPalette(RGBA_t *palette);
|
||||||
|
void HWR_SetMapPalette(void);
|
||||||
|
UINT32 HWR_CreateLightTable(UINT8 *lighttable);
|
||||||
|
void HWR_ClearLightTables(void);
|
||||||
|
|
||||||
|
|
||||||
// --------
|
// --------
|
||||||
|
|
|
@ -126,26 +126,6 @@ static line_t *gl_linedef;
|
||||||
static sector_t *gl_frontsector;
|
static sector_t *gl_frontsector;
|
||||||
static sector_t *gl_backsector;
|
static sector_t *gl_backsector;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
// STUFF FOR THE PROJECTION CODE
|
|
||||||
// --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
FTransform atransform;
|
|
||||||
// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct,
|
|
||||||
// copied here for local use
|
|
||||||
static fixed_t dup_viewx, dup_viewy, dup_viewz;
|
|
||||||
static angle_t dup_viewangle;
|
|
||||||
|
|
||||||
static float gl_viewx, gl_viewy, gl_viewz;
|
|
||||||
static float gl_viewsin, gl_viewcos;
|
|
||||||
|
|
||||||
// Maybe not necessary with the new T&L code (needs to be checked!)
|
|
||||||
static float gl_viewludsin, gl_viewludcos; // look up down kik test
|
|
||||||
static float gl_fovlud;
|
|
||||||
|
|
||||||
static angle_t gl_aimingangle;
|
|
||||||
static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox);
|
|
||||||
|
|
||||||
// Render stats
|
// Render stats
|
||||||
precise_t ps_hw_skyboxtime = 0;
|
precise_t ps_hw_skyboxtime = 0;
|
||||||
precise_t ps_hw_nodesorttime = 0;
|
precise_t ps_hw_nodesorttime = 0;
|
||||||
|
@ -170,6 +150,29 @@ boolean gl_sessioncommandsadded = false;
|
||||||
// false if shaders have not been initialized yet, or if shaders are not available
|
// false if shaders have not been initialized yet, or if shaders are not available
|
||||||
boolean gl_shadersavailable = false;
|
boolean gl_shadersavailable = false;
|
||||||
|
|
||||||
|
// Whether the internal state is set to palette rendering or not.
|
||||||
|
static boolean gl_palette_rendering_state = false;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// STUFF FOR THE PROJECTION CODE
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FTransform atransform;
|
||||||
|
// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct,
|
||||||
|
// copied here for local use
|
||||||
|
static fixed_t dup_viewx, dup_viewy, dup_viewz;
|
||||||
|
static angle_t dup_viewangle;
|
||||||
|
|
||||||
|
static float gl_viewx, gl_viewy, gl_viewz;
|
||||||
|
static float gl_viewsin, gl_viewcos;
|
||||||
|
|
||||||
|
// Maybe not necessary with the new T&L code (needs to be checked!)
|
||||||
|
static float gl_viewludsin, gl_viewludcos; // look up down kik test
|
||||||
|
static float gl_fovlud;
|
||||||
|
|
||||||
|
static angle_t gl_aimingangle;
|
||||||
|
static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox);
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Lighting
|
// Lighting
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -234,6 +237,33 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
||||||
Surface->LightInfo.light_level = light_level;
|
Surface->LightInfo.light_level = light_level;
|
||||||
Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0;
|
Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0;
|
||||||
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
|
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
|
||||||
|
|
||||||
|
if (HWR_ShouldUsePaletteRendering())
|
||||||
|
{
|
||||||
|
boolean default_colormap = false;
|
||||||
|
if (!colormap)
|
||||||
|
{
|
||||||
|
colormap = R_GetDefaultColormap(); // 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);
|
||||||
|
}
|
||||||
|
Surface->LightTableId = colormap->gl_lighttable_id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Surface->LightTableId = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
|
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
|
||||||
|
@ -905,13 +935,15 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||||
{
|
{
|
||||||
if (pfloor && (pfloor->flags & FF_FOG))
|
if (pfloor && (pfloor->flags & FF_FOG))
|
||||||
{
|
{
|
||||||
lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y);
|
lightnum = pfloor->master->frontsector->lightlevel;
|
||||||
colormap = pfloor->master->frontsector->extra_colormap;
|
colormap = pfloor->master->frontsector->extra_colormap;
|
||||||
|
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y);
|
lightnum = *list[i].lightlevel;
|
||||||
colormap = *list[i].extra_colormap;
|
colormap = *list[i].extra_colormap;
|
||||||
|
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,8 +1145,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
|
cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
lightnum = gl_frontsector->lightlevel;
|
||||||
colormap = gl_frontsector->extra_colormap;
|
colormap = gl_frontsector->extra_colormap;
|
||||||
|
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||||
|
|
||||||
if (gl_frontsector)
|
if (gl_frontsector)
|
||||||
Surf.PolyColor.s.alpha = 255;
|
Surf.PolyColor.s.alpha = 255;
|
||||||
|
@ -1739,8 +1772,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
|
|
||||||
blendmode = PF_Fog|PF_NoTexture;
|
blendmode = PF_Fog|PF_NoTexture;
|
||||||
|
|
||||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
lightnum = rover->master->frontsector->lightlevel;
|
||||||
colormap = rover->master->frontsector->extra_colormap;
|
colormap = rover->master->frontsector->extra_colormap;
|
||||||
|
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||||
|
|
||||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||||
|
|
||||||
|
@ -1851,8 +1885,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
|
|
||||||
blendmode = PF_Fog|PF_NoTexture;
|
blendmode = PF_Fog|PF_NoTexture;
|
||||||
|
|
||||||
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
lightnum = rover->master->frontsector->lightlevel;
|
||||||
colormap = rover->master->frontsector->extra_colormap;
|
colormap = rover->master->frontsector->extra_colormap;
|
||||||
|
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||||
|
|
||||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||||
|
|
||||||
|
@ -5867,6 +5902,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
||||||
else
|
else
|
||||||
type = &postimgtype;
|
type = &postimgtype;
|
||||||
|
|
||||||
|
if (!HWR_ShouldUsePaletteRendering())
|
||||||
{
|
{
|
||||||
// do we really need to save player (is it not the same)?
|
// do we really need to save player (is it not the same)?
|
||||||
player_t *saved_player = stplyr;
|
player_t *saved_player = stplyr;
|
||||||
|
@ -6080,6 +6116,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
||||||
HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind
|
HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind
|
||||||
ps_hw_skyboxtime = I_GetPreciseTime() - ps_hw_skyboxtime;
|
ps_hw_skyboxtime = I_GetPreciseTime() - ps_hw_skyboxtime;
|
||||||
|
|
||||||
|
if (!HWR_ShouldUsePaletteRendering())
|
||||||
{
|
{
|
||||||
// do we really need to save player (is it not the same)?
|
// do we really need to save player (is it not the same)?
|
||||||
player_t *saved_player = stplyr;
|
player_t *saved_player = stplyr;
|
||||||
|
@ -6277,6 +6314,56 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
||||||
HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
|
HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether palette rendering is "actually enabled."
|
||||||
|
// Can't have palette rendering if shaders are disabled.
|
||||||
|
boolean HWR_ShouldUsePaletteRendering(void)
|
||||||
|
{
|
||||||
|
return (cv_glpaletterendering.value && HWR_UseShader());
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable or disable palette rendering state depending on settings and availability
|
||||||
|
// called when relevant settings change
|
||||||
|
// shader recompilation is done in the cvar callback
|
||||||
|
static void HWR_TogglePaletteRendering(void)
|
||||||
|
{
|
||||||
|
// which state should we go to?
|
||||||
|
if (HWR_ShouldUsePaletteRendering())
|
||||||
|
{
|
||||||
|
// are we not in that state already?
|
||||||
|
if (!gl_palette_rendering_state)
|
||||||
|
{
|
||||||
|
gl_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 = GL_TEXFMT_P_8;
|
||||||
|
|
||||||
|
HWR_SetMapPalette();
|
||||||
|
HWR_SetPalette(pLocalPalette);
|
||||||
|
|
||||||
|
// If the r_opengl "texture palette" stays the same during this switch, the 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// are we not in that state already?
|
||||||
|
if (gl_palette_rendering_state)
|
||||||
|
{
|
||||||
|
gl_palette_rendering_state = false;
|
||||||
|
textureformat = GL_TEXFMT_RGBA;
|
||||||
|
HWR_SetPalette(pLocalPalette);
|
||||||
|
// If the r_opengl "texture palette" stays the same during this switch, the 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HWR_LoadLevel(void)
|
void HWR_LoadLevel(void)
|
||||||
{
|
{
|
||||||
#ifdef ALAM_LIGHTING
|
#ifdef ALAM_LIGHTING
|
||||||
|
@ -6290,6 +6377,9 @@ void HWR_LoadLevel(void)
|
||||||
HWR_ClearSkyDome();
|
HWR_ClearSkyDome();
|
||||||
HWR_BuildSkyDome();
|
HWR_BuildSkyDome();
|
||||||
|
|
||||||
|
if (HWR_ShouldUsePaletteRendering())
|
||||||
|
HWR_SetMapPalette();
|
||||||
|
|
||||||
gl_maploaded = true;
|
gl_maploaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6305,6 +6395,9 @@ static CV_PossibleValue_t glshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Thi
|
||||||
static void CV_glfiltermode_OnChange(void);
|
static void CV_glfiltermode_OnChange(void);
|
||||||
static void CV_glanisotropic_OnChange(void);
|
static void CV_glanisotropic_OnChange(void);
|
||||||
static void CV_glmodellighting_OnChange(void);
|
static void CV_glmodellighting_OnChange(void);
|
||||||
|
static void CV_glpaletterendering_OnChange(void);
|
||||||
|
static void CV_glpalettedepth_OnChange(void);
|
||||||
|
static void CV_glshaders_OnChange(void);
|
||||||
|
|
||||||
static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
|
static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
|
||||||
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
|
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
|
||||||
|
@ -6314,7 +6407,7 @@ static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA
|
||||||
{0, NULL}};
|
{0, NULL}};
|
||||||
CV_PossibleValue_t glanisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
|
CV_PossibleValue_t glanisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
|
||||||
|
|
||||||
consvar_t cv_glshaders = CVAR_INIT ("gr_shaders", "On", CV_SAVE, glshaders_cons_t, NULL);
|
consvar_t cv_glshaders = CVAR_INIT ("gr_shaders", "On", CV_SAVE|CV_CALL, glshaders_cons_t, CV_glshaders_OnChange);
|
||||||
consvar_t cv_glallowshaders = CVAR_INIT ("gr_allowclientshaders", "On", CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_glallowshaders = CVAR_INIT ("gr_allowclientshaders", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||||
consvar_t cv_fovchange = CVAR_INIT ("gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL);
|
consvar_t cv_fovchange = CVAR_INIT ("gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||||
|
|
||||||
|
@ -6342,6 +6435,11 @@ consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL)
|
||||||
|
|
||||||
consvar_t cv_glbatching = CVAR_INIT ("gr_batching", "On", 0, CV_OnOff, NULL);
|
consvar_t cv_glbatching = CVAR_INIT ("gr_batching", "On", 0, CV_OnOff, NULL);
|
||||||
|
|
||||||
|
static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}};
|
||||||
|
|
||||||
|
consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletterendering", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_glpaletterendering_OnChange);
|
||||||
|
consvar_t cv_glpalettedepth = CVAR_INIT ("gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_glpalettedepth_OnChange);
|
||||||
|
|
||||||
static void CV_glfiltermode_OnChange(void)
|
static void CV_glfiltermode_OnChange(void)
|
||||||
{
|
{
|
||||||
if (rendermode == render_opengl)
|
if (rendermode == render_opengl)
|
||||||
|
@ -6361,6 +6459,31 @@ static void CV_glmodellighting_OnChange(void)
|
||||||
HWR_CompileShaders();
|
HWR_CompileShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CV_glpaletterendering_OnChange(void)
|
||||||
|
{
|
||||||
|
if (gl_shadersavailable)
|
||||||
|
{
|
||||||
|
HWR_CompileShaders();
|
||||||
|
HWR_TogglePaletteRendering();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CV_glpalettedepth_OnChange(void)
|
||||||
|
{
|
||||||
|
// refresh the screen palette
|
||||||
|
if (HWR_ShouldUsePaletteRendering())
|
||||||
|
HWR_SetPalette(pLocalPalette);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CV_glshaders_OnChange(void)
|
||||||
|
{
|
||||||
|
if (cv_glpaletterendering.value)
|
||||||
|
{
|
||||||
|
// can't do palette rendering without shaders, so update the state if needed
|
||||||
|
HWR_TogglePaletteRendering();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//added by Hurdler: console varibale that are saved
|
//added by Hurdler: console varibale that are saved
|
||||||
void HWR_AddCommands(void)
|
void HWR_AddCommands(void)
|
||||||
{
|
{
|
||||||
|
@ -6389,6 +6512,9 @@ void HWR_AddCommands(void)
|
||||||
|
|
||||||
CV_RegisterVar(&cv_glbatching);
|
CV_RegisterVar(&cv_glbatching);
|
||||||
|
|
||||||
|
CV_RegisterVar(&cv_glpaletterendering);
|
||||||
|
CV_RegisterVar(&cv_glpalettedepth);
|
||||||
|
|
||||||
#ifndef NEWCLIP
|
#ifndef NEWCLIP
|
||||||
CV_RegisterVar(&cv_glclipwalls);
|
CV_RegisterVar(&cv_glclipwalls);
|
||||||
#endif
|
#endif
|
||||||
|
@ -6411,6 +6537,8 @@ void HWR_Startup(void)
|
||||||
{
|
{
|
||||||
CONS_Printf("HWR_Startup()...\n");
|
CONS_Printf("HWR_Startup()...\n");
|
||||||
|
|
||||||
|
textureformat = patchformat = GL_TEXFMT_RGBA;
|
||||||
|
|
||||||
HWR_InitPolyPool();
|
HWR_InitPolyPool();
|
||||||
HWR_AddSessionCommands();
|
HWR_AddSessionCommands();
|
||||||
HWR_InitMapTextures();
|
HWR_InitMapTextures();
|
||||||
|
@ -6421,11 +6549,9 @@ void HWR_Startup(void)
|
||||||
|
|
||||||
gl_shadersavailable = HWR_InitShaders();
|
gl_shadersavailable = HWR_InitShaders();
|
||||||
HWR_LoadAllCustomShaders();
|
HWR_LoadAllCustomShaders();
|
||||||
|
HWR_TogglePaletteRendering();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rendermode == render_opengl)
|
|
||||||
textureformat = patchformat = GL_TEXFMT_RGBA;
|
|
||||||
|
|
||||||
gl_init = true;
|
gl_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6564,7 +6690,7 @@ void HWR_DoPostProcessor(player_t *player)
|
||||||
|
|
||||||
// Armageddon Blast Flash!
|
// Armageddon Blast Flash!
|
||||||
// Could this even be considered postprocessor?
|
// Could this even be considered postprocessor?
|
||||||
if (player->flashcount)
|
if (player->flashcount && !HWR_ShouldUsePaletteRendering())
|
||||||
{
|
{
|
||||||
FOutVector v[4];
|
FOutVector v[4];
|
||||||
FSurfaceInfo Surf;
|
FSurfaceInfo Surf;
|
||||||
|
|
|
@ -74,6 +74,8 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 ast);
|
||||||
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
|
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||||
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
|
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
|
||||||
|
|
||||||
|
boolean HWR_ShouldUsePaletteRendering(void);
|
||||||
|
|
||||||
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
|
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
|
||||||
|
|
||||||
#ifdef ALAM_LIGHTING
|
#ifdef ALAM_LIGHTING
|
||||||
|
@ -96,8 +98,9 @@ extern consvar_t cv_glspritebillboarding;
|
||||||
extern consvar_t cv_glskydome;
|
extern consvar_t cv_glskydome;
|
||||||
extern consvar_t cv_glfakecontrast;
|
extern consvar_t cv_glfakecontrast;
|
||||||
extern consvar_t cv_glslopecontrast;
|
extern consvar_t cv_glslopecontrast;
|
||||||
|
|
||||||
extern consvar_t cv_glbatching;
|
extern consvar_t cv_glbatching;
|
||||||
|
extern consvar_t cv_glpaletterendering;
|
||||||
|
extern consvar_t cv_glpalettedepth;
|
||||||
|
|
||||||
extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowy;
|
extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowy;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#define GLSL_MODEL_VERTEX_SHADER \
|
#define GLSL_MODEL_VERTEX_SHADER \
|
||||||
"void main()\n" \
|
"void main()\n" \
|
||||||
"{\n" \
|
"{\n" \
|
||||||
"#ifdef MODEL_LIGHTING\n" \
|
"#ifdef SRB2_MODEL_LIGHTING\n" \
|
||||||
"float nDotVP = dot(gl_Normal, vec3(0, 1, 0));\n" \
|
"float nDotVP = dot(gl_Normal, vec3(0, 1, 0));\n" \
|
||||||
"float light = 0.75 + max(nDotVP, 0.0);\n" \
|
"float light = 0.75 + max(nDotVP, 0.0);\n" \
|
||||||
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
|
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
|
||||||
|
@ -69,6 +69,7 @@
|
||||||
// Software fragment shader
|
// Software fragment shader
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Include GLSL_FLOOR_FUDGES or GLSL_WALL_FUDGES or define the fudges in shaders that use this macro.
|
||||||
#define GLSL_DOOM_COLORMAP \
|
#define GLSL_DOOM_COLORMAP \
|
||||||
"float R_DoomColormap(float light, float z)\n" \
|
"float R_DoomColormap(float light, float z)\n" \
|
||||||
"{\n" \
|
"{\n" \
|
||||||
|
@ -76,8 +77,12 @@
|
||||||
"float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \
|
"float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \
|
||||||
"float startmap = (15.0 - lightnum) * 4.0;\n" \
|
"float startmap = (15.0 - lightnum) * 4.0;\n" \
|
||||||
"float scale = 160.0 / (lightz + 1.0);\n" \
|
"float scale = 160.0 / (lightz + 1.0);\n" \
|
||||||
"return startmap - scale * 0.5;\n" \
|
"float cap = (155.0 - light) * 0.26;\n" \
|
||||||
|
"return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||||
"}\n"
|
"}\n"
|
||||||
|
// lighting cap adjustment:
|
||||||
|
// first num (155.0), increase to make it start to go dark sooner
|
||||||
|
// second num (0.26), increase to make it go dark faster
|
||||||
|
|
||||||
#define GLSL_DOOM_LIGHT_EQUATION \
|
#define GLSL_DOOM_LIGHT_EQUATION \
|
||||||
"float R_DoomLightingEquation(float light)\n" \
|
"float R_DoomLightingEquation(float light)\n" \
|
||||||
|
@ -106,7 +111,28 @@
|
||||||
"}\n" \
|
"}\n" \
|
||||||
"final_color = mix(final_color, fade_color, darkness);\n"
|
"final_color = mix(final_color, fade_color, darkness);\n"
|
||||||
|
|
||||||
|
#define GLSL_PALETTE_RENDERING \
|
||||||
|
"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" \
|
||||||
|
"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" \
|
||||||
|
|
||||||
#define GLSL_SOFTWARE_FRAGMENT_SHADER \
|
#define GLSL_SOFTWARE_FRAGMENT_SHADER \
|
||||||
|
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||||
|
"uniform sampler2D tex;\n" \
|
||||||
|
"uniform sampler3D palette_lookup_tex;\n" \
|
||||||
|
"uniform sampler2D lighttable_tex;\n" \
|
||||||
|
"uniform vec4 poly_color;\n" \
|
||||||
|
"uniform float lighting;\n" \
|
||||||
|
GLSL_DOOM_COLORMAP \
|
||||||
|
"void main(void) {\n" \
|
||||||
|
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||||
|
GLSL_PALETTE_RENDERING \
|
||||||
|
"}\n" \
|
||||||
|
"#else\n" \
|
||||||
"uniform sampler2D tex;\n" \
|
"uniform sampler2D tex;\n" \
|
||||||
"uniform vec4 poly_color;\n" \
|
"uniform vec4 poly_color;\n" \
|
||||||
"uniform vec4 tint_color;\n" \
|
"uniform vec4 tint_color;\n" \
|
||||||
|
@ -124,11 +150,45 @@
|
||||||
GLSL_SOFTWARE_FADE_EQUATION \
|
GLSL_SOFTWARE_FADE_EQUATION \
|
||||||
"final_color.a = texel.a * poly_color.a;\n" \
|
"final_color.a = texel.a * poly_color.a;\n" \
|
||||||
"gl_FragColor = final_color;\n" \
|
"gl_FragColor = final_color;\n" \
|
||||||
"}\0"
|
"}\n" \
|
||||||
|
"#endif\0"
|
||||||
|
|
||||||
|
// hand tuned adjustments for light level calculation
|
||||||
|
#define GLSL_FLOOR_FUDGES \
|
||||||
|
"#define STARTMAP_FUDGE 1.06\n" \
|
||||||
|
"#define SCALE_FUDGE 1.15\n"
|
||||||
|
|
||||||
|
#define GLSL_WALL_FUDGES \
|
||||||
|
"#define STARTMAP_FUDGE 1.05\n" \
|
||||||
|
"#define SCALE_FUDGE 2.2\n"
|
||||||
|
|
||||||
|
#define GLSL_SOFTWARE_FRAGMENT_SHADER_FLOORS \
|
||||||
|
GLSL_FLOOR_FUDGES \
|
||||||
|
GLSL_SOFTWARE_FRAGMENT_SHADER
|
||||||
|
|
||||||
|
#define GLSL_SOFTWARE_FRAGMENT_SHADER_WALLS \
|
||||||
|
GLSL_WALL_FUDGES \
|
||||||
|
GLSL_SOFTWARE_FRAGMENT_SHADER
|
||||||
|
|
||||||
// same as above but multiplies results with the lighting value from the
|
// same as above but multiplies results with the lighting value from the
|
||||||
// accompanying vertex shader (stored in gl_Color)
|
// accompanying vertex shader (stored in gl_Color) if model lighting is enabled
|
||||||
#define GLSL_SOFTWARE_MODEL_FRAGMENT_SHADER \
|
#define GLSL_SOFTWARE_MODEL_FRAGMENT_SHADER \
|
||||||
|
GLSL_WALL_FUDGES \
|
||||||
|
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||||
|
"uniform sampler2D tex;\n" \
|
||||||
|
"uniform sampler3D palette_lookup_tex;\n" \
|
||||||
|
"uniform sampler2D lighttable_tex;\n" \
|
||||||
|
"uniform vec4 poly_color;\n" \
|
||||||
|
"uniform float lighting;\n" \
|
||||||
|
GLSL_DOOM_COLORMAP \
|
||||||
|
"void main(void) {\n" \
|
||||||
|
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||||
|
"#ifdef SRB2_MODEL_LIGHTING\n" \
|
||||||
|
"texel *= gl_Color;\n" \
|
||||||
|
"#endif\n" \
|
||||||
|
GLSL_PALETTE_RENDERING \
|
||||||
|
"}\n" \
|
||||||
|
"#else\n" \
|
||||||
"uniform sampler2D tex;\n" \
|
"uniform sampler2D tex;\n" \
|
||||||
"uniform vec4 poly_color;\n" \
|
"uniform vec4 poly_color;\n" \
|
||||||
"uniform vec4 tint_color;\n" \
|
"uniform vec4 tint_color;\n" \
|
||||||
|
@ -144,12 +204,13 @@
|
||||||
"vec4 final_color = base_color;\n" \
|
"vec4 final_color = base_color;\n" \
|
||||||
GLSL_SOFTWARE_TINT_EQUATION \
|
GLSL_SOFTWARE_TINT_EQUATION \
|
||||||
GLSL_SOFTWARE_FADE_EQUATION \
|
GLSL_SOFTWARE_FADE_EQUATION \
|
||||||
"#ifdef MODEL_LIGHTING\n" \
|
"#ifdef SRB2_MODEL_LIGHTING\n" \
|
||||||
"final_color *= gl_Color;\n" \
|
"final_color *= gl_Color;\n" \
|
||||||
"#endif\n" \
|
"#endif\n" \
|
||||||
"final_color.a = texel.a * poly_color.a;\n" \
|
"final_color.a = texel.a * poly_color.a;\n" \
|
||||||
"gl_FragColor = final_color;\n" \
|
"gl_FragColor = final_color;\n" \
|
||||||
"}\0"
|
"}\n" \
|
||||||
|
"#endif\0"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Water surface shader
|
// Water surface shader
|
||||||
|
@ -158,7 +219,32 @@
|
||||||
// Still needs to distort things underneath/around the water...
|
// Still needs to distort things underneath/around the water...
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#define GLSL_WATER_TEXEL \
|
||||||
|
"float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
|
||||||
|
"float a = -pi * (water_z * freq) + (leveltime * speed);\n" \
|
||||||
|
"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"
|
||||||
|
|
||||||
#define GLSL_WATER_FRAGMENT_SHADER \
|
#define GLSL_WATER_FRAGMENT_SHADER \
|
||||||
|
GLSL_FLOOR_FUDGES \
|
||||||
|
"const float freq = 0.025;\n" \
|
||||||
|
"const float amp = 0.025;\n" \
|
||||||
|
"const float speed = 2.0;\n" \
|
||||||
|
"const float pi = 3.14159;\n" \
|
||||||
|
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||||
|
"uniform sampler2D tex;\n" \
|
||||||
|
"uniform sampler3D palette_lookup_tex;\n" \
|
||||||
|
"uniform sampler2D lighttable_tex;\n" \
|
||||||
|
"uniform vec4 poly_color;\n" \
|
||||||
|
"uniform float lighting;\n" \
|
||||||
|
"uniform float leveltime;\n" \
|
||||||
|
GLSL_DOOM_COLORMAP \
|
||||||
|
"void main(void) {\n" \
|
||||||
|
GLSL_WATER_TEXEL \
|
||||||
|
GLSL_PALETTE_RENDERING \
|
||||||
|
"}\n" \
|
||||||
|
"#else\n" \
|
||||||
"uniform sampler2D tex;\n" \
|
"uniform sampler2D tex;\n" \
|
||||||
"uniform vec4 poly_color;\n" \
|
"uniform vec4 poly_color;\n" \
|
||||||
"uniform vec4 tint_color;\n" \
|
"uniform vec4 tint_color;\n" \
|
||||||
|
@ -167,25 +253,18 @@
|
||||||
"uniform float fade_start;\n" \
|
"uniform float fade_start;\n" \
|
||||||
"uniform float fade_end;\n" \
|
"uniform float fade_end;\n" \
|
||||||
"uniform float leveltime;\n" \
|
"uniform float leveltime;\n" \
|
||||||
"const float freq = 0.025;\n" \
|
|
||||||
"const float amp = 0.025;\n" \
|
|
||||||
"const float speed = 2.0;\n" \
|
|
||||||
"const float pi = 3.14159;\n" \
|
|
||||||
GLSL_DOOM_COLORMAP \
|
GLSL_DOOM_COLORMAP \
|
||||||
GLSL_DOOM_LIGHT_EQUATION \
|
GLSL_DOOM_LIGHT_EQUATION \
|
||||||
"void main(void) {\n" \
|
"void main(void) {\n" \
|
||||||
"float z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
|
GLSL_WATER_TEXEL \
|
||||||
"float a = -pi * (z * freq) + (leveltime * speed);\n" \
|
|
||||||
"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" \
|
|
||||||
"vec4 base_color = texel * poly_color;\n" \
|
"vec4 base_color = texel * poly_color;\n" \
|
||||||
"vec4 final_color = base_color;\n" \
|
"vec4 final_color = base_color;\n" \
|
||||||
GLSL_SOFTWARE_TINT_EQUATION \
|
GLSL_SOFTWARE_TINT_EQUATION \
|
||||||
GLSL_SOFTWARE_FADE_EQUATION \
|
GLSL_SOFTWARE_FADE_EQUATION \
|
||||||
"final_color.a = texel.a * poly_color.a;\n" \
|
"final_color.a = texel.a * poly_color.a;\n" \
|
||||||
"gl_FragColor = final_color;\n" \
|
"gl_FragColor = final_color;\n" \
|
||||||
"}\0"
|
"}\n" \
|
||||||
|
"#endif\0"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Fog block shader
|
// Fog block shader
|
||||||
|
@ -193,7 +272,10 @@
|
||||||
// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha
|
// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// The floor fudges are used, but should the wall fudges be used instead? or something inbetween?
|
||||||
|
// or separate values for floors and walls? (need to change more than this shader for that)
|
||||||
#define GLSL_FOG_FRAGMENT_SHADER \
|
#define GLSL_FOG_FRAGMENT_SHADER \
|
||||||
|
GLSL_FLOOR_FUDGES \
|
||||||
"uniform vec4 tint_color;\n" \
|
"uniform vec4 tint_color;\n" \
|
||||||
"uniform vec4 fade_color;\n" \
|
"uniform vec4 fade_color;\n" \
|
||||||
"uniform float lighting;\n" \
|
"uniform float lighting;\n" \
|
||||||
|
@ -220,6 +302,19 @@
|
||||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\n" \
|
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\n" \
|
||||||
"}\0"
|
"}\0"
|
||||||
|
|
||||||
|
// Shader for the palette rendering postprocess step
|
||||||
|
#define GLSL_PALETTE_POSTPROCESS_SHADER \
|
||||||
|
"uniform sampler2D tex;\n" \
|
||||||
|
"uniform sampler3D palette_lookup_tex;\n" \
|
||||||
|
"uniform sampler1D screen_palette_tex;\n" \
|
||||||
|
"void main(void) {\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(screen_palette_tex, palette_coord);\n" \
|
||||||
|
"gl_FragColor = final_color;\n" \
|
||||||
|
"}\0"
|
||||||
|
|
||||||
// ================
|
// ================
|
||||||
// Shader sources
|
// Shader sources
|
||||||
// ================
|
// ================
|
||||||
|
@ -229,13 +324,13 @@ static struct {
|
||||||
const char *fragment;
|
const char *fragment;
|
||||||
} const gl_shadersources[] = {
|
} const gl_shadersources[] = {
|
||||||
// Floor shader
|
// Floor shader
|
||||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER},
|
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER_FLOORS},
|
||||||
|
|
||||||
// Wall shader
|
// Wall shader
|
||||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER},
|
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER_WALLS},
|
||||||
|
|
||||||
// Sprite shader
|
// Sprite shader
|
||||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER},
|
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER_WALLS},
|
||||||
|
|
||||||
// Model shader
|
// Model shader
|
||||||
{GLSL_MODEL_VERTEX_SHADER, GLSL_SOFTWARE_MODEL_FRAGMENT_SHADER},
|
{GLSL_MODEL_VERTEX_SHADER, GLSL_SOFTWARE_MODEL_FRAGMENT_SHADER},
|
||||||
|
@ -249,6 +344,9 @@ static struct {
|
||||||
// Sky shader
|
// Sky shader
|
||||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SKY_FRAGMENT_SHADER},
|
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_SKY_FRAGMENT_SHADER},
|
||||||
|
|
||||||
|
// Palette postprocess shader
|
||||||
|
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_PALETTE_POSTPROCESS_SHADER},
|
||||||
|
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,7 +370,8 @@ static shader_t gl_shaders[NUMSHADERTARGETS*2];
|
||||||
|
|
||||||
static shadertarget_t gl_shadertargets[NUMSHADERTARGETS];
|
static shadertarget_t gl_shadertargets[NUMSHADERTARGETS];
|
||||||
|
|
||||||
#define MODEL_LIGHTING_DEFINE "#define MODEL_LIGHTING"
|
#define MODEL_LIGHTING_DEFINE "#define SRB2_MODEL_LIGHTING"
|
||||||
|
#define PALETTE_RENDERING_DEFINE "#define SRB2_PALETTE_RENDERING"
|
||||||
|
|
||||||
// Initialize shader variables and the backend's shader system. Load the base shaders.
|
// Initialize shader variables and the backend's shader system. Load the base shaders.
|
||||||
// Returns false if shaders cannot be used.
|
// Returns false if shaders cannot be used.
|
||||||
|
@ -446,6 +545,8 @@ static char *HWR_PreprocessShader(char *original)
|
||||||
new_len = original_len;
|
new_len = original_len;
|
||||||
if (cv_glmodellighting.value)
|
if (cv_glmodellighting.value)
|
||||||
new_len += sizeof(MODEL_LIGHTING_DEFINE) - 1 + 2 * line_ending_len;
|
new_len += sizeof(MODEL_LIGHTING_DEFINE) - 1 + 2 * line_ending_len;
|
||||||
|
if (cv_glpaletterendering.value)
|
||||||
|
new_len += sizeof(PALETTE_RENDERING_DEFINE) - 1 + 2 * line_ending_len;
|
||||||
|
|
||||||
// Allocate memory for modified shader.
|
// Allocate memory for modified shader.
|
||||||
new_shader = Z_Malloc(new_len + 1, PU_STATIC, NULL);
|
new_shader = Z_Malloc(new_len + 1, PU_STATIC, NULL);
|
||||||
|
@ -458,16 +559,23 @@ static char *HWR_PreprocessShader(char *original)
|
||||||
read_pos += insertion_pos;
|
read_pos += insertion_pos;
|
||||||
write_pos += insertion_pos;
|
write_pos += insertion_pos;
|
||||||
|
|
||||||
|
#define WRITE_DEFINE(define) \
|
||||||
|
{ \
|
||||||
|
strcpy(write_pos, line_ending); \
|
||||||
|
write_pos += line_ending_len; \
|
||||||
|
strcpy(write_pos, define); \
|
||||||
|
write_pos += sizeof(define) - 1; \
|
||||||
|
strcpy(write_pos, line_ending); \
|
||||||
|
write_pos += line_ending_len; \
|
||||||
|
}
|
||||||
|
|
||||||
// Write the additions.
|
// Write the additions.
|
||||||
if (cv_glmodellighting.value)
|
if (cv_glmodellighting.value)
|
||||||
{
|
WRITE_DEFINE(MODEL_LIGHTING_DEFINE)
|
||||||
strcpy(write_pos, line_ending);
|
if (cv_glpaletterendering.value)
|
||||||
write_pos += line_ending_len;
|
WRITE_DEFINE(PALETTE_RENDERING_DEFINE)
|
||||||
strcpy(write_pos, MODEL_LIGHTING_DEFINE);
|
|
||||||
write_pos += sizeof(MODEL_LIGHTING_DEFINE) - 1;
|
#undef WRITE_DEFINE
|
||||||
strcpy(write_pos, line_ending);
|
|
||||||
write_pos += line_ending_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the part after our additions.
|
// Copy the part after our additions.
|
||||||
M_Memcpy(write_pos, read_pos, original_len - insertion_pos);
|
M_Memcpy(write_pos, read_pos, original_len - insertion_pos);
|
||||||
|
@ -557,6 +665,7 @@ customshaderxlat_t shaderxlat[] =
|
||||||
{"WaterRipple", SHADER_WATER},
|
{"WaterRipple", SHADER_WATER},
|
||||||
{"Fog", SHADER_FOG},
|
{"Fog", SHADER_FOG},
|
||||||
{"Sky", SHADER_SKY},
|
{"Sky", SHADER_SKY},
|
||||||
|
{"PalettePostprocess", SHADER_PALETTE_POSTPROCESS},
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -739,18 +848,13 @@ const char *HWR_GetShaderName(INT32 shader)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
if (shader)
|
for (i = 0; shaderxlat[i].type; i++)
|
||||||
{
|
{
|
||||||
for (i = 0; shaderxlat[i].type; i++)
|
if (shaderxlat[i].id == shader)
|
||||||
{
|
return shaderxlat[i].type;
|
||||||
if (shaderxlat[i].id == shader)
|
|
||||||
return shaderxlat[i].type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Default";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HWRENDER
|
#endif // HWRENDER
|
||||||
|
|
|
@ -34,12 +34,21 @@ struct GLRGBAFloat
|
||||||
GLfloat alpha;
|
GLfloat alpha;
|
||||||
};
|
};
|
||||||
typedef struct GLRGBAFloat 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
|
// CONSTANTS
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
|
static const GLubyte white[4] = { 255, 255, 255, 255 };
|
||||||
|
|
||||||
// With OpenGL 1.1+, the first texture should be 1
|
// With OpenGL 1.1+, the first texture should be 1
|
||||||
static GLuint NOTEXTURE_NUM = 0;
|
static GLuint NOTEXTURE_NUM = 0;
|
||||||
|
|
||||||
|
@ -55,6 +64,7 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE;
|
||||||
|
|
||||||
|
|
||||||
static GLuint tex_downloaded = 0;
|
static GLuint tex_downloaded = 0;
|
||||||
|
static GLuint lt_downloaded = 0; // currently bound lighttable texture
|
||||||
static GLfloat fov = 90.0f;
|
static GLfloat fov = 90.0f;
|
||||||
static FBITFIELD CurrentPolyFlags;
|
static FBITFIELD CurrentPolyFlags;
|
||||||
|
|
||||||
|
@ -62,7 +72,14 @@ static FBITFIELD CurrentPolyFlags;
|
||||||
static FTextureInfo *TexCacheTail = NULL;
|
static FTextureInfo *TexCacheTail = NULL;
|
||||||
static FTextureInfo *TexCacheHead = NULL;
|
static FTextureInfo *TexCacheHead = NULL;
|
||||||
|
|
||||||
RGBA_t myPaletteData[256];
|
// Linked list of all lighttables.
|
||||||
|
static LTListItem *LightTablesTail = NULL;
|
||||||
|
static LTListItem *LightTablesHead = 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
|
||||||
GLint screen_width = 0; // used by Draw2DLine()
|
GLint screen_width = 0; // used by Draw2DLine()
|
||||||
GLint screen_height = 0;
|
GLint screen_height = 0;
|
||||||
GLbyte screen_depth = 0;
|
GLbyte screen_depth = 0;
|
||||||
|
@ -377,6 +394,8 @@ typedef void (APIENTRY * PFNglTexEnvi) (GLenum target, GLenum pname, GLint param
|
||||||
static PFNglTexEnvi pglTexEnvi;
|
static PFNglTexEnvi pglTexEnvi;
|
||||||
typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint param);
|
typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint param);
|
||||||
static PFNglTexParameteri pglTexParameteri;
|
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);
|
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;
|
static PFNglTexImage2D pglTexImage2D;
|
||||||
typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||||
|
@ -400,6 +419,10 @@ static PFNglCopyTexSubImage2D pglCopyTexSubImage2D;
|
||||||
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
|
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
|
||||||
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
|
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
|
||||||
|
|
||||||
|
/* 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 */
|
/* 1.3 functions for multitexturing */
|
||||||
typedef void (APIENTRY *PFNglActiveTexture) (GLenum);
|
typedef void (APIENTRY *PFNglActiveTexture) (GLenum);
|
||||||
static PFNglActiveTexture pglActiveTexture;
|
static PFNglActiveTexture pglActiveTexture;
|
||||||
|
@ -444,6 +467,9 @@ static PFNglBlendEquation pglBlendEquation;
|
||||||
#ifndef GL_TEXTURE1
|
#ifndef GL_TEXTURE1
|
||||||
#define GL_TEXTURE1 0x84C1
|
#define GL_TEXTURE1 0x84C1
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef GL_TEXTURE2
|
||||||
|
#define GL_TEXTURE2 0x84C2
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 1.5 Parms */
|
/* 1.5 Parms */
|
||||||
#ifndef GL_ARRAY_BUFFER
|
#ifndef GL_ARRAY_BUFFER
|
||||||
|
@ -515,6 +541,7 @@ boolean SetupGLfunc(void)
|
||||||
|
|
||||||
GETOPENGLFUNC(pglTexEnvi, glTexEnvi)
|
GETOPENGLFUNC(pglTexEnvi, glTexEnvi)
|
||||||
GETOPENGLFUNC(pglTexParameteri, glTexParameteri)
|
GETOPENGLFUNC(pglTexParameteri, glTexParameteri)
|
||||||
|
GETOPENGLFUNC(pglTexImage1D, glTexImage1D)
|
||||||
GETOPENGLFUNC(pglTexImage2D, glTexImage2D)
|
GETOPENGLFUNC(pglTexImage2D, glTexImage2D)
|
||||||
GETOPENGLFUNC(pglTexSubImage2D, glTexSubImage2D)
|
GETOPENGLFUNC(pglTexSubImage2D, glTexSubImage2D)
|
||||||
|
|
||||||
|
@ -590,7 +617,12 @@ typedef enum
|
||||||
gluniform_fade_start,
|
gluniform_fade_start,
|
||||||
gluniform_fade_end,
|
gluniform_fade_end,
|
||||||
|
|
||||||
// misc. (custom shaders)
|
// palette rendering
|
||||||
|
gluniform_screen_palette_tex,
|
||||||
|
gluniform_palette_lookup_tex,
|
||||||
|
gluniform_lighttable_tex,
|
||||||
|
|
||||||
|
// misc.
|
||||||
gluniform_leveltime,
|
gluniform_leveltime,
|
||||||
|
|
||||||
gluniform_max,
|
gluniform_max,
|
||||||
|
@ -656,6 +688,9 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
void SetupGLFunc4(void)
|
void SetupGLFunc4(void)
|
||||||
{
|
{
|
||||||
|
/* 1.2 funcs */
|
||||||
|
pglTexImage3D = GetGLFunc("glTexImage3D");
|
||||||
|
/* 1.3 funcs */
|
||||||
pglActiveTexture = GetGLFunc("glActiveTexture");
|
pglActiveTexture = GetGLFunc("glActiveTexture");
|
||||||
pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f");
|
pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f");
|
||||||
pglClientActiveTexture = GetGLFunc("glClientActiveTexture");
|
pglClientActiveTexture = GetGLFunc("glClientActiveTexture");
|
||||||
|
@ -1496,6 +1531,9 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
||||||
w = pTexInfo->width;
|
w = pTexInfo->width;
|
||||||
h = pTexInfo->height;
|
h = pTexInfo->height;
|
||||||
|
|
||||||
|
if (w*h > 2048*2048 && pTexInfo->format != GL_TEXFMT_RGBA)
|
||||||
|
I_Error("Tried to convert too big texture: %dx%d", w, h);
|
||||||
|
|
||||||
if ((pTexInfo->format == GL_TEXFMT_P_8) ||
|
if ((pTexInfo->format == GL_TEXFMT_P_8) ||
|
||||||
(pTexInfo->format == GL_TEXFMT_AP_88))
|
(pTexInfo->format == GL_TEXFMT_AP_88))
|
||||||
{
|
{
|
||||||
|
@ -1889,11 +1927,31 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||||
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
|
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
|
||||||
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
|
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
|
||||||
|
|
||||||
// misc. (custom shaders)
|
// palette rendering
|
||||||
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
|
shader->uniforms[gluniform_screen_palette_tex] = GETUNI("screen_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
|
#undef GETUNI
|
||||||
|
|
||||||
|
// set permanent uniform values
|
||||||
|
#define UNIFORM_1(uniform, a, function) \
|
||||||
|
if (uniform != -1) \
|
||||||
|
function (uniform, a);
|
||||||
|
|
||||||
|
pglUseProgram(shader->program);
|
||||||
|
|
||||||
|
// texture unit numbers for the samplers used for palette rendering
|
||||||
|
UNIFORM_1(shader->uniforms[gluniform_screen_palette_tex], 2, pglUniform1i);
|
||||||
|
UNIFORM_1(shader->uniforms[gluniform_palette_lookup_tex], 1, pglUniform1i);
|
||||||
|
UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 2, pglUniform1i);
|
||||||
|
|
||||||
|
// restore gl shader state
|
||||||
|
pglUseProgram(gl_shaderstate.program);
|
||||||
|
#undef UNIFORM_1
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1956,6 +2014,14 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
|
||||||
fade.green = byte2float[pSurf->FadeColor.s.green];
|
fade.green = byte2float[pSurf->FadeColor.s.green];
|
||||||
fade.blue = byte2float[pSurf->FadeColor.s.blue];
|
fade.blue = byte2float[pSurf->FadeColor.s.blue];
|
||||||
fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
|
fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
|
||||||
|
|
||||||
|
if (pSurf->LightTableId && pSurf->LightTableId != lt_downloaded)
|
||||||
|
{
|
||||||
|
pglActiveTexture(GL_TEXTURE2);
|
||||||
|
pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId);
|
||||||
|
pglActiveTexture(GL_TEXTURE0);
|
||||||
|
lt_downloaded = pSurf->LightTableId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2148,9 +2214,6 @@ EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky)
|
||||||
pglDisableClientState(GL_COLOR_ARRAY);
|
pglDisableClientState(GL_COLOR_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
|
||||||
//
|
|
||||||
// ==========================================================================
|
|
||||||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
||||||
{
|
{
|
||||||
switch (IdState)
|
switch (IdState)
|
||||||
|
@ -2514,6 +2577,14 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
||||||
else if (Surface->PolyColor.s.alpha == 0xFF)
|
else if (Surface->PolyColor.s.alpha == 0xFF)
|
||||||
flags |= (PF_Occlude | PF_Masked);
|
flags |= (PF_Occlude | PF_Masked);
|
||||||
|
|
||||||
|
if (Surface->LightTableId && Surface->LightTableId != lt_downloaded)
|
||||||
|
{
|
||||||
|
pglActiveTexture(GL_TEXTURE2);
|
||||||
|
pglBindTexture(GL_TEXTURE_2D, Surface->LightTableId);
|
||||||
|
pglActiveTexture(GL_TEXTURE0);
|
||||||
|
lt_downloaded = Surface->LightTableId;
|
||||||
|
}
|
||||||
|
|
||||||
SetBlend(flags);
|
SetBlend(flags);
|
||||||
Shader_SetUniforms(Surface, &poly, &tint, &fade);
|
Shader_SetUniforms(Surface, &poly, &tint, &fade);
|
||||||
|
|
||||||
|
@ -3249,6 +3320,9 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
|
||||||
ClearBuffer(true, false, &clearColour);
|
ClearBuffer(true, false, &clearColour);
|
||||||
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
|
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
|
||||||
|
|
||||||
|
// prepare shader, if it is enabled
|
||||||
|
Shader_SetUniforms(NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
pglColor4ubv(white);
|
pglColor4ubv(white);
|
||||||
|
|
||||||
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
|
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
|
||||||
|
@ -3258,4 +3332,76 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
|
||||||
tex_downloaded = finalScreenTexture;
|
tex_downloaded = finalScreenTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut)
|
||||||
|
{
|
||||||
|
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, GL_R8, HWR_PALETTE_LUT_SIZE, HWR_PALETTE_LUT_SIZE, HWR_PALETTE_LUT_SIZE,
|
||||||
|
0, GL_RED, GL_UNSIGNED_BYTE, lut);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif //HWRENDER
|
#endif //HWRENDER
|
||||||
|
|
18
src/m_menu.c
18
src/m_menu.c
|
@ -1443,18 +1443,20 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
|
||||||
|
|
||||||
{IT_HEADER, NULL, "General", NULL, 51},
|
{IT_HEADER, NULL, "General", NULL, 51},
|
||||||
{IT_STRING|IT_CVAR, NULL, "Shaders", &cv_glshaders, 63},
|
{IT_STRING|IT_CVAR, NULL, "Shaders", &cv_glshaders, 63},
|
||||||
{IT_STRING|IT_CVAR, NULL, "Lack of perspective", &cv_glshearing, 73},
|
{IT_STRING|IT_CVAR, NULL, "Palette rendering", &cv_glpaletterendering, 73},
|
||||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 83},
|
{IT_STRING|IT_CVAR, NULL, "Palette bit depth", &cv_glpalettedepth, 83},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Lack of perspective", &cv_glshearing, 93},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 103},
|
||||||
|
|
||||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 102},
|
{IT_HEADER, NULL, "Miscellaneous", NULL, 122},
|
||||||
{IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 114},
|
{IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 134},
|
||||||
{IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_glfiltermode, 124},
|
{IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_glfiltermode, 144},
|
||||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_glanisotropicmode, 134},
|
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_glanisotropicmode, 154},
|
||||||
#ifdef ALAM_LIGHTING
|
#ifdef ALAM_LIGHTING
|
||||||
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 144},
|
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 164},
|
||||||
#endif
|
#endif
|
||||||
#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)))
|
#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)))
|
||||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 154},
|
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 174},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#include "byteptr.h"
|
#include "byteptr.h"
|
||||||
#include "dehacked.h"
|
#include "dehacked.h"
|
||||||
|
|
||||||
|
#ifdef HWRENDER
|
||||||
|
#include "hardware/hw_glob.h" // HWR_ClearLightTables
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Graphics.
|
// Graphics.
|
||||||
// SRB2 graphics for walls and sprites
|
// SRB2 graphics for walls and sprites
|
||||||
|
@ -425,6 +429,9 @@ void R_ClearColormaps(void)
|
||||||
{
|
{
|
||||||
// Purged by PU_LEVEL, just overwrite the pointer
|
// Purged by PU_LEVEL, just overwrite the pointer
|
||||||
extra_colormaps = R_CreateDefaultColormap(true);
|
extra_colormaps = R_CreateDefaultColormap(true);
|
||||||
|
#ifdef HWRENDER
|
||||||
|
HWR_ClearLightTables();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -69,6 +69,11 @@ typedef struct extracolormap_s
|
||||||
|
|
||||||
lighttable_t *colormap;
|
lighttable_t *colormap;
|
||||||
|
|
||||||
|
#ifdef HWRENDER
|
||||||
|
// The id of the hardware lighttable. Zero means it does not exist yet.
|
||||||
|
UINT32 gl_lighttable_id;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef EXTRACOLORMAPLUMPS
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
lumpnum_t lump; // for colormap lump matching, init to LUMPERROR
|
lumpnum_t lump; // for colormap lump matching, init to LUMPERROR
|
||||||
char lumpname[9]; // for netsyncing
|
char lumpname[9]; // for netsyncing
|
||||||
|
|
|
@ -74,7 +74,7 @@ void *hwSym(const char *funcName,void *handle)
|
||||||
{
|
{
|
||||||
void *funcPointer = NULL;
|
void *funcPointer = NULL;
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
if (0 == strcmp("SetPalette", funcName))
|
if (0 == strcmp("SetTexturePalette", funcName))
|
||||||
funcPointer = &OglSdlSetPalette;
|
funcPointer = &OglSdlSetPalette;
|
||||||
|
|
||||||
GETFUNC(Init);
|
GETFUNC(Init);
|
||||||
|
@ -113,6 +113,11 @@ void *hwSym(const char *funcName,void *handle)
|
||||||
|
|
||||||
GETFUNC(SetShaderInfo);
|
GETFUNC(SetShaderInfo);
|
||||||
|
|
||||||
|
GETFUNC(SetPaletteLookup);
|
||||||
|
GETFUNC(CreateLightTable);
|
||||||
|
GETFUNC(ClearLightTables);
|
||||||
|
GETFUNC(SetScreenPalette);
|
||||||
|
|
||||||
#else //HWRENDER
|
#else //HWRENDER
|
||||||
if (0 == strcmp("FinishUpdate", funcName))
|
if (0 == strcmp("FinishUpdate", funcName))
|
||||||
return funcPointer; //&FinishUpdate;
|
return funcPointer; //&FinishUpdate;
|
||||||
|
|
|
@ -1241,6 +1241,17 @@ void I_FinishUpdate(void)
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
else if (rendermode == render_opengl)
|
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(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS));
|
||||||
|
HWR_DrawScreenFinalTexture(vid.width, vid.height);
|
||||||
|
HWD.pfnUnSetShader();
|
||||||
|
HWD.pfnSetSpecialState(HWD_SET_SHADERS, 0);
|
||||||
|
}
|
||||||
OglSdlFinishUpdate(cv_vidwait.value);
|
OglSdlFinishUpdate(cv_vidwait.value);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1863,7 +1874,7 @@ void VID_StartupOpenGL(void)
|
||||||
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
|
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
|
||||||
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
|
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
|
||||||
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
||||||
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
|
HWD.pfnSetTexturePalette= hwSym("SetTexturePalette",NULL);
|
||||||
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
|
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
|
||||||
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
|
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
|
||||||
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
|
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
|
||||||
|
@ -1886,6 +1897,11 @@ void VID_StartupOpenGL(void)
|
||||||
|
|
||||||
HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL);
|
HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL);
|
||||||
|
|
||||||
|
HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL);
|
||||||
|
HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL);
|
||||||
|
HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL);
|
||||||
|
HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL);
|
||||||
|
|
||||||
vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library
|
vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library
|
||||||
|
|
||||||
if (vid.glstate == VID_GL_LIBRARY_ERROR)
|
if (vid.glstate == VID_GL_LIBRARY_ERROR)
|
||||||
|
|
|
@ -209,8 +209,8 @@ void ST_doPaletteStuff(void)
|
||||||
palette = 0;
|
palette = 0;
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
if (rendermode == render_opengl)
|
if (rendermode == render_opengl && !HWR_ShouldUsePaletteRendering())
|
||||||
palette = 0; // No flashpals here in OpenGL
|
palette = 0; // Don't set the palette to a flashpal in OpenGL's truecolor mode
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (palette != st_palette)
|
if (palette != st_palette)
|
||||||
|
@ -2786,7 +2786,7 @@ void ST_Drawer(void)
|
||||||
//25/08/99: Hurdler: palette changes is done for all players,
|
//25/08/99: Hurdler: palette changes is done for all players,
|
||||||
// not only player1! That's why this part
|
// not only player1! That's why this part
|
||||||
// of code is moved somewhere else.
|
// of code is moved somewhere else.
|
||||||
if (rendermode == render_soft)
|
if (rendermode == render_soft || HWR_ShouldUsePaletteRendering())
|
||||||
#endif
|
#endif
|
||||||
if (rendermode != render_none) ST_doPaletteStuff();
|
if (rendermode != render_none) ST_doPaletteStuff();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue