Paletteshader #71

Merged
alufolie91 merged 44 commits from paletteshader into Saturn 2023-09-18 15:51:59 +02:00
16 changed files with 614 additions and 141 deletions

No files matched your search

-1
View File
@@ -576,7 +576,6 @@ void HWR_SetPalette(RGBA_t *palette)
Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED);
}
}
// --------------------------------------------------------------------------
// Make sure texture is downloaded and set it as the source
// --------------------------------------------------------------------------
+2
View File
@@ -224,6 +224,7 @@ struct FSurfaceInfo
RGBA_t PolyColor;
RGBA_t TintColor;
RGBA_t FadeColor;
UINT32 LightTableId;
FLightInfo LightInfo; // jimita 14032019
};
typedef struct FSurfaceInfo FSurfaceInfo;
@@ -231,6 +232,7 @@ typedef struct FSurfaceInfo FSurfaceInfo;
enum hwdsetspecialstate
{
HWD_SET_SHADERS,
HWD_SET_PALETTE_SHADER_ENABLED,
HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE,
+6
View File
@@ -80,6 +80,9 @@ EXPORT void 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 UINT32 HWRAPI(AddLightTable) (UINT8 *lighttable);
EXPORT void HWRAPI(ClearLightTableCache) (void);
// ==========================================================================
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
// ==========================================================================
@@ -126,6 +129,9 @@ struct hwdriver_s
StartBatching pfnStartBatching;
RenderBatches pfnRenderBatches;
AddLightTable pfnAddLightTable;
ClearLightTableCache pfnClearLightTableCache;
};
extern struct hwdriver_s hwdriver;
+140 -99
View File
@@ -30,6 +30,7 @@
#include "../r_fps.h"
#include "../r_state.h"
#include "../r_local.h"
#include "../r_data.h"
#include "../r_patch.h" // a mystery as to what this is for
#include "../r_bsp.h" // R_NoEncore
#include "../r_main.h" // cv_fov
@@ -60,10 +61,14 @@ struct hwdriver_s hwdriver;
// Commands and console variables
// ==========================================================================
// keep the state here instead of in the cv var, so it always matches the state in r_opengl.c
int gr_use_palette_shader = 0;
static void CV_filtermode_ONChange(void);
static void CV_anisotropic_ONChange(void);
static void CV_screentextures_ONChange(void);
static void CV_useCustomShaders_ONChange(void);
static void CV_useCustomShaders_ONChange(void);
static void CV_grpaletteshader_OnChange(void);
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
@@ -115,7 +120,11 @@ static INT32 current_bsp_culling_distance = 0;
consvar_t cv_grscreentextures = {"gr_screentextures", "On", CV_CALL, CV_OnOff,
CV_screentextures_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_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_grpaletteshader_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grflashpal = {"gr_flashpal", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static void CV_filtermode_ONChange(void)
{
@@ -138,6 +147,16 @@ static void CV_useCustomShaders_ONChange(void)
HWD.pfnInitCustomShaders();
}
static void CV_grpaletteshader_OnChange(void)
{
if (rendermode == render_opengl)
{
HWD.pfnSetSpecialState(HWD_SET_PALETTE_SHADER_ENABLED, cv_grpaletteshader.value);
gr_use_palette_shader = cv_grpaletteshader.value;
V_SetPalette(0);
}
}
// ==========================================================================
// Globals
// ==========================================================================
@@ -400,6 +419,7 @@ static size_t gr_numportalcullsectors = 0;
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;
@@ -451,6 +471,37 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
Surface->LightInfo.light_level = light_level;
Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0;
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
if (gr_use_palette_shader)
{
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()
{
if (rendermode == render_opengl)
HWD.pfnClearLightTableCache();
}
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
@@ -723,7 +774,7 @@ void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedhei
else if (PolyFlags & PF_Ripple)
HWD.pfnSetShader(5); // water shader
else
HWD.pfnSetShader(1); // floor shader
HWD.pfnSetShader(gr_use_palette_shader ? 9 : 1); // floor shader
HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, false);
@@ -861,7 +912,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
break;
}
HWD.pfnSetShader(2); // wall shader
HWD.pfnSetShader(gr_use_palette_shader ? 10 : 2); // wall shader
HWD.pfnDrawPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal, false);
}
}
@@ -895,7 +946,7 @@ void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend
{
HWR_Lighting(pSurf, lightlevel, wallcolormap);
HWD.pfnSetShader(2); // wall shader
HWD.pfnSetShader(gr_use_palette_shader ? 10 : 2); // wall shader
// don't draw to color buffer when drawing to stencil
if (gl_drawing_stencil)
@@ -951,6 +1002,9 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa
pegb = wallVerts[0].t;
pegmul = (pegb - pegt) / (top - bot);
if (fpclassify(pegmul) == FP_NAN)
pegmul = 0.0;
#ifdef ESLOPE
endrealtop = endtop = wallVerts[2].y;
endrealbot = endbot = wallVerts[1].y;
@@ -959,6 +1013,8 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa
endpegmul = (endpegb - endpegt) / (endtop - endbot);
#endif
if (fpclassify(endpegmul) == FP_NAN)
endpegmul = 0.0;
for (i = 0; i < sector->numlights; i++)
{
@@ -972,13 +1028,15 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa
{
if (pfloor && (pfloor->flags & FF_FOG))
{
lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y);
colormap = pfloor->master->frontsector->extra_colormap;
lightnum = pfloor->master->frontsector->lightlevel;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
}
else
{
lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y);
colormap = list[i].extra_colormap;
lightnum = *list[i].lightlevel;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
}
}
@@ -1070,7 +1128,8 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa
#endif
#ifdef ESLOPE
if (endbheight >= endtop)
if (endbheight > endtop)
endbot = endtop;
#endif
if (bheight >= top)
continue;
@@ -1080,13 +1139,11 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa
if (bot < realbot)
bot = realbot;
#ifdef ESLOPE
endbot = endbheight;
if (endbot < endrealbot)
endbot = endrealbot;
#ifdef ESLOPE
endbot = min(max(endbheight, endrealbot), endtop);
#endif
Surf->PolyColor.s.alpha = alpha;
#ifdef ESLOPE
@@ -1379,8 +1436,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT));
}
lightnum = HWR_CalcWallLight(gr_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
colormap = gr_frontsector->extra_colormap;
lightnum = gr_frontsector->lightlevel;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
if (gr_frontsector)
Surf.PolyColor.s.alpha = 255;
@@ -1680,10 +1738,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
if (gr_midtexture || gr_portal == GRPORTAL_STENCIL || gr_portal == GRPORTAL_DEPTH || gl_drawing_stencil)
{
FBITFIELD blendmode;
sector_t *front, *back;
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
fixed_t texturevpeg = 0;
INT32 repeats;
if (gr_linedef->frontsector->heightsec != -1)
@@ -1719,6 +1774,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else
repeats = 1;
fixed_t midtexheight = textureheight[gr_midtexture] * repeats;
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
// SoM: a little note: This code re-arranging will
// fix the bug in Nimrod map02. popentop and popenbottom
// record the limits the texture can be displayed in.
@@ -1732,8 +1791,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// From CB
if (gr_curline->polyseg)
{
popentop = back->ceilingheight;
popenbottom = back->floorheight;
popentop = popentopslope = back->ceilingheight;
popenbottom = popenbottomslope = back->floorheight;
}
else
#endif
@@ -1741,10 +1800,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
#ifdef ESLOPE
popentop = min(worldtop, worldhigh);
popenbottom = max(worldbottom, worldlow);
#else
popentop = min(front->ceilingheight, back->ceilingheight);
popenbottom = max(front->floorheight, back->floorheight);
#endif
popentopslope = min(worldtopslope, worldhighslope);
popenbottomslope = max(worldbottomslope, worldlowslope);
}
#ifdef ESLOPE
@@ -1753,12 +1811,16 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
{
polybottom = max(front->floorheight, back->floorheight) + gr_sidedef->rowoffset;
polytop = polybottom + textureheight[gr_midtexture]*repeats;
polybottomslope = polybottom;
polytop = polybottom + midtexheight;
polytopslope = polytop;
}
else
{
polytop = min(front->ceilingheight, back->ceilingheight) + gr_sidedef->rowoffset;
polybottom = polytop - textureheight[gr_midtexture]*repeats;
polytopslope = polytop;
polybottom = polytop - midtexheight;
polybottomslope = polybottom;
}
}
else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
@@ -1767,12 +1829,17 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
#endif
{
polybottom = popenbottom + gr_sidedef->rowoffset;
polytop = polybottom + textureheight[gr_midtexture]*repeats;
polytop = polybottom + midtexheight;
polybottomslope = popenbottomslope + gr_sidedef->rowoffset;
polytopslope = polybottomslope + midtexheight;
}
else
{
polytop = popentop + gr_sidedef->rowoffset;
polybottom = polytop - textureheight[gr_midtexture]*repeats;
polybottom = polytop - midtexheight;
polytopslope = popentopslope + gr_sidedef->rowoffset;
polybottomslope = polytopslope - midtexheight;
}
// CB
@@ -1783,6 +1850,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
lowcut = polybottom;
highcut = polytop;
lowcutslope = polybottomslope;
highcutslope = polytopslope;
}
#endif
else
@@ -1790,83 +1859,49 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
lowcut = popenbottom;
highcut = popentop;
lowcutslope = popenbottomslope;
highcutslope = popentopslope;
}
h = min(highcut, polytop);
l = max(polybottom, lowcut);
hS = min(highcutslope, polytopslope);
lS = max(polybottomslope, lowcutslope);
// PEGGING
fixed_t texturevpeg, texturevpegslope;
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
{
// PEGGING
#ifdef ESLOPE
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
#else
if (gr_linedef->flags & ML_DONTPEGBOTTOM)
#endif
texturevpeg = textureheight[gr_sidedef->midtexture]*repeats - h + polybottom;
else
texturevpeg = polytop - h;
texturevpeg = midtexheight - h + polybottom;
texturevpegslope = midtexheight - hS + polybottomslope;
}
else
{
texturevpeg = polytop - h;
texturevpegslope = polytopslope - hS;
}
grTex = HWR_GetTexture(gr_midtexture);
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
}
wallVerts[3].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
wallVerts[2].t = texturevpegslope * grTex->scaleY;
wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// set top/bottom coords
// Take the texture peg into account, rather than changing the offsets past
// where the polygon might not be.
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l);
#ifdef ESLOPE
// Correct to account for slopes
{
fixed_t midtextureslant;
if (gr_linedef->flags & ML_EFFECT2)
midtextureslant = 0;
else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
midtextureslant = worldlow < worldbottom
? worldbottomslope-worldbottom
: worldlowslope-worldlow;
else
midtextureslant = worldtop < worldhigh
? worldtopslope-worldtop
: worldhighslope-worldhigh;
polytop += midtextureslant;
polybottom += midtextureslant;
highcut += worldtop < worldhigh
? worldtopslope-worldtop
: worldhighslope-worldhigh;
lowcut += worldlow < worldbottom
? worldbottomslope-worldbottom
: worldlowslope-worldlow;
// Texture stuff
h = min(highcut, polytop);
l = max(polybottom, lowcut);
{
// PEGGING
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
texturevpeg = textureheight[gr_sidedef->midtexture]*repeats - h + polybottom;
else
texturevpeg = polytop - h;
wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY;
}
wallVerts[2].y = FIXED_TO_FLOAT(h);
wallVerts[1].y = FIXED_TO_FLOAT(l);
}
wallVerts[3].y = FIXED_TO_FLOAT(h);
wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[1].y = FIXED_TO_FLOAT(lS);
#endif
// set alpha for transparent walls (new boom and legacy linedef types)
// ooops ! this do not work at all because render order we should render it in backtofront order
FBITFIELD blendmode;
switch (gr_linedef->special)
{
@@ -2224,8 +2259,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
blendmode = PF_Fog|PF_NoTexture;
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
colormap = rover->master->frontsector->extra_colormap;
lightnum = rover->master->frontsector->lightlevel;
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);
@@ -2347,8 +2384,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
blendmode = PF_Fog|PF_NoTexture;
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
colormap = rover->master->frontsector->extra_colormap;
lightnum = rover->master->frontsector->lightlevel;
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);
@@ -3055,7 +3093,7 @@ void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t
else
blendmode |= PF_Masked|PF_Modulated;
HWD.pfnSetShader(1); // floor shader
HWD.pfnSetShader(gr_use_palette_shader ? 9 : 1); // floor shader
HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, false);
}
@@ -3854,7 +3892,7 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
if (sSurf.PolyColor.s.alpha > floorheight/4)
{
sSurf.PolyColor.s.alpha = (UINT8)(sSurf.PolyColor.s.alpha - floorheight/4);
HWD.pfnSetShader(1); // floor shader
HWD.pfnSetShader(gr_use_palette_shader ? 9 : 1); // floor shader
HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated, false);
}
}
@@ -4221,7 +4259,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
Surf.PolyColor.s.alpha = alpha;
HWD.pfnSetShader(3); // sprite shader
HWD.pfnSetShader(gr_use_palette_shader ? 10 : 3); // sprite shader
HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false);
top = bot;
@@ -4261,7 +4299,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
Surf.PolyColor.s.alpha = alpha;
HWD.pfnSetShader(3); // sprite shader
HWD.pfnSetShader(gr_use_palette_shader ? 10 : 3); // sprite shader
HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false);
}
@@ -4414,7 +4452,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
blend = PF_Translucent|PF_Occlude;
}
HWD.pfnSetShader(3); // sprite shader
HWD.pfnSetShader(gr_use_palette_shader ? 10 : 3); // sprite shader
HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false);
}
}
@@ -4508,7 +4546,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
blend = PF_Translucent|PF_Occlude;
}
HWD.pfnSetShader(3); // sprite shader
HWD.pfnSetShader(gr_use_palette_shader ? 10 : 3); // sprite shader
HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, false);
}
@@ -6056,6 +6094,8 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_portalline);
CV_RegisterVar(&cv_portalonly);
CV_RegisterVar(&cv_secbright);
CV_RegisterVar(&cv_grpaletteshader);
CV_RegisterVar(&cv_grflashpal);
}
// --------------------------------------------------------------------------
@@ -6097,7 +6137,6 @@ void HWR_Startup(void)
}
}
// --------------------------------------------------------------------------
// Free resources allocated by the hardware renderer
// --------------------------------------------------------------------------
@@ -6119,8 +6158,6 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting
HWD.pfnSetShader(2); // wall shader
if (blend & PF_Environment)
blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects
@@ -6132,6 +6169,8 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency
if (!fogwall)
HWD.pfnSetShader(gr_use_palette_shader ? 10 : 2); // wall shader
HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode, false);
#ifdef WALLSPLATS
@@ -6163,7 +6202,7 @@ void HWR_DoPostProcessor(player_t *player)
// Armageddon Blast Flash!
// Could this even be considered postprocessor?
if (player->flashcount)
if (player->flashcount && !cv_grpaletteshader.value || player->flashcount && cv_grpaletteshader.value && !cv_grflashpal.value)
{
FOutVector v[4];
FSurfaceInfo Surf;
@@ -6292,6 +6331,8 @@ void HWR_MakeScreenFinalTexture(void)
void HWR_DrawScreenFinalTexture(int width, int height)
{
if (gr_use_palette_shader)
HWD.pfnSetShader(11); //post processing
HWD.pfnDrawScreenFinalTexture(width, height);
}
+4
View File
@@ -142,6 +142,8 @@ 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);
@@ -179,6 +181,8 @@ 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_grflashpal;
extern consvar_t cv_grportals;
extern consvar_t cv_nostencil;
extern consvar_t cv_secbright;
+394 -20
View File
@@ -26,10 +26,15 @@
#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)
// Eeeeh not sure is this right way, but it works
#include "../hw_main.h"
// Eeeeh not sure is this right way, but it works < sry :c
extern consvar_t cv_grusecustomshaders;
extern fixed_t fovtan; // also extremely bad, I'm just too lazy!!!
@@ -44,12 +49,15 @@ struct GLRGBAFloat
GLfloat alpha;
};
typedef struct GLRGBAFloat GLRGBAFloat;
static const GLubyte white[4] = { 255, 255, 255, 255 };
// ==========================================================================
// CONSTANTS
// ==========================================================================
// With OpenGL 1.1+, the first texture should be 1
#define NOTEXTURE_NUM 0
@@ -70,8 +78,17 @@ static GLuint tex_downloaded = 0;
static GLfloat fov = 90.0f;
static FBITFIELD CurrentPolyFlags;
static FTextureInfo* gr_cachetail = NULL;
static FTextureInfo* gr_cachehead = NULL;
static FTextureInfo *gr_cachetail = NULL;
static FTextureInfo *gr_cachehead = NULL;
typedef struct LightTableCacheEntry_s
{
GLuint id;
struct LightTableCacheEntry_s *next;
} LightTableCacheEntry_t;
LightTableCacheEntry_t *ltcachehead = NULL;
LightTableCacheEntry_t *ltcachetail = NULL;
RGBA_t myPaletteData[256];
GLint screen_width = 0; // used by Draw2DLine()
@@ -235,6 +252,7 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...)
#define pglTexEnvi glTexEnvi
#define pglTexParameteri glTexParameteri
#define pglTexImage2D glTexImage2D
#define pglTexImage3D glTexImage3D
/* Fog */
#define pglFogf glFogf
@@ -355,6 +373,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint
static PFNglTexParameteri pglTexParameteri;
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;
/* Fog */
typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param);
@@ -511,6 +531,7 @@ 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);
@@ -532,6 +553,7 @@ static PFNglLinkProgram pglLinkProgram;
static PFNglGetProgramiv pglGetProgramiv;
static PFNglUseProgram pglUseProgram;
static PFNglUniform1i pglUniform1i;
static PFNglUniform1iv pglUniform1iv;
static PFNglUniform1f pglUniform1f;
static PFNglUniform2f pglUniform2f;
static PFNglUniform3f pglUniform3f;
@@ -555,6 +577,10 @@ static boolean gl_shaderprogramchanged = true;
static boolean gl_batching = false;// are we currently collecting batches?
static GLint gl_palette[768];
static INT32 gl_use_palette_shader = 0;
boolean gl_palette_initialized = false;
static INT32 gl_enable_screen_textures = 1;
static GLint gl_portal_stencil_level = 0;
@@ -571,10 +597,15 @@ typedef enum
gluniform_lighting,
gluniform_fade_start,
gluniform_fade_end,
// misc. (custom shaders)
// palette rendering
gluniform_palette,
gluniform_color_lookup,
gluniform_lighttable_tex,
// misc.
gluniform_leveltime,
gluniform_max,
} gluniform_t;
@@ -594,6 +625,18 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS];
// GLSL Software fragment shader
//
#define GLSL_DOOM_COLORMAP_floors \
"float R_DoomColormap(float light, float z)\n" \
"{\n" \
"float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \
"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 * 1.06 - scale * 0.5 * 1.15;\n" \
"}\n"
// 1.06 and 1.15 were chosen when trying to match software lighting in a test map
#define GLSL_DOOM_COLORMAP \
"float R_DoomColormap(float light, float z)\n" \
"{\n" \
@@ -604,6 +647,16 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS];
"return startmap - scale * 0.5;\n" \
"}\n"
#define GLSL_DOOM_COLORMAP_walls \
"float R_DoomColormap(float light, float z)\n" \
"{\n" \
"float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \
"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 * 1.05 - scale * 1.0 * 1.1;\n" \
"}\n"
#define GLSL_DOOM_LIGHT_EQUATION \
"float R_DoomLightingEquation(float light)\n" \
"{\n" \
@@ -631,16 +684,16 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS];
"}\n" \
"final_color = mix(final_color, fade_color, darkness);\n"
#define GLSL_SOFTWARE_FRAGMENT_SHADER \
#define GLSL_SOFTWARE_UNIFORMS \
"uniform sampler2D tex;\n" \
"uniform vec4 poly_color;\n" \
"uniform vec4 tint_color;\n" \
"uniform vec4 fade_color;\n" \
"uniform float lighting;\n" \
"uniform float fade_start;\n" \
"uniform float fade_end;\n" \
GLSL_DOOM_COLORMAP \
GLSL_DOOM_LIGHT_EQUATION \
"uniform float fade_end;\n"
#define GLSL_SOFTWARE_MAIN \
"void main(void) {\n" \
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
"vec4 base_color = texel * poly_color;\n" \
@@ -649,7 +702,59 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS];
GLSL_SOFTWARE_FADE_EQUATION \
"final_color.a = texel.a * poly_color.a;\n" \
"gl_FragColor = final_color;\n" \
"}\0"
"}\n"
#define GLSL_SOFTWARE_FRAGMENT_SHADER_FLOORS \
GLSL_SOFTWARE_UNIFORMS \
GLSL_DOOM_COLORMAP_floors \
GLSL_DOOM_LIGHT_EQUATION \
GLSL_SOFTWARE_MAIN \
"\0"
#define GLSL_SOFTWARE_FRAGMENT_SHADER_WALLS \
GLSL_SOFTWARE_UNIFORMS \
GLSL_DOOM_COLORMAP_walls \
GLSL_DOOM_LIGHT_EQUATION \
GLSL_SOFTWARE_MAIN \
"\0"
#define GLSL_SOFTWARE_PAL_UNIFORMS \
"uniform sampler2D 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 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" \
"final_color.a = texel.a * poly_color.a;\n" \
"gl_FragColor = final_color;\n" \
"}\n"
#define GLSL_SOFTWARE_PAL_FRAGMENT_SHADER_FLOORS \
GLSL_SOFTWARE_PAL_UNIFORMS \
GLSL_DOOM_COLORMAP_floors \
GLSL_SOFTWARE_PAL_MAIN \
"\0"
#define GLSL_SOFTWARE_PAL_FRAGMENT_SHADER_WALLS \
GLSL_SOFTWARE_PAL_UNIFORMS \
GLSL_DOOM_COLORMAP_walls \
GLSL_SOFTWARE_PAL_MAIN \
"\0"
#define GLSL_SOFTWARE_PAL_FRAGMENT_SHADER_POSTPROCESS \
GLSL_SOFTWARE_PAL_UNIFORMS \
GLSL_SOFTWARE_PAL_MAIN \
"\0"
//
// Water surface shader
@@ -708,6 +813,20 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS];
GLSL_SOFTWARE_FADE_EQUATION \
"gl_FragColor = final_color;\n" \
"}\0"
//
// Palette color quantization shader
//
#define GLSL_PALETTE_FRAGMENT_SHADER \
"uniform sampler2D tex;\n" \
"uniform sampler3D lookup_tex;\n" \
"uniform int palette[768];\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" \
"}\0"
//
// GLSL generic fragment shader
@@ -725,16 +844,16 @@ static const char *fragment_shaders[] = {
GLSL_DEFAULT_FRAGMENT_SHADER,
// Floor fragment shader
GLSL_SOFTWARE_FRAGMENT_SHADER,
GLSL_SOFTWARE_FRAGMENT_SHADER_FLOORS,
// Wall fragment shader
GLSL_SOFTWARE_FRAGMENT_SHADER,
GLSL_SOFTWARE_FRAGMENT_SHADER_WALLS,
// Sprite fragment shader
GLSL_SOFTWARE_FRAGMENT_SHADER,
GLSL_SOFTWARE_FRAGMENT_SHADER_WALLS,
// Model fragment shader
GLSL_SOFTWARE_FRAGMENT_SHADER,
GLSL_SOFTWARE_FRAGMENT_SHADER_WALLS,
// Water fragment shader
GLSL_WATER_FRAGMENT_SHADER,
@@ -747,6 +866,15 @@ static const char *fragment_shaders[] = {
"void main(void) {\n"
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n"
"}\0",
// Palette fragment shader
GLSL_PALETTE_FRAGMENT_SHADER,
GLSL_SOFTWARE_PAL_FRAGMENT_SHADER_FLOORS,
GLSL_SOFTWARE_PAL_FRAGMENT_SHADER_WALLS,
GLSL_SOFTWARE_PAL_FRAGMENT_SHADER_POSTPROCESS,
NULL,
};
@@ -792,6 +920,13 @@ static const char *vertex_shaders[] = {
// Sky vertex shader
GLSL_DEFAULT_VERTEX_SHADER,
// Palette vertex shader
GLSL_DEFAULT_VERTEX_SHADER,
GLSL_DEFAULT_VERTEX_SHADER,
GLSL_DEFAULT_VERTEX_SHADER,
NULL,
};
@@ -800,6 +935,7 @@ static const char *vertex_shaders[] = {
void SetupGLFunc4(void)
{
pglTexImage3D = GetGLFunc("glTexImage3D");
pglActiveTexture = GetGLFunc("glActiveTexture");
pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f");
pglClientActiveTexture = GetGLFunc("glClientActiveTexture");
@@ -826,6 +962,7 @@ void SetupGLFunc4(void)
pglGetProgramiv = GetGLFunc("glGetProgramiv");
pglUseProgram = GetGLFunc("glUseProgram");
pglUniform1i = GetGLFunc("glUniform1i");
pglUniform1iv = GetGLFunc("glUniform1iv");
pglUniform1f = GetGLFunc("glUniform1f");
pglUniform2f = GetGLFunc("glUniform2f");
pglUniform3f = GetGLFunc("glUniform3f");
@@ -858,12 +995,13 @@ EXPORT boolean HWRAPI(LoadShaders) (void)
const GLchar* vert_shader = vertex_shaders[i];
const GLchar* frag_shader = fragment_shaders[i];
boolean custom = cv_grusecustomshaders.value && ((gl_customvertexshaders[i] || gl_customfragmentshaders[i]) && (i > 0));
// 18032019
if (cv_grusecustomshaders.value && gl_customvertexshaders[i])
vert_shader = gl_customvertexshaders[i];
if (cv_grusecustomshaders.value && gl_customfragmentshaders[i])
frag_shader = gl_customfragmentshaders[i];
if (i >= MAXSHADERS)
break;
@@ -946,11 +1084,38 @@ EXPORT boolean HWRAPI(LoadShaders) (void)
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
// palette rendering
shader->uniforms[gluniform_palette] = GETUNI("palette");
shader->uniforms[gluniform_color_lookup] = GETUNI("lookup_tex");
shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex");
// misc. (custom shaders)
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
#undef GETUNI
// set permanent uniform values
#define UNIFORM_1(uniform, a, function) \
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_lighttable_tex], 2, pglUniform1i);
pglUseProgram(0);
#undef UNIFORM_1
#undef UNIFORM_2
}
#endif
return true;
@@ -962,7 +1127,9 @@ EXPORT boolean HWRAPI(LoadShaders) (void)
EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment)
{
#ifdef GL_SHADERS
if (!pglUseProgram) return;
if (!pglUseProgram)
return;
if (number < 1 || number > MAXSHADERS)
I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS);
@@ -984,8 +1151,14 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boo
EXPORT void HWRAPI(InitCustomShaders) (void)
{
#ifdef GL_SHADERS
KillShaders();
LoadShaders();
if (gl_use_palette_shader)
{
InitPalette(0, false);
}
#endif
}
@@ -1022,6 +1195,105 @@ 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!
void 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)
{
// 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)
I_Error("pglTexImage3D is NULL!");
pglTexImage3D(GL_TEXTURE_3D, 0, GL_R8, 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);
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
// -----------------+
@@ -1201,6 +1473,46 @@ 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;
pglGenTextures(1, &ltcachetail->id);
if (!ltcachetail->id)
I_Error("hwr lighttable cache entry id is zero");
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, GL_R8, 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
@@ -1312,6 +1624,9 @@ 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)
InitPalette(0, false); // just gonna put this here for now
}
@@ -1886,6 +2201,12 @@ static int comparePolygons(const void *p1, const void *p2)
diff = poly1->texNum - poly2->texNum;
if (diff != 0) return diff;
if (gl_use_palette_shader)
{
diff = poly1->surf.LightTableId - poly2->surf.LightTableId;
if (diff != 0) return diff;
}
diff = poly1->polyFlags - poly2->polyFlags;
if (diff != 0) return diff;
@@ -2024,7 +2345,15 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
firstFade.alpha = byte2float[currentSurfaceInfo.FadeColor.s.alpha];
if (gl_allowshaders)
{
load_shaders(&currentSurfaceInfo, &firstPoly, &firstTint, &firstFade);
if (gl_use_palette_shader)
{
pglActiveTexture(GL_TEXTURE2);// this stuff could be done better but gonna do it quick like this for now
pglBindTexture(GL_TEXTURE_2D, currentSurfaceInfo.LightTableId);
pglActiveTexture(GL_TEXTURE0);
}
}
if (currentPolyFlags & PF_NoTexture)
currentTexture = 0;
@@ -2135,7 +2464,21 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
changeState = true;
changePolyFlags = true;
}
if (gl_allowshaders)
if ((gl_allowshaders) && (gl_use_palette_shader))
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end ||
currentSurfaceInfo.LightTableId != nextSurfaceInfo.LightTableId)
{
changeState = true;
changeSurfaceInfo = true;
}
}
else if ((gl_allowshaders) && (!gl_use_palette_shader))
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
@@ -2265,7 +2608,15 @@ EXPORT void HWRAPI(RenderBatches) (precise_t *sSortTime, precise_t *sDrawTime, i
fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha];
load_shaders(&nextSurfaceInfo, &poly, &tint, &fade);
if (gl_use_palette_shader)
{
pglActiveTexture(GL_TEXTURE2);// this stuff could be done better but gonna do it quick like this for now
pglBindTexture(GL_TEXTURE_2D, nextSurfaceInfo.LightTableId);
pglActiveTexture(GL_TEXTURE0);
}
}
currentSurfaceInfo = nextSurfaceInfo;
changeSurfaceInfo = false;
@@ -2365,6 +2716,13 @@ 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_use_palette_shader && gl_allowshaders)
{
pglActiveTexture(GL_TEXTURE2);
pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId);
pglActiveTexture(GL_TEXTURE0);
}
}
load_shaders(pSurf, &poly, &tint, &fade);
@@ -2707,6 +3065,10 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
break;
}
break;
case HWD_SET_PALETTE_SHADER_ENABLED:
gl_use_palette_shader = Value;
break;
case HWD_SET_TEXTUREFILTERMODE:
switch (Value)
@@ -3775,6 +4137,12 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
clearColour.alpha = 1;
ClearBuffer(true, false, false, &clearColour);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (gl_use_palette_shader && cv_grshaders.value)
{
pglUseProgram(gl_shaderprograms[8].program); // palette shader
pglActiveTexture(GL_TEXTURE1);
}
pglColor4ubv(white);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
@@ -3783,6 +4151,12 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex_downloaded = finalScreenTexture;
if (gl_use_palette_shader && cv_grshaders.value)
{
pglUseProgram(0);
pglActiveTexture(GL_TEXTURE0);
}
}
#endif //HWRENDER
+4
View File
@@ -133,4 +133,8 @@ typedef enum
GLF_NOTEXENV = 0x02,
} oglflags_t;
// in order for custom playpals n shit to work properly
extern boolean gl_palette_initialized;
void InitPalette(int flashnum, boolean skiplut);
#endif
+5 -4
View File
@@ -1347,7 +1347,8 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "3D Models", &cv_grmdls, 5},
{IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_grfallbackplayermodel, 15},
{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, "Use custom Shaders", &cv_grusecustomshaders, 35},
{IT_STRING|IT_CVAR, NULL, "Palette Rendering", &cv_grpaletteshader, 35},
{IT_STRING | IT_CVAR, NULL, "Min Shader Brightness", &cv_secbright, 45},
{IT_STRING|IT_CVAR, NULL, "Texture Quality", &cv_scr_depth, 65},
@@ -1407,7 +1408,6 @@ static menuitem_t OP_SoundOptionsMenu[] =
{IT_STRING|IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 155}
};
static menuitem_t OP_SoundAdvancedMenu[] =
{
#ifdef HAVE_OPENMPT
@@ -1706,8 +1706,9 @@ static menuitem_t OP_SaturnMenu[] =
{IT_STRING | IT_CVAR, NULL, "Show Minimap Names", &cv_showminimapnames, 80},
{IT_STRING | IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 90},
{IT_STRING | IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 110},
{IT_SUBMENU|IT_STRING, NULL, "Player distortion...", &OP_PlayerDistortDef, 130},
{IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 145},
{IT_STRING | IT_CVAR, NULL, "Flashpals in Palette Renderer", &cv_grflashpal, 120},
{IT_SUBMENU|IT_STRING, NULL, "Player distortion...", &OP_PlayerDistortDef, 140},
{IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 155},
{IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 170}, // uwu
};
+13 -5
View File
@@ -26,6 +26,10 @@
#include "v_video.h" // pLocalPalette
#include "dehacked.h"
#ifdef HWRENDER
#include "hardware/hw_main.h"
#endif
#if defined (_WIN32) || defined (_WIN32_WCE)
#include <malloc.h> // alloca(sizeof)
#endif
@@ -1137,6 +1141,10 @@ void R_ClearColormaps(void)
foundcolormaps[i] = LUMPERROR;
memset(extra_colormaps, 0, sizeof (extra_colormaps));
#ifdef HWRENDER
HWR_ClearLightTableCache();
#endif
}
/*INT32 R_ColormapNumForName(char *name)
@@ -1316,13 +1324,13 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
extra_colormaps[mapnum].fadestart = (UINT16)fadestart;
extra_colormaps[mapnum].fadeend = (UINT16)fadeend;
extra_colormaps[mapnum].fog = fog;
if (rendermode == render_soft)
{
if (rendermode == render_soft || rendermode == render_opengl)
{
double r, g, b, cbrightness;
int p;
lighttable_t *colormap_p;
// Initialise the map and delta arrays
// map[i] stores an RGB color (as double) for index i,
// which is then converted to SRB2's palette later
@@ -1402,7 +1410,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
}
}
}
return (INT32)mapnum;
}
-2
View File
@@ -104,6 +104,4 @@ UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
extern INT32 numtextures;
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
#endif
+6
View File
@@ -62,6 +62,12 @@ 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.
UINT32 gl_lighttable_id;
#endif
} extracolormap_t;
//
+2
View File
@@ -1955,6 +1955,8 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_grshearing);
CV_RegisterVar(&cv_grshaders);
CV_RegisterVar(&cv_grusecustomshaders);
CV_RegisterVar(&cv_grpaletteshader);
CV_RegisterVar(&cv_grflashpal);
#endif
#ifdef HWRENDER
+3
View File
@@ -113,6 +113,9 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(StartBatching);
GETFUNC(RenderBatches);
GETFUNC(AddLightTable);
GETFUNC(ClearLightTableCache);
#else //HWRENDER
if (0 == strcmp("FinishUpdate", funcName))
+3
View File
@@ -2148,6 +2148,9 @@ void I_StartupGraphics(void)
HWD.pfnStartBatching = hwSym("StartBatching",NULL);
HWD.pfnRenderBatches = hwSym("RenderBatches",NULL);
HWD.pfnAddLightTable = hwSym("AddLightTable",NULL);
HWD.pfnClearLightTableCache = hwSym("ClearLightTableCache",NULL);
if (!HWD.pfnInit()) // load the OpenGL library
rendermode = render_soft;
+10 -6
View File
@@ -232,18 +232,22 @@ void ST_doPaletteStuff(void)
else
palette = 0;
palette = min(max(palette, 0), 13);
#ifdef HWRENDER
if (rendermode == render_opengl)
if (rendermode == render_opengl && !cv_grpaletteshader.value || rendermode == render_opengl && cv_grpaletteshader.value && !cv_grflashpal.value)
palette = 0; // No flashpals here in OpenGL
#endif
palette = min(max(palette, 0), 13);
if (palette != st_palette)
{
st_palette = palette;
if (rendermode == render_soft)
#ifdef HWRENDER
if (rendermode != render_none && cv_grpaletteshader.value && cv_grflashpal.value)
#else
if (rendermode != render_none)
#endif
{
//V_SetPaletteLump(GetPalette()); // Reset the palette -- is this needed?
if (!splitscreen)
@@ -2167,9 +2171,9 @@ void ST_Drawer(void)
//25/08/99: Hurdler: palette changes is done for all players,
// not only player1! That's why this part
// of code is moved somewhere else.
if (rendermode == render_soft)
if (rendermode == render_soft || rendermode == render_opengl && cv_grpaletteshader.value && cv_grflashpal.value)
#endif
if (rendermode != render_none) ST_doPaletteStuff();
if (rendermode != render_none) ST_doPaletteStuff();
if (st_overlay)
{
+22 -4
View File
@@ -28,6 +28,7 @@
#ifdef HWRENDER
#include "hardware/hw_main.h"
#include "hardware/r_opengl/r_opengl.h"
#endif
// Each screen is [vid.width*vid.height];
@@ -224,8 +225,17 @@ void V_SetPalette(INT32 palettenum)
LoadMapPalette();
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
HWR_SetPalette(&pLocalPalette[palettenum*256]);
if (rendermode != render_soft && rendermode != render_none) {
// in palette rendering mode, we already manage our palette ourselves
if (cv_grpaletteshader.value == 1)
{
// reset our palette lookups n shit
gl_palette_initialized = false;
InitPalette(palettenum, true);
}
else
HWR_SetPalette(pLocalPalette);
}
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
else
#endif
@@ -238,8 +248,16 @@ void V_SetPaletteLump(const char *pal)
{
LoadPalette(pal);
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
HWR_SetPalette(pLocalPalette);
if (rendermode != render_soft && rendermode != render_none) {
if (cv_grpaletteshader.value == 1)
{
// reset our palette lookups n shit
gl_palette_initialized = false;
InitPalette(0, false);
}
else
HWR_SetPalette(pLocalPalette);
}
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
else
#endif