Add PF_ColorMapped

Not all surfaces have tint and fade colors. Checking for a specific surface flag, that tells the backend those colors are present, avoids uninitialized reads.

# Conflicts:
#	src/hardware/hw_main.c
This commit is contained in:
toaster 2022-03-18 12:43:36 +00:00
parent 11875b56c7
commit 2868639144
4 changed files with 120 additions and 65 deletions

View file

@ -227,14 +227,15 @@ enum EPolyFlags
PF_NoDepthTest = 0x00000200, // Disables the depth test mode PF_NoDepthTest = 0x00000200, // Disables the depth test mode
PF_Invisible = 0x00000400, // Disables write to color buffer PF_Invisible = 0x00000400, // Disables write to color buffer
PF_Decal = 0x00000800, // Enables polygon offset PF_Decal = 0x00000800, // Enables polygon offset
PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB) PF_Modulated = 0x00001000, // Modulation (multiply output with constant RGBA)
// When set, pass the color constant into the FSurfaceInfo -> PolyColor // When set, pass the color constant into the FSurfaceInfo -> PolyColor
PF_NoTexture = 0x00002000, // Disables texturing PF_NoTexture = 0x00002000, // Disables texturing
PF_Corona = 0x00004000, // Tells the renderer we are drawing a corona PF_Corona = 0x00004000, // Tells the renderer we are drawing a corona
PF_Ripple = 0x00008000, // Water effect shader PF_ColorMapped = 0x00008000, // Surface has "tint" and "fade" colors, which are sent as uniforms to a shader.
PF_RemoveYWrap = 0x00010000, // Forces clamp texture on Y PF_RemoveYWrap = 0x00010000, // Forces clamp texture on Y
PF_ForceWrapX = 0x00020000, // Forces repeat texture on X PF_ForceWrapX = 0x00020000, // Forces repeat texture on X
PF_ForceWrapY = 0x00040000 // Forces repeat texture on Y PF_ForceWrapY = 0x00040000, // Forces repeat texture on Y
PF_Ripple = 0x00100000 // Water ripple effect. The current backend doesn't use it for anything.
}; };
@ -263,7 +264,6 @@ struct FTextureInfo
}; };
typedef struct FTextureInfo FTextureInfo; typedef struct FTextureInfo FTextureInfo;
// jimita 14032019
struct FLightInfo struct FLightInfo
{ {
FUINT light_level; FUINT light_level;
@ -279,7 +279,7 @@ struct FSurfaceInfo
RGBA_t PolyColor; RGBA_t PolyColor;
RGBA_t TintColor; RGBA_t TintColor;
RGBA_t FadeColor; RGBA_t FadeColor;
FLightInfo LightInfo; // jimita 14032019 FLightInfo LightInfo;
}; };
typedef struct FSurfaceInfo FSurfaceInfo; typedef struct FSurfaceInfo FSurfaceInfo;

View file

@ -68,7 +68,6 @@ EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
#define SCREENVERTS 10 #define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
// jimita
EXPORT boolean HWRAPI(CompileShaders) (void); EXPORT boolean HWRAPI(CompileShaders) (void);
EXPORT void HWRAPI(CleanShaders) (void); EXPORT void HWRAPI(CleanShaders) (void);
EXPORT void HWRAPI(SetShader) (int type); EXPORT void HWRAPI(SetShader) (int type);

View file

