diff --git a/src/f_wipe.c b/src/f_wipe.c index 43b7180b7..b9a09e89f 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -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 diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index bf1bed9ee..c325e9d3f 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -154,6 +154,7 @@ enum SHADER_SKY, SHADER_PALETTE_POSTPROCESS, SHADER_UI_COLORMAP_FADE, + SHADER_UI_TINTED_WIPE, NUMSHADERTARGETS }; diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index d4fe88d47..f4d9a09f8 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -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); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7dfe1bff9..4c14a4cfe 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -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) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 8af1fc041..36d1e94f9 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -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); diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 6f81a55ef..4e2ec14a1 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -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}, }; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6152b2c43..e9027eba5 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -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,43 +3086,55 @@ 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); - SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest); + 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 - pglActiveTexture(GL_TEXTURE0); - pglEnable(GL_TEXTURE_2D); - pglBindTexture(GL_TEXTURE_2D, screenTextures[wipeEnd]); - pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + // Draw the end screen that fades in + pglActiveTexture(GL_TEXTURE0); + pglEnable(GL_TEXTURE_2D); + pglBindTexture(GL_TEXTURE_2D, screenTextures[wipeEnd]); + pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - pglActiveTexture(GL_TEXTURE1); - pglEnable(GL_TEXTURE_2D); - pglBindTexture(GL_TEXTURE_2D, fademaskdownloaded); + pglActiveTexture(GL_TEXTURE1); + pglEnable(GL_TEXTURE_2D); + pglBindTexture(GL_TEXTURE_2D, fademaskdownloaded); - pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - // const float defaultST[8] + // const float defaultST[8] - pglClientActiveTexture(GL_TEXTURE0); - pglTexCoordPointer(2, GL_FLOAT, 0, fix); - pglVertexPointer(3, GL_FLOAT, 0, screenVerts); - pglClientActiveTexture(GL_TEXTURE1); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglTexCoordPointer(2, GL_FLOAT, 0, defaultST); - pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + pglClientActiveTexture(GL_TEXTURE0); + pglTexCoordPointer(2, GL_FLOAT, 0, fix); + pglVertexPointer(3, GL_FLOAT, 0, screenVerts); + pglClientActiveTexture(GL_TEXTURE1); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglTexCoordPointer(2, GL_FLOAT, 0, defaultST); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit + pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglActiveTexture(GL_TEXTURE0); - pglClientActiveTexture(GL_TEXTURE0); - tex_downloaded = screenTextures[wipeEnd]; + pglActiveTexture(GL_TEXTURE0); + pglClientActiveTexture(GL_TEXTURE0); + tex_downloaded = screenTextures[wipeEnd]; + } } // Create a texture from the screen.