From e11439ddf335f21b294b0bb78b7e605e63b6038d Mon Sep 17 00:00:00 2001 From: hzqst <113660872@qq.com> Date: Sat, 23 Dec 2023 16:30:07 +0800 Subject: [PATCH] update R_StudioGetSkin --- Plugins/Renderer/gl_hooks.cpp | 3 +- Plugins/Renderer/gl_rmain.cpp | 1 + Plugins/Renderer/gl_studio.cpp | 151 ++++++++++++++++++++++++--------- Plugins/Renderer/gl_studio.h | 40 ++++++++- 4 files changed, 153 insertions(+), 42 deletions(-) diff --git a/Plugins/Renderer/gl_hooks.cpp b/Plugins/Renderer/gl_hooks.cpp index d82bb0ac..5137c87e 100644 --- a/Plugins/Renderer/gl_hooks.cpp +++ b/Plugins/Renderer/gl_hooks.cpp @@ -4559,6 +4559,7 @@ void R_FillAddress(void) Sig_FuncNotFound(GL_UnloadTexture); } +#if 0//unused if (1) { typedef struct @@ -4635,7 +4636,7 @@ void R_FillAddress(void) Sig_VarNotFound(DM_RemapSkin); Sig_VarNotFound(r_remapindex); } - +#endif if (1) { typedef struct diff --git a/Plugins/Renderer/gl_rmain.cpp b/Plugins/Renderer/gl_rmain.cpp index 2eb3fe75..26d6e1d6 100644 --- a/Plugins/Renderer/gl_rmain.cpp +++ b/Plugins/Renderer/gl_rmain.cpp @@ -2313,6 +2313,7 @@ void R_NewMap(void) R_NewMapWSurf(); R_NewMapLight(); + R_StudioFlushAllSkins(); R_StudioReloadVBOCache(); //This is for GoldSrc diff --git a/Plugins/Renderer/gl_studio.cpp b/Plugins/Renderer/gl_studio.cpp index 87e2fca4..f9908c8f 100644 --- a/Plugins/Renderer/gl_studio.cpp +++ b/Plugins/Renderer/gl_studio.cpp @@ -5,15 +5,15 @@ #include #include -std::unordered_map g_StudioBoneCacheManager; - -std::unordered_map g_StudioProgramTable; - std::vector g_StudioVBOCache; std::unordered_map g_StudioVBOMaterialCache; -#define MAX_STUDIO_BONE_CACHES 1024 +std::unordered_map g_StudioSkinCache; + +std::unordered_map g_StudioBoneCacheManager; + +std::unordered_map g_StudioProgramTable; static studio_bone_cache g_StudioBoneCaches[MAX_STUDIO_BONE_CACHES]; @@ -59,10 +59,13 @@ dlight_t* (*locallight)[3] = NULL; int* numlight = NULL; int* r_topcolor = NULL; int* r_bottomcolor = NULL; + +#if 0//unused player_model_t(*DM_PlayerState)[MAX_CLIENTS] = NULL; skin_t (*DM_RemapSkin)[64][MAX_SKINS] = NULL; skin_t* (*pDM_RemapSkin)[2528][MAX_SKINS] = NULL; int* r_remapindex = NULL; +#endif //Stats @@ -1174,9 +1177,47 @@ bool R_IsRemapSkin(const char* texture, int* low, int* mid, int* high) return false; } -skin_t* R_StudioGetSkin(int keynum, int index) +void R_StudioFlushAllSkins() { + for(auto &itor : g_StudioSkinCache) + { + delete itor.second; + } + + g_StudioSkinCache.clear(); +} + +void R_StudioFlushSkins(int keynum) +{ +#if 0 + for (int index = 0; index < MAX_SKINS; index++) + { + if ((*pDM_RemapSkin)[keynum][index]) + (*pDM_RemapSkin)[keynum][index]->model = NULL; + } +#endif + #if 1 + auto& itor = g_StudioSkinCache.find(keynum); + + if (itor != g_StudioSkinCache.end()) + { + auto pSkinCache = itor->second; + + if (pSkinCache) + { + for (int index = 0; index < MAX_SKINS; index++) + { + pSkinCache->skins[index].model = NULL; + } + } + } +#endif +} + +skin_t* R_StudioGetSkin(int keynum, int index) +{ +#if 0 if (index >= MAX_SKINS) index = 0; @@ -1194,9 +1235,45 @@ skin_t* R_StudioGetSkin(int keynum, int index) } return pskin; -#else +#endif + +#if 0 return gPrivateFuncs.R_StudioGetSkin(keynum, index); #endif + +#if 1 + + if (index >= MAX_SKINS) + index = 0; + + if (index < 0) + index = 0; + + auto& itor = g_StudioSkinCache.find(keynum); + + if (itor != g_StudioSkinCache.end()) + { + return &itor->second->skins[index]; + } + else + { + auto pSkinCache = new (std::nothrow) studio_skin_cache_t; + + if (pSkinCache) + { + memset(pSkinCache, 0, sizeof(studio_skin_cache_t)); + + pSkinCache->skins[index].keynum = keynum; + pSkinCache->skins[index].topcolor = -1; + pSkinCache->skins[index].bottomcolor = -1; + g_StudioSkinCache[keynum] = pSkinCache; + + return &pSkinCache->skins[index]; + } + } + + return NULL; +#endif } byte* R_StudioReloadSkin(model_t* pModel, int index, skin_t* pskin) @@ -1277,15 +1354,6 @@ byte* R_StudioReloadSkin(model_t* pModel, int index, skin_t* pskin) return pData->data; } -void R_StudioFlushSkins(int keynum) -{ - for (int index = 0; index < MAX_SKINS; index++) - { - if ((*pDM_RemapSkin)[keynum][index]) - (*pDM_RemapSkin)[keynum][index]->model = NULL; - } -} - void PaletteHueReplace(byte* palette, int newHue, int start, int end) { // Convert the new hue value to a range used in the algorithm double targetHue = static_cast(newHue) * 1.411764705882353; @@ -1370,42 +1438,45 @@ void R_StudioSetupSkinEx(const studio_vbo_t* VBOData, studiohdr_t* ptexturehdr, { auto pskin = R_StudioGetSkin((*currententity)->index, index); - if (pskin->model != (*r_model) || pskin->topcolor != (*r_topcolor) && pskin->bottomcolor != (*r_bottomcolor)) + if (pskin) { - if (pskin->model) - R_StudioFlushSkins((*currententity)->index); + if (pskin->model != (*r_model) || pskin->topcolor != (*r_topcolor) || pskin->bottomcolor != (*r_bottomcolor)) + { + if (pskin->model) + R_StudioFlushSkins((*currententity)->index); - auto pData = R_StudioReloadSkin((*r_model), index, pskin); + auto pTextureData = R_StudioReloadSkin((*r_model), index, pskin); - if (pData) - { - char fullname[1024] = {0}; - snprintf(fullname, sizeof(fullname), "%s_%s_%d", ptexturehdr->name, ptexture[index].name, (*currententity)->index); + if (pTextureData) + { + char fullname[1024] = { 0 }; + snprintf(fullname, sizeof(fullname), "%s_%s_%d", ptexturehdr->name, ptexture[index].name, (*currententity)->index); - byte* orig_palette = pData + (ptexture[index].height * ptexture[index].width); + byte* orig_palette = pTextureData + (ptexture[index].height * ptexture[index].width); - byte tmp_palette[768]; - memcpy(tmp_palette, orig_palette, 768); + byte tmp_palette[768]; + memcpy(tmp_palette, orig_palette, 768); - pskin->model = (*r_model); - pskin->bottomcolor = (*r_bottomcolor); - pskin->topcolor = (*r_topcolor); + pskin->model = (*r_model); + pskin->bottomcolor = (*r_bottomcolor); + pskin->topcolor = (*r_topcolor); - PaletteHueReplace(tmp_palette, pskin->topcolor, l, m); + PaletteHueReplace(tmp_palette, pskin->topcolor, l, m); - if (h != 0) - PaletteHueReplace(tmp_palette, pskin->bottomcolor, m, h); + if (h != 0) + PaletteHueReplace(tmp_palette, pskin->bottomcolor, m, h); - GL_UnloadTextureWithType(fullname, GLT_STUDIO, true); + GL_UnloadTextureWithType(fullname, GLT_STUDIO, true); - pskin->gl_index = GL_LoadTexture(fullname, GLT_STUDIO, pskin->width, pskin->height, pData, false, (ptexture[index].flags & STUDIO_NF_MASKED) ? TEX_TYPE_ALPHA : TEX_TYPE_NONE, tmp_palette); + pskin->gl_index = GL_LoadTexture(fullname, GLT_STUDIO, pskin->width, pskin->height, pTextureData, false, (ptexture[index].flags & STUDIO_NF_MASKED) ? TEX_TYPE_ALPHA : TEX_TYPE_NONE, tmp_palette); + } } - } - if (pskin->gl_index != 0) - { - GL_Bind(pskin->gl_index); - return; + if (pskin->gl_index != 0) + { + GL_Bind(pskin->gl_index); + return; + } } } } diff --git a/Plugins/Renderer/gl_studio.h b/Plugins/Renderer/gl_studio.h index df5cd1f8..ed0bfdd1 100644 --- a/Plugins/Renderer/gl_studio.h +++ b/Plugins/Renderer/gl_studio.h @@ -6,6 +6,8 @@ #include #include +#define MAX_STUDIO_BONE_CACHES 1024 + #define STUDIO_DIFFUSE_TEXTURE 0 #define STUDIO_REPLACE_TEXTURE 1 #define STUDIO_NORMAL_TEXTURE 2 @@ -182,6 +184,40 @@ typedef struct studio_vbo_s bool bExternalFileLoaded; }studio_vbo_t; +class studio_skin_handle +{ +public: + studio_skin_handle(int keynum) + { + m_keynum = keynum; + } + + bool operator == (const studio_skin_handle& a) const + { + return m_keynum == a.m_keynum; + } + + int m_keynum; + int m_index; +}; + +class studio_skin_hasher +{ +public: + std::size_t operator()(const studio_skin_handle& key) const + { + auto base = (std::size_t)(key.m_keynum << 8); + + base += ((std::size_t)key.m_index); + + return base; + } +}; + +typedef struct studio_skin_cache_s +{ + skin_t skins[MAX_SKINS]; +}studio_skin_cache_t; class studio_bone_handle { @@ -289,11 +325,12 @@ extern dlight_t *(*locallight)[3]; extern int *numlight; extern int* r_topcolor; extern int* r_bottomcolor; +#if 0 extern player_model_t(*DM_PlayerState)[MAX_CLIENTS]; extern skin_t(*DM_RemapSkin)[64][MAX_SKINS]; extern skin_t* (*pDM_RemapSkin)[2528][MAX_SKINS]; extern int* r_remapindex; - +#endif extern model_t *cl_sprite_white; extern model_t *cl_shellchrome; @@ -308,6 +345,7 @@ void R_StudioBoneCaches_StartFrame(); studio_vbo_t *R_PrepareStudioVBO(studiohdr_t *studiohdr); void R_StudioLoadExternalFile(model_t *mod, studiohdr_t *studiohdr, studio_vbo_t *VBOData); void R_StudioReloadVBOCache(void); +void R_StudioFlushAllSkins(); void R_ShutdownStudio(void); void R_InitStudio(void); void R_SaveStudioProgramStates(void);