From 8c69e0c6bcc4edb0560d8bf29056025380bb4dbb Mon Sep 17 00:00:00 2001 From: hzqst <113660872@qq.com> Date: Sat, 6 Jan 2024 17:45:34 +0800 Subject: [PATCH] Fixed a bug that viewmodel's normal was broken when cl_righthand=1. Fixed a bug that Renderer failed to load on HL25 engine due to OpenGL 4.2 was specified by engine. --- .../renderer/shader/studio_shader.fsh | 8 + Plugins/Renderer/gl_hooks.cpp | 145 ++++++++++-------- Plugins/Renderer/gl_local.h | 2 + Plugins/Renderer/gl_rmain.cpp | 66 +++++++- Plugins/Renderer/gl_studio.cpp | 6 +- Plugins/Renderer/gl_studio.h | 1 + Plugins/Renderer/plugins.cpp | 28 ++-- Plugins/Renderer/privatehook.h | 2 + 8 files changed, 178 insertions(+), 80 deletions(-) diff --git a/Build/svencoop/renderer/shader/studio_shader.fsh b/Build/svencoop/renderer/shader/studio_shader.fsh index c5282caa..9338cc91 100644 --- a/Build/svencoop/renderer/shader/studio_shader.fsh +++ b/Build/svencoop/renderer/shader/studio_shader.fsh @@ -546,6 +546,10 @@ vec3 R_GenerateSimplifiedNormal() } #endif + #if defined(REVERT_NORMAL_ENABLED) + vNormal = vNormal * -1.0; + #endif + return vNormal; } @@ -568,6 +572,10 @@ vec3 R_GenerateAdjustedNormal(vec3 vWorldPos, float flNormalMask) } #endif + #if defined(REVERT_NORMAL_ENABLED) + vNormal = vNormal * -1.0; + #endif + #if defined(STUDIO_NF_CELSHADE) #if defined(STUDIO_NF_CELSHADE_FACE) diff --git a/Plugins/Renderer/gl_hooks.cpp b/Plugins/Renderer/gl_hooks.cpp index 37a34002..36dbc5c1 100644 --- a/Plugins/Renderer/gl_hooks.cpp +++ b/Plugins/Renderer/gl_hooks.cpp @@ -321,6 +321,12 @@ void R_FillAddress(void) { ULONG_PTR addr; + auto hSDL2 = GetModuleHandleA("SDL2.dll"); + if (hSDL2) + { + gPrivateFuncs.SDL_GL_SetAttribute = (decltype(gPrivateFuncs.SDL_GL_SetAttribute))GetProcAddress(hSDL2, "SDL_GL_SetAttribute"); + } + auto engineFactory = g_pMetaHookAPI->GetEngineFactory(); if (engineFactory) @@ -7382,6 +7388,7 @@ hook_t *g_phook_triapi_Color4f = NULL; hook_t *g_phook_Draw_MiptexTexture = NULL; hook_t *g_phook_BuildGammaTable = NULL; hook_t *g_phook_DLL_SetModKey = NULL; +hook_t *g_phook_SDL_GL_SetAttribute = NULL; void R_UninstallHooksForEngineDLL(void) { @@ -7402,10 +7409,7 @@ void R_UninstallHooksForEngineDLL(void) } Uninstall_Hook(R_NewMap); - //Uninstall_Hook(R_CullBox); Uninstall_Hook(Mod_PointInLeaf); - //Uninstall_Hook(R_BuildLightMap);//Overrrided - //Uninstall_Hook(R_AddDynamicLights);//Overrrided Uninstall_Hook(R_GLStudioDrawPoints); Uninstall_Hook(GL_UnloadTextures); Uninstall_Hook(GL_LoadTexture2); @@ -7423,7 +7427,11 @@ void R_UninstallHooksForEngineDLL(void) Uninstall_Hook(triapi_RenderMode); Uninstall_Hook(Draw_MiptexTexture); Uninstall_Hook(BuildGammaTable); - //Uninstall_Hook(DLL_SetModKey); + + if (gPrivateFuncs.SDL_GL_SetAttribute) + { + Uninstall_Hook(SDL_GL_SetAttribute); + } Uninstall_Hook(studioapi_StudioDynamicLight); Uninstall_Hook(studioapi_StudioCheckBBox); @@ -7448,18 +7456,17 @@ void R_InstallHooks(void) } Install_InlineHook(R_NewMap); - //Install_InlineHook(R_CullBox); Install_InlineHook(Mod_PointInLeaf); - //Install_InlineHook(R_BuildLightMap);//Overrided - //Install_InlineHook(R_AddDynamicLights);//Overrided Install_InlineHook(R_GLStudioDrawPoints); Install_InlineHook(GL_UnloadTextures); Install_InlineHook(GL_LoadTexture2); Install_InlineHook(GL_BuildLightmaps); + if (!bHasOfficialGLTexAllocSupport) { Install_InlineHook(enginesurface_createNewTextureID); } + Install_InlineHook(enginesurface_drawSetTextureFile); Install_InlineHook(enginesurface_drawFlushText); Install_InlineHook(Mod_LoadStudioModel); @@ -7467,7 +7474,21 @@ void R_InstallHooks(void) Install_InlineHook(triapi_RenderMode); Install_InlineHook(Draw_MiptexTexture); Install_InlineHook(BuildGammaTable); - //Install_InlineHook(DLL_SetModKey); + + //OpenGL4.2 was forced by HL25 engine which might ruin the renderer features. + /* + if ( a1 ) + { + SDL_GL_SetAttribute(17, 4); + SDL_GL_SetAttribute(18, 2); + result = SDL_GL_SetAttribute(21, 2); + } + */ + if (g_iEngineType == ENGINE_GOLDSRC_HL25 && + gPrivateFuncs.SDL_GL_SetAttribute) + { + Install_InlineHook(SDL_GL_SetAttribute); + } } int WINAPI GL_RedirectedGenTexture(void) @@ -7475,77 +7496,79 @@ int WINAPI GL_RedirectedGenTexture(void) return GL_GenTexture(); } +/* +Purpose: Redirect all "mov eax, allocated_textures" to "call GL_RedirectedGenTexture" for legacy engine +*/ + void R_RedirectLegacyOpenGLTextureAllocation(void) { - if (!bHasOfficialGLTexAllocSupport) - { - const char pattern[] = "\xA1\x2A\x2A\x2A\x2A"; - *(ULONG_PTR*)(pattern + 1) = (ULONG_PTR)allocated_textures; + if (bHasOfficialGLTexAllocSupport) + return; + + const char pattern[] = "\xA1\x2A\x2A\x2A\x2A"; + *(ULONG_PTR*)(pattern + 1) = (ULONG_PTR)allocated_textures; - PUCHAR SearchBegin = (PUCHAR)g_dwEngineTextBase; - PUCHAR SearchLimit = (PUCHAR)g_dwEngineTextBase + g_dwEngineTextSize; - while (SearchBegin < SearchLimit) + PUCHAR SearchBegin = (PUCHAR)g_dwEngineTextBase; + PUCHAR SearchLimit = (PUCHAR)g_dwEngineTextBase + g_dwEngineTextSize; + while (SearchBegin < SearchLimit) + { + PUCHAR pFound = (PUCHAR)Search_Pattern_From_Size(SearchBegin, SearchLimit - SearchBegin, pattern); + if (pFound) { - PUCHAR pFound = (PUCHAR)Search_Pattern_From_Size(SearchBegin, SearchLimit - SearchBegin, pattern); - if (pFound) + typedef struct { - typedef struct - { - bool bFoundWriteBack; - bool bFoundGL_Bind; - }RedirectBlobEngineOpenGLTextureContext; + bool bFoundWriteBack; + bool bFoundGL_Bind; + }RedirectBlobEngineOpenGLTextureContext; - RedirectBlobEngineOpenGLTextureContext ctx = { 0 }; - - g_pMetaHookAPI->DisasmRanges(pFound, 0x100, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { + RedirectBlobEngineOpenGLTextureContext ctx = { 0 }; - auto pinst = (cs_insn*)inst; - auto ctx = (RedirectBlobEngineOpenGLTextureContext*)context; - - if (pinst->id == X86_INS_MOV && - pinst->detail->x86.op_count == 2 && - pinst->detail->x86.operands[0].type == X86_OP_MEM && - (PUCHAR)pinst->detail->x86.operands[0].mem.disp == (PUCHAR)allocated_textures && - pinst->detail->x86.operands[1].type == X86_OP_REG && - pinst->detail->x86.operands[1].reg == X86_REG_EAX) - { - ctx->bFoundWriteBack = true; - } + g_pMetaHookAPI->DisasmRanges(pFound, 0x100, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) { - if (address[0] == 0xE8 && - (PUCHAR)pinst->detail->x86.operands[0].imm == (PUCHAR)gPrivateFuncs.GL_Bind) - { - ctx->bFoundGL_Bind = true; - } + auto pinst = (cs_insn*)inst; + auto ctx = (RedirectBlobEngineOpenGLTextureContext*)context; - if (ctx->bFoundWriteBack || ctx->bFoundGL_Bind) - return TRUE; + if (pinst->id == X86_INS_MOV && + pinst->detail->x86.op_count == 2 && + pinst->detail->x86.operands[0].type == X86_OP_MEM && + (PUCHAR)pinst->detail->x86.operands[0].mem.disp == (PUCHAR)allocated_textures && + pinst->detail->x86.operands[1].type == X86_OP_REG && + pinst->detail->x86.operands[1].reg == X86_REG_EAX) + { + ctx->bFoundWriteBack = true; + } - if (address[0] == 0xCC) - return TRUE; + if (address[0] == 0xE8 && + (PUCHAR)pinst->detail->x86.operands[0].imm == (PUCHAR)gPrivateFuncs.GL_Bind) + { + ctx->bFoundGL_Bind = true; + } - if (pinst->id == X86_INS_RET) - return TRUE; + if (ctx->bFoundWriteBack || ctx->bFoundGL_Bind) + return TRUE; - return FALSE; + if (address[0] == 0xCC) + return TRUE; - }, 0, &ctx); + if (pinst->id == X86_INS_RET) + return TRUE; - if (ctx.bFoundWriteBack || ctx.bFoundGL_Bind) - { - char redirect[] = "\xE8\x2A\x2A\x2A\x2A"; - *(int*)(redirect + 1) = (PUCHAR)GL_RedirectedGenTexture - (pFound + 5); - g_pMetaHookAPI->WriteMemory(pFound, redirect, sizeof(redirect) - 1); + return FALSE; - //gEngfuncs.Con_Printf("%p redirected\n", pFound); - } + }, 0, &ctx); - SearchBegin = pFound + Sig_Length(pattern); - } - else + if (ctx.bFoundWriteBack || ctx.bFoundGL_Bind) { - break; + char redirect[] = "\xE8\x2A\x2A\x2A\x2A"; + *(int*)(redirect + 1) = (PUCHAR)GL_RedirectedGenTexture - (pFound + 5); + g_pMetaHookAPI->WriteMemory(pFound, redirect, sizeof(redirect) - 1); } + + SearchBegin = pFound + Sig_Length(pattern); + } + else + { + break; } } } \ No newline at end of file diff --git a/Plugins/Renderer/gl_local.h b/Plugins/Renderer/gl_local.h index ec598423..342449c1 100644 --- a/Plugins/Renderer/gl_local.h +++ b/Plugins/Renderer/gl_local.h @@ -524,6 +524,8 @@ TEMPENTITY *EngineGetTempTentByIndex(int index); void RemoveFileExtension(std::string& filePath); +int _cdecl SDL_GL_SetAttribute(int attr, int value); + //void DLL_SetModKey(void *pinfo, char *pkey, char *pvalue); extern GLint r_viewport[4]; diff --git a/Plugins/Renderer/gl_rmain.cpp b/Plugins/Renderer/gl_rmain.cpp index 16ff51e8..3edc0adb 100644 --- a/Plugins/Renderer/gl_rmain.cpp +++ b/Plugins/Renderer/gl_rmain.cpp @@ -1608,11 +1608,11 @@ void GL_Init(void) return; } - //if (!GLEW_VERSION_4_3) - //{ - //g_pMetaHookAPI->SysError("OpenGL 4.3 is not supported!\nRequirement: Nvidia GeForce 400 series and newer / AMD Radeon HD 5000 Series and newer / Intel HD Graphics in Intel Haswell and newer.\n"); - //return; - //} + if (!GLEW_VERSION_4_3) + { + g_pMetaHookAPI->SysError("OpenGL 4.3 is not supported!\n"); + return; + } //No vanilla detail texture support (*detTexSupported) = false; @@ -3951,4 +3951,60 @@ void GammaToLinear(float *color) color[0] = pow(color[0], v_gamma->value); color[1] = pow(color[1], v_gamma->value); color[2] = pow(color[2], v_gamma->value); +} + +typedef enum +{ + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR, + SDL_GL_CONTEXT_RESET_NOTIFICATION, + SDL_GL_CONTEXT_NO_ERROR +} SDL_GLattr; + +typedef enum +{ + SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, + SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, + SDL_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */ +} SDL_GLprofile; + +int __cdecl SDL_GL_SetAttribute(int attr, int value) +{ + if (attr == SDL_GL_CONTEXT_MAJOR_VERSION) + { + return gPrivateFuncs.SDL_GL_SetAttribute(attr, 4); + } + if (attr == SDL_GL_CONTEXT_MINOR_VERSION) + { + return gPrivateFuncs.SDL_GL_SetAttribute(attr, 3); + } + if (attr == SDL_GL_CONTEXT_PROFILE_MASK) + { + return gPrivateFuncs.SDL_GL_SetAttribute(attr, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + } + + return gPrivateFuncs.SDL_GL_SetAttribute(attr, value); } \ No newline at end of file diff --git a/Plugins/Renderer/gl_studio.cpp b/Plugins/Renderer/gl_studio.cpp index ab4afc98..cf725c2c 100644 --- a/Plugins/Renderer/gl_studio.cpp +++ b/Plugins/Renderer/gl_studio.cpp @@ -641,6 +641,9 @@ void R_UseStudioProgram(program_state_t state, studio_program_t* progOutput) if (state & STUDIO_ANIMATED_TEXTURE_ENABLED) defs << "#define ANIMATED_TEXTURE_ENABLED\n"; + if (state & STUDIO_REVERT_NORMAL_ENABLED) + defs << "#define REVERT_NORMAL_ENABLED\n"; + if (glewIsSupported("GL_NV_bindless_texture")) defs << "#define NV_BINDLESS_ENABLED\n"; @@ -1073,6 +1076,7 @@ const program_state_mapping_t s_StudioProgramStateName[] = { { STUDIO_PACKED_PARALLAXTEXTURE_ENABLED ,"STUDIO_PACKED_PARALLAXTEXTURE_ENABLED" }, { STUDIO_PACKED_SPECULARTEXTURE_ENABLED ,"STUDIO_PACKED_SPECULARTEXTURE_ENABLED" }, { STUDIO_ANIMATED_TEXTURE_ENABLED ,"STUDIO_ANIMATED_TEXTURE_ENABLED" }, +{ STUDIO_REVERT_NORMAL_ENABLED ,"STUDIO_REVERT_NORMAL_ENABLED" }, { STUDIO_NF_FLATSHADE ,"STUDIO_NF_FLATSHADE" }, { STUDIO_NF_CHROME ,"STUDIO_NF_CHROME" }, @@ -2186,7 +2190,7 @@ void R_StudioDrawVBOMesh_DrawPass( if (R_IsFlippedViewModel()) { - StudioProgramState |= STUDIO_NF_DOUBLE_FACE; + StudioProgramState |= (STUDIO_NF_DOUBLE_FACE | STUDIO_REVERT_NORMAL_ENABLED); } if (StudioProgramState & STUDIO_NF_DOUBLE_FACE) diff --git a/Plugins/Renderer/gl_studio.h b/Plugins/Renderer/gl_studio.h index e6accda1..ba28256d 100644 --- a/Plugins/Renderer/gl_studio.h +++ b/Plugins/Renderer/gl_studio.h @@ -441,5 +441,6 @@ extern r_studio_interface_t **gpStudioInterface; #define STUDIO_PACKED_PARALLAXTEXTURE_ENABLED 0x10000000000ull #define STUDIO_PACKED_SPECULARTEXTURE_ENABLED 0x20000000000ull #define STUDIO_ANIMATED_TEXTURE_ENABLED 0x40000000000ull +#define STUDIO_REVERT_NORMAL_ENABLED 0x80000000000ull #define STUDIO_PACKED_TEXTURE_ALLBITS (STUDIO_PACKED_DIFFUSETEXTURE_ENABLED | STUDIO_PACKED_NORMALTEXTURE_ENABLED | STUDIO_PACKED_PARALLAXTEXTURE_ENABLED | STUDIO_PACKED_SPECULARTEXTURE_ENABLED) diff --git a/Plugins/Renderer/plugins.cpp b/Plugins/Renderer/plugins.cpp index 66b4f598..813082f7 100644 --- a/Plugins/Renderer/plugins.cpp +++ b/Plugins/Renderer/plugins.cpp @@ -9,19 +9,21 @@ mh_enginesave_t *g_pMetaSave = NULL; IFileSystem *g_pFileSystem = NULL; IFileSystem_HL25* g_pFileSystem_HL25 = NULL; -HINSTANCE g_hInstance, g_hThisModule, g_hEngineModule; -PVOID g_dwEngineBase; -DWORD g_dwEngineSize; -PVOID g_dwEngineTextBase; -DWORD g_dwEngineTextSize; -PVOID g_dwEngineDataBase; -DWORD g_dwEngineDataSize; -PVOID g_dwEngineRdataBase; -DWORD g_dwEngineRdataSize; -DWORD g_dwEngineBuildnum; -int g_iEngineType; -PVOID g_dwClientBase; -DWORD g_dwClientSize; +HINSTANCE g_hInstance = 0; +HMODULE g_hThisModule = 0; +HMODULE g_hEngineModule = 0; +PVOID g_dwEngineBase = 0; +DWORD g_dwEngineSize = 0; +PVOID g_dwEngineTextBase = 0; +DWORD g_dwEngineTextSize = 0; +PVOID g_dwEngineDataBase = 0; +DWORD g_dwEngineDataSize = 0; +PVOID g_dwEngineRdataBase = 0; +DWORD g_dwEngineRdataSize = 0; +DWORD g_dwEngineBuildnum = 0; +int g_iEngineType = 0; +PVOID g_dwClientBase = 0; +DWORD g_dwClientSize = 0; void IPluginsV4::Init(metahook_api_t *pAPI, mh_interface_t *pInterface, mh_enginesave_t *pSave) { diff --git a/Plugins/Renderer/privatehook.h b/Plugins/Renderer/privatehook.h index 754eaf28..92a1264c 100644 --- a/Plugins/Renderer/privatehook.h +++ b/Plugins/Renderer/privatehook.h @@ -142,6 +142,8 @@ typedef struct void(*R_StudioSetupBones)(void); void(*R_StudioMergeBones)(model_t *pSubModel); + //SDL2 + int (__cdecl * SDL_GL_SetAttribute)(int attr, int value); }private_funcs_t; extern hook_t* g_phook_GL_Init;