@ -181,6 +181,11 @@ boolean gl_shadersavailable = true;
// Lighting // Lighting
// ========================================================================== // ==========================================================================
static boolean HWR_UseShader(void)
{
return (cv_glshaders.value && gl_shadersavailable);
}
boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel) boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel)
{ {
if (R_ThingIsFullBright(thing)) if (R_ThingIsFullBright(thing))
@ -202,7 +207,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG; fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG;
// Crappy backup coloring if you can't do shaders // Crappy backup coloring if you can't do shaders
if (!cv_glshaders.value || !gl_shadersavailable) if (!HWR_UseShader())
{ {
// be careful, this may get negative for high lightlevel values. // be careful, this may get negative for high lightlevel values.
float tint_alpha, fade_alpha; float tint_alpha, fade_alpha;
@ -391,7 +396,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
static FOutVector *planeVerts = NULL; static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0; static UINT16 numAllocedPlaneVerts = 0;
int shader; INT32 shader = SHADER_DEFAULT;
// no convex poly were generated for this subsector // no convex poly were generated for this subsector
if (!xsub->planepoly) if (!xsub->planepoly)
@ -588,12 +593,17 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
else else
PolyFlags |= PF_Masked|PF_Modulated; PolyFlags |= PF_Masked|PF_Modulated;
if (PolyFlags & PF_Fog) if (HWR_UseShader())
shader = SHADER_FOG; // fog shader {
else if (PolyFlags & PF_Ripple) if (PolyFlags & PF_Fog)
shader = SHADER_WATER; // water shader shader = SHADER_FOG;
else else if (PolyFlags & PF_Ripple)
shader = SHADER_FLOOR; // floor shader shader = SHADER_WATER;
else
shader = SHADER_FLOOR;
PolyFlags |= PF_ColorMapped;
}
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false); HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
@ -810,8 +820,17 @@ static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, I
// //
static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap)
{ {
INT32 shader = SHADER_DEFAULT;
HWR_Lighting(pSurf, lightlevel, wallcolormap); HWR_Lighting(pSurf, lightlevel, wallcolormap);
HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, SHADER_WALL, false); // wall shader
if (HWR_UseShader())
{
shader = SHADER_WALL;
blendmode |= PF_ColorMapped;
}
HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, shader, false);
} }
// ========================================================================== // ==========================================================================
@ -2729,30 +2748,30 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap) UINT8 alpha, extracolormap_t *planecolormap)
{ {
float height; //constant y for all points on the convex flat polygon FSurfaceInfo Surf;
FOutVector *v3d; FOutVector *v3d;
INT32 i; INT32 shader = SHADER_DEFAULT;
float flatxref,flatyref;
size_t nrPlaneVerts = polysector->numVertices;
INT32 i;
float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon
float flatxref, flatyref;
float fflatwidth = 64.0f, fflatheight = 64.0f; float fflatwidth = 64.0f, fflatheight = 64.0f;
INT32 flatflag = 63; INT32 flatflag = 63;
boolean texflat = false; boolean texflat = false;
float scrollx = 0.0f, scrolly = 0.0f; float scrollx = 0.0f, scrolly = 0.0f;
angle_t angle = 0; angle_t angle = 0;
FSurfaceInfo Surf;
fixed_t tempxs, tempyt; fixed_t tempxs, tempyt;
size_t nrPlaneVerts;
static FOutVector *planeVerts = NULL; static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0; static UINT16 numAllocedPlaneVerts = 0;
nrPlaneVerts = polysector->numVertices; if (nrPlaneVerts < 3) // Not even a triangle?
height = FIXED_TO_FLOAT(fixedheight);
if (nrPlaneVerts < 3) //not even a triangle ?
return; return;
else if (nrPlaneVerts > (size_t)UINT16_MAX) // FIXME: exceeds plVerts size
if (nrPlaneVerts > (size_t)UINT16_MAX) // FIXME: exceeds plVerts size
{ {
CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX); CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX);
return; return;
@ -2904,7 +2923,6 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y); v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y);
} }
HWR_Lighting(&Surf, lightlevel, planecolormap); HWR_Lighting(&Surf, lightlevel, planecolormap);
if (blendmode & PF_Translucent) if (blendmode & PF_Translucent)
@ -2915,7 +2933,13 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
else else
blendmode |= PF_Masked|PF_Modulated; blendmode |= PF_Masked|PF_Modulated;
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, SHADER_FLOOR, false); // floor shader if (HWR_UseShader())
{
shader = SHADER_FLOOR;
blendmode |= PF_ColorMapped;
}
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, shader, false);
} }
static void HWR_AddPolyObjectPlanes(void) static void HWR_AddPolyObjectPlanes(void)
@ -3650,9 +3674,10 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
float fscale; float fx; float fy; float offset; float fscale; float fx; float fy; float offset;
float ph; float ph;
extracolormap_t *colormap = NULL; extracolormap_t *colormap = NULL;
FBITFIELD blendmode = PF_ReverseSubtract;
INT32 shader = SHADER_DEFAULT;
UINT8 i; UINT8 i;
SINT8 flip = P_MobjFlip(thing); SINT8 flip = P_MobjFlip(thing);
UINT32 tFlag = PF_ReverseSubtract;
INT32 light; INT32 light;
fixed_t scalemul; fixed_t scalemul;
@ -3764,10 +3789,16 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
if (thing->whiteshadow == true) if (thing->whiteshadow == true)
{ {
tFlag = PF_Additive; blendmode = PF_Additive;
} }
HWR_ProcessPolygon(&sSurf, shadowVerts, 4, tFlag|PF_Modulated, SHADER_SPRITE, false); // sprite shader if (HWR_UseShader())
{
shader = SHADER_SPRITE;
blendmode |= PF_ColorMapped;
}
HWR_ProcessPolygon(&sSurf, shadowVerts, 4, blendmode|PF_Modulated, shader, false);
} }
// This is expecting a pointer to an array containing 4 wallVerts for a sprite // This is expecting a pointer to an array containing 4 wallVerts for a sprite
@ -3815,6 +3846,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
boolean lightset = true; boolean lightset = true;
FBITFIELD blend = 0; FBITFIELD blend = 0;
FBITFIELD occlusion; FBITFIELD occlusion;
INT32 shader = SHADER_DEFAULT;
boolean use_linkdraw_hack = false; boolean use_linkdraw_hack = false;
UINT8 alpha; UINT8 alpha;
@ -3937,6 +3969,12 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
} }
} }
if (HWR_UseShader())
{
shader = SHADER_SPRITE;
blend |= PF_ColorMapped;
}
alpha = Surf.PolyColor.s.alpha; alpha = Surf.PolyColor.s.alpha;
// Start with the lightlevel and colormap from the top of the sprite // Start with the lightlevel and colormap from the top of the sprite
@ -4049,7 +4087,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
Surf.PolyColor.s.alpha = alpha; Surf.PolyColor.s.alpha = alpha;
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
if (use_linkdraw_hack) if (use_linkdraw_hack)
HWR_LinkDrawHackAdd(wallVerts, spr); HWR_LinkDrawHackAdd(wallVerts, spr);
@ -4078,7 +4116,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
Surf.PolyColor.s.alpha = alpha; Surf.PolyColor.s.alpha = alpha;
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
if (use_linkdraw_hack) if (use_linkdraw_hack)
HWR_LinkDrawHackAdd(wallVerts, spr); HWR_LinkDrawHackAdd(wallVerts, spr);
@ -4323,6 +4361,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
} }
{ {
INT32 shader = SHADER_DEFAULT;
FBITFIELD blend = 0; FBITFIELD blend = 0;
FBITFIELD occlusion; FBITFIELD occlusion;
boolean use_linkdraw_hack = false; boolean use_linkdraw_hack = false;
@ -4375,7 +4414,13 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
if (!occlusion) use_linkdraw_hack = true; if (!occlusion) use_linkdraw_hack = true;
} }
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader if (HWR_UseShader())
{
shader = SHADER_SPRITE;
blend |= PF_ColorMapped;
}
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
if (use_linkdraw_hack) if (use_linkdraw_hack)
HWR_LinkDrawHackAdd(wallVerts, spr); HWR_LinkDrawHackAdd(wallVerts, spr);
@ -4386,6 +4431,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
// Sprite drawer for precipitation // Sprite drawer for precipitation
static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
{ {
INT32 shader = SHADER_DEFAULT;
FBITFIELD blend = 0; FBITFIELD blend = 0;
FOutVector wallVerts[4]; FOutVector wallVerts[4];
patch_t *gpatch; patch_t *gpatch;
@ -4489,7 +4535,13 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
} }
} }
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader if (HWR_UseShader())
{
shader = SHADER_SPRITE;
blend |= PF_ColorMapped;
}
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
} }
#endif #endif
@ -6680,24 +6732,29 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
FBITFIELD blendmode = blend; FBITFIELD blendmode = blend;
UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha
int shader; INT32 shader = SHADER_DEFAULT;
// Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting
HWR_Lighting(pSurf, lightlevel, wallcolormap); HWR_Lighting(pSurf, lightlevel, wallcolormap);
pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting
shader = SHADER_WALL; // wall shader
if (blend & PF_Environment) if (blend & PF_Environment)
blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects
if (fogwall) if (HWR_UseShader())
{ {
blendmode |= PF_Fog; if (fogwall)
shader = SHADER_FOG; // fog shader shader = SHADER_FOG;
else
shader = SHADER_WALL;
blendmode |= PF_ColorMapped;
} }
if (fogwall)
blendmode |= PF_Fog;
blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency
HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode, shader, false); HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode, shader, false);
} }
@ -6879,7 +6936,6 @@ void HWR_DrawScreenFinalTexture(int width, int height)
HWD.pfnDrawScreenFinalTexture(width, height); HWD.pfnDrawScreenFinalTexture(width, height);
} }
// jimita 18032019
static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum) static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum)
{ {
UINT16 i; UINT16 i;

View file

@ -942,7 +942,6 @@ void SetupGLFunc4(void)
*(void**)&pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); *(void**)&pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps");
} }
// jimita
EXPORT boolean HWRAPI(CompileShaders) (void) EXPORT boolean HWRAPI(CompileShaders) (void)
{ {
#ifdef GL_SHADERS #ifdef GL_SHADERS
@ -2206,32 +2205,34 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
SetBlend(PolyFlags); //TODO: inline (#pragma..) SetBlend(PolyFlags); //TODO: inline (#pragma..)
// PolyColor
if (pSurf) if (pSurf)
{ {
// If Modulated, mix the surface colour to the texture // If modulated, mix the surface colour to the texture
if (CurrentPolyFlags & PF_Modulated) if (CurrentPolyFlags & PF_Modulated)
{
// Poly color
poly.red = byte2float[pSurf->PolyColor.s.red];
poly.green = byte2float[pSurf->PolyColor.s.green];
poly.blue = byte2float[pSurf->PolyColor.s.blue];
poly.alpha = byte2float[pSurf->PolyColor.s.alpha];
pglColor4ubv((GLubyte*)&pSurf->PolyColor.s); pglColor4ubv((GLubyte*)&pSurf->PolyColor.s);
// If the surface is either modulated or colormapped, or both
if (CurrentPolyFlags & (PF_Modulated | PF_ColorMapped))
{
poly.red = byte2float[pSurf->PolyColor.s.red];
poly.green = byte2float[pSurf->PolyColor.s.green];
poly.blue = byte2float[pSurf->PolyColor.s.blue];
poly.alpha = byte2float[pSurf->PolyColor.s.alpha];
} }
// Tint color // Only if the surface is colormapped
tint.red = byte2float[pSurf->TintColor.s.red]; if (CurrentPolyFlags & PF_ColorMapped)
tint.green = byte2float[pSurf->TintColor.s.green]; {
tint.blue = byte2float[pSurf->TintColor.s.blue]; tint.red = byte2float[pSurf->TintColor.s.red];
tint.alpha = byte2float[pSurf->TintColor.s.alpha]; tint.green = byte2float[pSurf->TintColor.s.green];
tint.blue = byte2float[pSurf->TintColor.s.blue];
tint.alpha = byte2float[pSurf->TintColor.s.alpha];
// Fade color fade.red = byte2float[pSurf->FadeColor.s.red];
fade.red = byte2float[pSurf->FadeColor.s.red]; 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]; }
} }
// this test is added for new coronas' code (without depth buffer) // this test is added for new coronas' code (without depth buffer)
@ -3022,7 +3023,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
pglMatrixMode(GL_PROJECTION); pglMatrixMode(GL_PROJECTION);
pglLoadIdentity(); pglLoadIdentity();
// jimita 14042019
// Simulate Software's y-shearing // Simulate Software's y-shearing
// https://zdoom.org/wiki/Y-shearing // https://zdoom.org/wiki/Y-shearing
if (shearing) if (shearing)