From 5194ed81ad9defbfd4eb6012001d6de26c4742ed Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 24 Nov 2024 13:33:28 -0300 Subject: [PATCH] Fix colormap textures not being updated for palette shaders --- src/hardware/hw_cache.c | 57 +++++++++++++++++++++++--------- src/hardware/hw_drv.h | 2 ++ src/hardware/hw_glob.h | 3 +- src/hardware/r_opengl/r_opengl.c | 18 ++++++++++ src/lua_colorlib.c | 2 +- src/r_data.c | 9 +++++ src/r_data.h | 1 + src/r_defs.h | 7 ++-- src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/z_zone.c | 1 + src/z_zone.h | 1 + 12 files changed, 83 insertions(+), 20 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index f282ca891..b71bf7007 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1258,20 +1258,29 @@ void HWR_SetMapPalette(void) // Creates a hardware lighttable from the supplied lighttable. // Returns the id of the hw lighttable, usable in FSurfaceInfo. -UINT32 HWR_CreateLightTable(UINT8 *lighttable) +UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable) { - UINT32 i, id; + UINT32 i; RGBA_t *palette = HWR_GetTexturePalette(); - RGBA_t *hw_lighttable = Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_STATIC, NULL); // To make the palette index -> RGBA mapping easier for the shader, // the hardware lighttable is composed of RGBA colors instead of palette indices. for (i = 0; i < 256 * 32; i++) hw_lighttable[i] = palette[lighttable[i]]; - id = HWD.pfnCreateLightTable(hw_lighttable); - Z_Free(hw_lighttable); - return id; + return HWD.pfnCreateLightTable(hw_lighttable); +} + +// Updates a hardware lighttable of a given id from the supplied lighttable. +void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable) +{ + UINT32 i; + RGBA_t *palette = HWR_GetTexturePalette(); + + for (i = 0; i < 256 * 32; i++) + hw_lighttable[i] = palette[lighttable[i]]; + + HWD.pfnUpdateLightTable(id, hw_lighttable); } // get hwr lighttable id for colormap, create it if it doesn't already exist @@ -1285,25 +1294,41 @@ UINT32 HWR_GetLightTableID(extracolormap_t *colormap) default_colormap = true; } - // create hw lighttable if there isn't one - if (!colormap->gl_lighttable_id) - { - UINT8 *colormap_pointer; + 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); + if (default_colormap) + colormap_pointer = colormaps; // don't actually use the data from the "default colormap" + else + colormap_pointer = colormap->colormap; + + // create hw lighttable if there isn't one + if (colormap->gl_lighttable.data == NULL) + { + Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_HWRLIGHTTABLEDATA, &colormap->gl_lighttable.data); } - return colormap->gl_lighttable_id; + // Generate the texture for this light table + if (!colormap->gl_lighttable.id) + { + colormap->gl_lighttable.id = HWR_CreateLightTable(colormap_pointer, colormap->gl_lighttable.data); + } + // Update the texture if it was directly changed by a script + else if (colormap->gl_lighttable.needs_update) + { + HWR_UpdateLightTable(colormap->gl_lighttable.id, colormap_pointer, colormap->gl_lighttable.data); + } + + colormap->gl_lighttable.needs_update = false; + + 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) { + Z_FreeTag(PU_HWRLIGHTTABLEDATA); + if (vid.glstate == VID_GL_LIBRARY_LOADED) HWD.pfnClearLightTables(); } diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 694cc1b8c..a5fdc00a4 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -71,6 +71,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut); EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable); +EXPORT void HWRAPI(UpdateLightTable)(UINT32 id, RGBA_t *hw_lighttable); EXPORT void HWRAPI(ClearLightTables)(void); EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette); @@ -125,6 +126,7 @@ struct hwdriver_s SetPaletteLookup pfnSetPaletteLookup; CreateLightTable pfnCreateLightTable; + UpdateLightTable pfnUpdateLightTable; ClearLightTables pfnClearLightTables; SetScreenPalette pfnSetScreenPalette; }; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 62fe8d0bd..bf9f7da3b 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -133,7 +133,8 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch); void HWR_SetPalette(RGBA_t *palette); void HWR_SetMapPalette(void); -UINT32 HWR_CreateLightTable(UINT8 *lighttable); +UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable); +void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable); UINT32 HWR_GetLightTableID(extracolormap_t *colormap); void HWR_ClearLightTables(void); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 75a92c2fb..85a50edb0 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -3257,6 +3257,24 @@ EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable) return item->id; } +EXPORT void HWRAPI(UpdateLightTable)(UINT32 id, RGBA_t *hw_lighttable) +{ + LTListItem *item = LightTablesHead; + while (item && item->id != id) + item = item->next; + + if (item) + { + pglBindTexture(GL_TEXTURE_2D, item->id); + + // Just update it + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 32, GL_RGBA, GL_UNSIGNED_BYTE, hw_lighttable); + + // restore previously bound texture + pglBindTexture(GL_TEXTURE_2D, tex_downloaded); + } +} + // Delete light table textures, ids given before become invalid and must not be used. EXPORT void HWRAPI(ClearLightTables)(void) { diff --git a/src/lua_colorlib.c b/src/lua_colorlib.c index 9e679eb40..2743635ed 100644 --- a/src/lua_colorlib.c +++ b/src/lua_colorlib.c @@ -593,7 +593,7 @@ static int extracolormap_set(lua_State *L) || exc->fadergba != old_fade_rgba || exc->fadestart != old_fade_start || exc->fadeend != old_fade_end) - R_GenerateLightTable(exc, true); + R_UpdateLightTable(exc, true); return 0; } diff --git a/src/r_data.c b/src/r_data.c index e7200ecbd..244690ebe 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -849,6 +849,15 @@ void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup) } } +void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup) +{ + R_GenerateLightTable(extra_colormap, uselookup); + +#ifdef HWRENDER + extra_colormap->gl_lighttable.needs_update = true; +#endif +} + extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) { // default values diff --git a/src/r_data.h b/src/r_data.h index 7c6ee19d5..64abf6d83 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -90,6 +90,7 @@ typedef enum } textmapcolormapflags_t; void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup); +void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap); extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3); extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags); diff --git a/src/r_defs.h b/src/r_defs.h index 51fac21fa..7269aa9d5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -76,8 +76,11 @@ typedef struct extracolormap_s lighttable_t *colormap; #ifdef HWRENDER - // The id of the hardware lighttable. Zero means it does not exist yet. - UINT32 gl_lighttable_id; + struct { + UINT32 id; // The id of the hardware lighttable. Zero means it does not exist yet. + RGBA_t *data; // The texture data of the hardware lighttable. + boolean needs_update; // If the colormap changed recently or not. + } gl_lighttable; #endif #ifdef EXTRACOLORMAPLUMPS diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index ca87fcc79..f56126601 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -112,6 +112,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetPaletteLookup); GETFUNC(CreateLightTable); + GETFUNC(UpdateLightTable); GETFUNC(ClearLightTables); GETFUNC(SetScreenPalette); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 10c866a1e..36bfd380f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1901,6 +1901,7 @@ void VID_StartupOpenGL(void) HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL); HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL); + HWD.pfnUpdateLightTable = hwSym("UpdateLightTable",NULL); HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL); HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL); diff --git a/src/z_zone.c b/src/z_zone.c index 5750f8ae0..0852fabae 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -671,6 +671,7 @@ static void Command_Memfree_f(void) CONS_Printf(M_GetText("Cached textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); CONS_Printf(M_GetText("Texture colormaps : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); CONS_Printf(M_GetText("Model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10)); + CONS_Printf(M_GetText("Light table textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRLIGHTTABLEDATA)>>10)); CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); CONS_Printf(M_GetText("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10); } diff --git a/src/z_zone.h b/src/z_zone.h index ce7af4a15..56c540c3b 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -55,6 +55,7 @@ enum PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch PU_HWRMODELTEXTURE = 23, // Hardware model texture + PU_HWRLIGHTTABLEDATA = 24, // Hardware light table data PU_HWRCACHE = 48, // static until unlocked PU_CACHE = 49, // static until unlocked