From b3c970d6b483e83a0f924fe752015902badec424 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Wed, 9 Mar 2022 02:43:51 +0200 Subject: [PATCH] Light table support for HWR_FadeScreenMenuBack --- src/hardware/hw_cache.c | 26 ++++++++++++++++++++++++++ src/hardware/hw_defs.h | 5 +++-- src/hardware/hw_draw.c | 13 +++++++++++++ src/hardware/hw_drv.h | 2 +- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 26 ++------------------------ src/hardware/hw_shaders.c | 15 +++++++++++++++ src/hardware/r_opengl/r_opengl.c | 12 ++++++++---- src/sdl/i_video.c | 2 +- src/sdl/ogl_sdl.c | 2 +- 10 files changed, 71 insertions(+), 33 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 9170d79d7..75a77e9f0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1497,6 +1497,32 @@ UINT32 HWR_CreateLightTable(UINT8 *lighttable) return id; } +// get hwr lighttable id for colormap, create it if it doesn't already exist +UINT32 HWR_GetLightTableID(extracolormap_t *colormap) +{ + 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); + } + + return colormap->gl_lighttable_id; +} + // Note: all hardware lighttable ids assigned before this // call become invalid and must not be used. void HWR_ClearLightTables(void) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index b175c21e0..bf1bed9ee 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -153,8 +153,9 @@ enum SHADER_FOG, SHADER_SKY, SHADER_PALETTE_POSTPROCESS, + SHADER_UI_COLORMAP_FADE, - NUMSHADERTARGETS, + NUMSHADERTARGETS }; // Maximum amount of shader programs @@ -335,7 +336,7 @@ enum hwdscreentexture HWD_SCREENTEXTURE_WIPE_START, // source image for the wipe/fade effect HWD_SCREENTEXTURE_WIPE_END, // destination image for the wipe/fade effect HWD_SCREENTEXTURE_GENERIC1, // underwater/heat effect, intermission background - HWD_SCREENTEXTURE_GENERIC2, // screen before palette rendering's postprocessing + HWD_SCREENTEXTURE_GENERIC2, // palette-based colormap fade, screen before palette rendering's postprocessing HWD_SCREENTEXTURE_GENERIC3, // screen after palette rendering's postprocessing NUMSCREENTEXTURES, // (generic3 is unused if palette rendering is disabled) }; diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 90b9d0372..e8365ee2f 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -797,6 +797,19 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) if (color & 0xFF00) // Do COLORMAP fade. { + if (HWR_ShouldUsePaletteRendering()) + { + const hwdscreentexture_t scr_tex = HWD_SCREENTEXTURE_GENERIC2; + + Surf.LightTableId = HWR_GetLightTableID(NULL); + Surf.LightInfo.light_level = strength; + HWD.pfnMakeScreenTexture(scr_tex); + HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_UI_COLORMAP_FADE)); + HWD.pfnDrawScreenTexture(scr_tex, &Surf, PF_ColorMapped|PF_NoDepthTest); + HWD.pfnUnSetShader(); + + return; + } Surf.PolyColor.rgba = UINT2RGBA(0x01010160); Surf.PolyColor.s.alpha = (strength*8); } diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 503547865..d4fe88d47 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -56,7 +56,7 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd); -EXPORT void HWRAPI(DrawScreenTexture) (int tex); +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_glob.h b/src/hardware/hw_glob.h index 2c582d6d8..70218de0d 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -132,6 +132,7 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch); void HWR_SetPalette(RGBA_t *palette); void HWR_SetMapPalette(void); UINT32 HWR_CreateLightTable(UINT8 *lighttable); +UINT32 HWR_GetLightTableID(extracolormap_t *colormap); void HWR_ClearLightTables(void); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f7752dfa9..7dfe1bff9 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -239,31 +239,9 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col 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; - } + Surface->LightTableId = HWR_GetLightTableID(colormap); else - { Surface->LightTableId = 0; - } } UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work @@ -6835,7 +6813,7 @@ void HWR_EndScreenWipe(void) void HWR_DrawIntermissionBG(void) { - HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1); + HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0); } // diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index d4d7f21bc..6f81a55ef 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -315,6 +315,18 @@ "gl_FragColor = final_color;\n" \ "}\0" +#define GLSL_UI_COLORMAP_FADE_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform float lighting;\n" \ + "uniform sampler3D palette_lookup_tex;\n" \ + "uniform sampler2D lighttable_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" \ + "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" \ + // ================ // Shader sources // ================ @@ -347,6 +359,9 @@ static struct { // Palette postprocess shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_PALETTE_POSTPROCESS_SHADER}, + // UI colormap fade shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_COLORMAP_FADE_SHADER}, + {NULL, NULL}, }; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index efeb8289d..6152b2c43 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1181,11 +1181,11 @@ EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *dst_data) // and draw generic2 back after reading the framebuffer. // this hack is for some reason **much** faster than the simple solution of using glGetTexImage. if (tex != HWD_SCREENTEXTURE_GENERIC2) - DrawScreenTexture(tex); + DrawScreenTexture(tex, NULL, 0); pglPixelStorei(GL_PACK_ALIGNMENT, 1); pglReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, dst_data); if (tex != HWD_SCREENTEXTURE_GENERIC2) - DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2); + DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0); // Flip image upside down. // In other words, convert OpenGL's "bottom->top" row order into "top->bottom". for(i = 0; i < screen_height/2; i++) @@ -1965,6 +1965,7 @@ static void Shader_CompileError(const char *message, GLuint program, INT32 shade } // code that is common between DrawPolygon and DrawIndexedTriangles +// DrawScreenTexture also can use this function for fancier screen texture drawing // the corona thing is there too, i have no idea if that stuff works with DrawIndexedTriangles and batching static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD PolyFlags) { @@ -2978,7 +2979,7 @@ EXPORT void HWRAPI(FlushScreenTextures) (void) screenTextures[i] = 0; } -EXPORT void HWRAPI(DrawScreenTexture)(int tex) +EXPORT void HWRAPI(DrawScreenTexture)(int tex, FSurfaceInfo *surf, FBITFIELD polyflags) { float xfix, yfix; INT32 texsize = 512; @@ -3015,7 +3016,10 @@ EXPORT void HWRAPI(DrawScreenTexture)(int tex) pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); - Shader_SetUniforms(NULL, NULL, NULL, NULL); // prepare shader, if it is enabled + if (surf) + PreparePolygon(surf, NULL, polyflags); + else + Shader_SetUniforms(NULL, NULL, NULL, NULL); // prepare shader, if it is enabled pglColor4ubv(white); pglTexCoordPointer(2, GL_FLOAT, 0, fix); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ad539e76b..da357354c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1260,7 +1260,7 @@ void I_FinishUpdate(void) HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC2); HWD.pfnSetSpecialState(HWD_SET_SHADERS, 1); HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS)); - HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2); + HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0); HWD.pfnUnSetShader(); HWD.pfnSetSpecialState(HWD_SET_SHADERS, 0); } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 91df683ec..cd09dc071 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -234,7 +234,7 @@ void OglSdlFinishUpdate(boolean waitvbl) // effects that want to take the old screen can do so after this // Generic2 has the screen image without palette rendering brightness adjustments. // Using that here will prevent brightness adjustments being applied twice. - DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2); + DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0); } EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette)