Tinted wipe support for OpenGL

This commit is contained in:
Hannu Hanhi 2022-03-12 02:04:57 +02:00
parent b3c970d6b4
commit f74433cc64
7 changed files with 99 additions and 36 deletions

View file

@ -565,7 +565,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
if (rendermode == render_opengl)
{
// send in the wipe type and wipe frame because we need to cache the graphic
HWR_DoTintedWipe(wipetype, wipeframe-1);
HWR_DoWipe(wipetype, wipeframe-1);
}
else
#endif

View file

@ -154,6 +154,7 @@ enum
SHADER_SKY,
SHADER_PALETTE_POSTPROCESS,
SHADER_UI_COLORMAP_FADE,
SHADER_UI_TINTED_WIPE,
NUMSHADERTARGETS
};

View file

@ -55,7 +55,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd);
EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd, FSurfaceInfo *surf, FBITFIELD polyFlags);
EXPORT void HWRAPI(DrawScreenTexture) (int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
EXPORT void HWRAPI(MakeScreenTexture) (int tex);
EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, int width, int height);

View file

@ -6858,13 +6858,31 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
return;
HWR_GetFadeMask(wipelumpnum);
HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END);
}
if (wipestyle == WIPESTYLE_COLORMAP && HWR_UseShader())
{
FSurfaceInfo surf = {0};
FBITFIELD polyflags = PF_Modulated|PF_NoDepthTest;
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
{
// It does the same thing
HWR_DoWipe(wipenum, scrnnum);
polyflags |= (wipestyleflags & WSF_TOWHITE) ? PF_Additive : PF_ReverseSubtract;
surf.PolyColor.s.red = FADEREDFACTOR;
surf.PolyColor.s.green = FADEGREENFACTOR;
surf.PolyColor.s.blue = FADEBLUEFACTOR;
// polycolor alpha communicates fadein / fadeout to the shader and the backend
surf.PolyColor.s.alpha = (wipestyleflags & WSF_FADEIN) ? 255 : 0;
// backend shader may not have been enabled yet so do it here
HWR_SetShaderState();
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_UI_TINTED_WIPE));
HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END,
&surf, polyflags);
HWD.pfnUnSetShader();
}
else
{
HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END,
NULL, 0);
}
}
void HWR_MakeScreenFinalTexture(void)

View file

@ -62,7 +62,6 @@ void HWR_StartScreenWipe(void);
void HWR_EndScreenWipe(void);
void HWR_DrawIntermissionBG(void);
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(int width, int height);

View file

@ -315,6 +315,7 @@
"gl_FragColor = final_color;\n" \
"}\0"
// Applies a palettized colormap fade to tex
#define GLSL_UI_COLORMAP_FADE_SHADER \
"uniform sampler2D tex;\n" \
"uniform float lighting;\n" \
@ -325,7 +326,29 @@
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
"vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (lighting + 0.5) / 32.0);\n" \
"gl_FragColor = texture2D(lighttable_tex, lighttable_coord);\n" \
"}\0" \
"}\0"
// For wipes that use additive and subtractive blending.
// alpha_factor = 31 * 8 / 10 = 24.8
// Calculated based on the use of the "fade" variable from the GETCOLOR macro
// in r_data.c:R_CreateFadeColormaps.
// However this value created some ugliness in fades to white (special stage entry)
// while palette rendering is enabled, so I raised the value just a bit.
#define GLSL_UI_TINTED_WIPE_SHADER \
"uniform sampler2D tex;\n" \
"uniform vec4 poly_color;\n" \
"const float alpha_factor = 24.875;\n" \
"void main(void) {\n" \
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
"vec4 final_color = poly_color;\n" \
"float alpha = texel.a;\n" \
"if (final_color.a >= 0.5)\n" \
"alpha = 1.0 - alpha;\n" \
"alpha *= alpha_factor;\n" \
"final_color *= alpha;\n" \
"final_color.a = 1.0;\n" \
"gl_FragColor = final_color;\n" \
"}\0"
// ================
// Shader sources
@ -362,6 +385,9 @@ static struct {
// UI colormap fade shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_COLORMAP_FADE_SHADER},
// UI tinted wipe shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_TINTED_WIPE_SHADER},
{NULL, NULL},
};

View file

@ -3030,7 +3030,8 @@ EXPORT void HWRAPI(DrawScreenTexture)(int tex, FSurfaceInfo *surf, FBITFIELD pol
}
// Do screen fades!
EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd, FSurfaceInfo *surf,
FBITFIELD polyFlags)
{
INT32 texsize = 512;
float xfix, yfix;
@ -3055,6 +3056,12 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
1.0f, 1.0f
};
int firstScreen;
if (surf && surf->PolyColor.s.alpha == 255)
firstScreen = wipeEnd; // it's a tinted fade-in, we need wipeEnd
else
firstScreen = wipeStart;
// look for power of two that is large enough for the screen
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
@ -3079,13 +3086,24 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
SetBlend(PF_Modulated|PF_NoDepthTest);
pglEnable(GL_TEXTURE_2D);
// Draw the original screen
pglBindTexture(GL_TEXTURE_2D, screenTextures[wipeStart]);
pglBindTexture(GL_TEXTURE_2D, screenTextures[firstScreen]);
pglColor4ubv(white);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (surf)
{
// Draw fade mask to screen using surf and polyFlags
// Used for colormap/tinted wipes.
pglBindTexture(GL_TEXTURE_2D, fademaskdownloaded);
pglTexCoordPointer(2, GL_FLOAT, 0, defaultST);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
PreparePolygon(surf, NULL, polyFlags);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
else // Blend wipeEnd into screen with the fade mask
{
SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
// Draw the end screen that fades in
@ -3116,6 +3134,7 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
pglActiveTexture(GL_TEXTURE0);
pglClientActiveTexture(GL_TEXTURE0);
tex_downloaded = screenTextures[wipeEnd];
}
}
// Create a texture from the screen.