From 02d12af47ee289223326702076a694ae50115718 Mon Sep 17 00:00:00 2001 From: hzqst <113660872@qq.com> Date: Mon, 22 Jan 2024 00:09:45 +0800 Subject: [PATCH] Use cl.time instead of GetSystemTime in Subtitle System. --- Plugins/CaptionMod/GameUI.cpp | 6 +- Plugins/CaptionMod/SubtitlePanel.cpp | 107 ++++++++------ Plugins/CaptionMod/SubtitlePanel.h | 12 +- Plugins/CaptionMod/Viewport.cpp | 94 +++++++------ Plugins/CaptionMod/Viewport.h | 7 +- Plugins/CaptionMod/exportfuncs.cpp | 23 ++- Plugins/CaptionMod/exportfuncs.h | 4 +- Plugins/CaptionMod/privatefuncs.cpp | 26 +++- Plugins/CaptionMod/privatefuncs.h | 2 + Plugins/Renderer/gl_rmain.cpp | 9 +- Plugins/Renderer/gl_wsurf.cpp | 201 ++++++++++++++------------- 11 files changed, 287 insertions(+), 204 deletions(-) diff --git a/Plugins/CaptionMod/GameUI.cpp b/Plugins/CaptionMod/GameUI.cpp index 082a534d..d2d562ce 100644 --- a/Plugins/CaptionMod/GameUI.cpp +++ b/Plugins/CaptionMod/GameUI.cpp @@ -264,8 +264,12 @@ void CGameUI::RunFrame(void) void CGameUI::ConnectToServer(const char *game, int IP, int port) { - if(gEngfuncs.GetMaxClients() > 1) + g_pViewPort->ConnectToServer(game, IP, port); + + if (gEngfuncs.GetMaxClients() > 1) + { return g_pfnCGameUI_ConnectToServer(this, 0, game, IP, port); + } //This just stop GameUI from sending "mp3 stop" on level transition return g_pfnCGameUI_ConnectToServer(this, 0, "valve", IP, port); diff --git a/Plugins/CaptionMod/SubtitlePanel.cpp b/Plugins/CaptionMod/SubtitlePanel.cpp index 9c438470..a66b1ee1 100644 --- a/Plugins/CaptionMod/SubtitlePanel.cpp +++ b/Plugins/CaptionMod/SubtitlePanel.cpp @@ -26,8 +26,8 @@ SubtitlePanel::SubtitlePanel(Panel *parent) : EditablePanel(parent, "Subtitle") m_hTextFont = NULL; m_iAntiSpam = 0; m_iCornorSize = 0; - m_iCurPanelY = 0; - m_iCurPanelYEnd = 0; + m_flCurPanelY = 0; + m_flCurPanelYEnd = 0; m_iFontTall = 0; m_iLineSpace = 0; m_iMaxLines = 0; @@ -144,8 +144,8 @@ void SubtitlePanel::ApplySchemeSettings(vgui::IScheme *pScheme) m_iMaxLines = max(1, m_iMaxLines-1); m_iPanelTop = iTextTall - (m_iMaxLines - 1) * m_iScaledLineSpace - m_iMaxLines * m_iFontTall; - m_iCurPanelY = 0; - m_iCurPanelYEnd = GetTall(); + m_flCurPanelY = 0; + m_flCurPanelYEnd = GetTall(); m_iPanelY = 9999; m_iPanelYEnd = -9999; } @@ -164,7 +164,7 @@ bool CAnimMovement::Update(void) m_Started = true; m_StartValue = m_Line->m_YPos; } - float frac = min((g_pViewPort->GetSystemTime() - m_StartTime) / m_AnimTime, 1); + float frac = min((g_pViewPort->GetCurTime() - m_StartTime) / m_AnimTime, 1); m_Line->m_YPos = (int)(frac * m_EndValue + (1 - frac) * m_StartValue); } return true; @@ -184,7 +184,7 @@ bool CAnimAlphaFade::Update(void) m_Started = true; m_StartValue = m_Line->m_Alpha; } - float frac = min((g_pViewPort->GetSystemTime() - m_StartTime) / m_AnimTime, 1); + float frac = min((g_pViewPort->GetCurTime() - m_StartTime) / m_AnimTime, 1); m_Line->m_Alpha = (int)(frac * m_EndValue + (1 - frac) * m_StartValue); } return true; @@ -202,12 +202,12 @@ float CSubLine::GetYPosOutRate(void) bool CSubLine::ShouldStart(void) { - return (g_pViewPort->GetSystemTime() > m_StartTime); + return (g_pViewPort->GetCurTime() > m_StartTime); } bool CSubLine::ShouldRetire(void) { - return (g_pViewPort->GetSystemTime() > m_EndTime || m_LineIndex > m_Panel->m_iMaxLines); + return (g_pViewPort->GetCurTime() > m_EndTime || m_LineIndex > m_Panel->m_iMaxLines); } bool CSubLine::Update(void) @@ -246,13 +246,13 @@ void CSubLine::MoveTo(int ToPos, float Time) i --; } } - CSubLineAnim *Anim = (CSubLineAnim *)new CAnimMovement(g_pViewPort->GetSystemTime(), Time, ToPos, this); + CSubLineAnim *Anim = (CSubLineAnim *)new CAnimMovement(g_pViewPort->GetCurTime(), Time, ToPos, this); m_AnimList[m_AnimList.AddToTail()] = Anim; } void CSubLine::AlphaFade(int Alpha, float Time) { - CSubLineAnim *Anim = (CSubLineAnim *)new CAnimAlphaFade(g_pViewPort->GetSystemTime(), Time, Alpha, this); + CSubLineAnim *Anim = (CSubLineAnim *)new CAnimAlphaFade(g_pViewPort->GetCurTime(), Time, Alpha, this); m_AnimList[m_AnimList.AddToTail()] = Anim; } @@ -302,7 +302,7 @@ void SubtitlePanel::StartNextSubtitle(CDictionary *pDict) if(pNextDict) { - StartSubtitle(pNextDict, pDict->m_flDuration, g_pViewPort->GetSystemTime() + pDict->m_flNextDelay); + StartSubtitle(pNextDict, pDict->m_flDuration, g_pViewPort->GetCurTime() + pDict->m_flNextDelay); } } @@ -364,10 +364,10 @@ void SubtitlePanel::StartLine(CSubLine *Line) if (Line->m_StartTime == 0) { - Line->m_StartTime = g_pViewPort->GetSystemTime(); + Line->m_StartTime = g_pViewPort->GetCurTime(); } - //Give it the lastest endtime + //Give it the latest endtime Line->m_EndTime = max(Line->m_StartTime + Line->m_Duration, latestEndTime); //Fade it now @@ -642,27 +642,42 @@ void SubtitlePanel::UpdateSubtitlePanelVars(SubtitlePanelVars_t *vars) void SubtitlePanel::VidInit(void) { - if(gEngfuncs.GetMaxClients() > 1) - ClearSubtitle(); + } -//#include +void SubtitlePanel::ConnectToServer(const char* game, int IP, int port) +{ + if (gEngfuncs.GetMaxClients() > 1) + { + ClearSubtitle(); + } +} -void SubtitlePanel::Paint(void) +void SubtitlePanel::AdjustClock(double flAdjustment) { - //if (SCR_IsLoadingVisible()) - // return; + for (int i = 0; i < m_Lines.Count(); ++i) + { + auto pLine = m_Lines[i]; - //Remove any raw OpenGL call - //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - gEngfuncs.pTriAPI->RenderMode(kRenderTransAlpha); + pLine->m_EndTime += flAdjustment; + pLine->m_StartTime += flAdjustment; + } + for (int i = 0; i < m_BackLines.Count(); ++i) + { + auto pLine = m_BackLines[i]; - int x; + pLine->m_EndTime += flAdjustment; + pLine->m_StartTime += flAdjustment; + } +} + +void SubtitlePanel::Paint(void) +{ int iPanelWidth, iPanelHeight; GetSize(iPanelWidth, iPanelHeight); - x = m_iScaledXSpace; + int x = m_iScaledXSpace; m_iPanelY = 9999; m_iPanelYEnd = -9999; m_iPanelAlpha = 0; @@ -690,10 +705,10 @@ void SubtitlePanel::Paint(void) } //Check if the panel is trying to fade in when it's fully hidden - if(m_iCurPanelY > m_iCurPanelYEnd && m_iPanelY < m_iPanelYEnd) + if(m_flCurPanelY > m_flCurPanelYEnd && m_iPanelY < m_iPanelYEnd) { - m_iCurPanelY = m_iPanelY; - m_iCurPanelYEnd = m_iPanelYEnd; + m_flCurPanelY = m_iPanelY; + m_flCurPanelYEnd = m_iPanelYEnd; } //The panel's top won't be higher than m_iPanelTop @@ -708,24 +723,24 @@ void SubtitlePanel::Paint(void) m_iPanelYEnd = 0; //Panel scaling animation - if(m_iCurPanelY != m_iPanelY) + if(m_flCurPanelY != m_iPanelY) { - int sign = (m_iPanelY - m_iCurPanelY) ? 1 : -1; - m_iCurPanelY += sign * 200.0f * (g_pViewPort->GetFrameTime()); - if(sign == 1 && m_iCurPanelY > m_iPanelY) - m_iCurPanelY = m_iPanelY; - else if(sign == -1 && m_iCurPanelY < m_iPanelY) - m_iCurPanelY = m_iPanelY; + int sign = (m_iPanelY - m_flCurPanelY) ? 1 : -1; + m_flCurPanelY += sign * 200.0f * (g_pViewPort->GetFrameTime()); + if(sign == 1 && m_flCurPanelY > m_iPanelY) + m_flCurPanelY = m_iPanelY; + else if(sign == -1 && m_flCurPanelY < m_iPanelY) + m_flCurPanelY = m_iPanelY; } - if(m_iCurPanelYEnd != m_iPanelYEnd) + if(m_flCurPanelYEnd != m_iPanelYEnd) { - int sign = (m_iPanelYEnd - m_iCurPanelYEnd) ? 1 : -1; - m_iCurPanelYEnd += sign * 200.0f * (g_pViewPort->GetFrameTime()); - if(sign == 1 && m_iCurPanelYEnd > m_iPanelYEnd) - m_iCurPanelYEnd = m_iPanelYEnd; - else if(sign == -1 && m_iCurPanelYEnd < m_iPanelYEnd) - m_iCurPanelYEnd = m_iPanelYEnd; + int sign = (m_iPanelYEnd - m_flCurPanelYEnd) ? 1 : -1; + m_flCurPanelYEnd += sign * 200.0f * (g_pViewPort->GetFrameTime()); + if(sign == 1 && m_flCurPanelYEnd > m_iPanelYEnd) + m_flCurPanelYEnd = m_iPanelYEnd; + else if(sign == -1 && m_flCurPanelYEnd < m_iPanelYEnd) + m_flCurPanelYEnd = m_iPanelYEnd; } } @@ -738,9 +753,9 @@ void SubtitlePanel::PaintBackground(void) //Use the Current value since we want the animation x = 0; - y = m_iCurPanelY; + y = m_flCurPanelY; w = iPanelWidth; - h = m_iCurPanelYEnd - m_iCurPanelY; + h = m_flCurPanelYEnd - m_flCurPanelY; if(h <= 0) return; @@ -750,9 +765,11 @@ void SubtitlePanel::PaintBackground(void) //Remove any raw OpenGL call //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + //Force GL_MODULATE to be applied gEngfuncs.pTriAPI->RenderMode(kRenderTransAlpha); - //Cornor is maximum at 1/4 wide or tall + //Corner is maximum at 1/4 wide or tall r = min(min(m_iScaledCornorSize, h / 4), w / 4); //Do the AlphaMultiplier @@ -782,4 +799,6 @@ void SubtitlePanel::PaintBackground(void) surface()->DrawSetTexture(m_iRoundCornorMaterial[3]); surface()->DrawTexturedRect(x, y+h-r, x+r, y+h); + + gEngfuncs.pTriAPI->RenderMode(kRenderNormal); } diff --git a/Plugins/CaptionMod/SubtitlePanel.h b/Plugins/CaptionMod/SubtitlePanel.h index ed1a657e..7f57fc0f 100644 --- a/Plugins/CaptionMod/SubtitlePanel.h +++ b/Plugins/CaptionMod/SubtitlePanel.h @@ -33,11 +33,11 @@ class CSubLineAnim } virtual bool IsPlaying(void) { - return (g_pViewPort->GetSystemTime() >= m_StartTime && g_pViewPort->GetSystemTime() < m_StartTime + m_AnimTime); + return (g_pViewPort->GetCurTime() >= m_StartTime && g_pViewPort->GetCurTime() < m_StartTime + m_AnimTime); } virtual bool IsDonePlay(void) { - return (g_pViewPort->GetSystemTime() >= m_StartTime + m_AnimTime); + return (g_pViewPort->GetCurTime() >= m_StartTime + m_AnimTime); } virtual LineAnim_t GetType(void) = 0; virtual bool Update(void) = 0; @@ -131,7 +131,8 @@ class SubtitlePanel : public vgui::EditablePanel SubtitlePanel(Panel *parent); virtual ~SubtitlePanel(); void VidInit(void); - + void ConnectToServer(const char* game, int IP, int port); + void AdjustClock(double flAdjustment); public://Subtitle interface void StartSubtitle(CDictionary * pDict, float flDurationTime, float flStartTime); void StartNextSubtitle(CDictionary *pDict); @@ -180,8 +181,9 @@ class SubtitlePanel : public vgui::EditablePanel int m_iPanelYEnd; int m_iPanelAlpha; //For panel scaling animation - int m_iCurPanelY; - int m_iCurPanelYEnd; + float m_flCurPanelY; + float m_flCurPanelYEnd; + //Textures int m_iRoundCornorMaterial[4]; //The lines that displaying now CUtlVector m_Lines; diff --git a/Plugins/CaptionMod/Viewport.cpp b/Plugins/CaptionMod/Viewport.cpp index 89b6927c..5a3e5c03 100644 --- a/Plugins/CaptionMod/Viewport.cpp +++ b/Plugins/CaptionMod/Viewport.cpp @@ -41,11 +41,10 @@ CViewport::CViewport(void) : Panel(NULL, "CaptionViewport") SetKeyBoardInputEnabled(false); SetProportional(true); m_pSubtitlePanel = NULL; + m_pChatDialog = NULL; m_szLevelName[0] = 0; - m_SystemTime = 0; - m_OldSystemTime = 0; - m_FrameTime = 0; + m_CurTime = 0; } CViewport::~CViewport(void) @@ -842,19 +841,6 @@ void CDictionary::FinalizeString(std::wstring &output, int iPrefix) searchStart = result.suffix().first; } - /*if (bReplaced && m_pTextMessage) - { - if (m_pTextMessage->pMessage) - delete m_pTextMessage->pMessage; - - //Covert the text to UTF8 - int utf8Length = WideCharToMultiByte(CP_UTF8, 0, &output[0], -1, NULL, 0, NULL, NULL); - char* utf8Text = new char[utf8Length + 1]; - WideCharToMultiByte(CP_UTF8, 0, &output[0], -1, utf8Text, utf8Length, NULL, NULL); - utf8Text[utf8Length] = '\0'; - m_pTextMessage->pMessage = utf8Text; - }*/ - if(iPrefix) output = m_szSpeaker + finalize; else @@ -881,32 +867,15 @@ void CViewport::SetParent(VPANEL vPanel) void CViewport::Think(void) { - auto levelname = gEngfuncs.pfnGetLevelName(); - if (!levelname || !levelname[0]) - return; - - if (0 != strcmp(levelname, m_szLevelName)) + if ((*cl_time) > 1) { - std::string name = levelname; - name = name.substr(0, name.length() - 4); - name += "_dictionary.csv"; - - LoadCustomDictionary(name.c_str()); - - if (0 != strcmp(m_szCurrentLanguage, "english")) + if ((*cl_time) < m_CurTime) { - name = levelname; - name = name.substr(0, name.length() - 4); - name += "_dictionary_"; - name += m_szCurrentLanguage; - name += ".csv"; - - LoadCustomDictionary(name.c_str()); + if (m_pSubtitlePanel) + m_pSubtitlePanel->AdjustClock((*cl_time) - m_CurTime); } - LinkDictionary(); - - strcpy(m_szLevelName, levelname); + m_CurTime = (*cl_time); } } @@ -931,7 +900,7 @@ void CViewport::Init(void) void CViewport::StartSubtitle(CDictionary *dict, float flDurationTime) { if (cap_enabled && cap_enabled->value) { - m_pSubtitlePanel->StartSubtitle(dict, flDurationTime, g_pViewPort->GetSystemTime()); + m_pSubtitlePanel->StartSubtitle(dict, flDurationTime, g_pViewPort->GetCurTime()); } } @@ -942,6 +911,43 @@ void CViewport::StartNextSubtitle(CDictionary* dict) } } +void CViewport::ConnectToServer(const char* game, int IP, int port) +{ + auto szLevelName = gEngfuncs.pfnGetLevelName(); + + if (!szLevelName || !szLevelName[0]) + return; + + if (0 != strcmp(szLevelName, m_szLevelName)) + { + std::string name = szLevelName; + RemoveFileExtension(name); + name += "_dictionary.csv"; + + LoadCustomDictionary(name.c_str()); + + if (0 != strcmp(m_szCurrentLanguage, "english")) + { + name = szLevelName; + RemoveFileExtension(name); + name += "_dictionary_"; + name += m_szCurrentLanguage; + name += ".csv"; + + LoadCustomDictionary(name.c_str()); + } + + LinkDictionary(); + + strncpy(m_szLevelName, szLevelName, sizeof(m_szLevelName) - 1); + m_szLevelName[sizeof(m_szLevelName) - 1] = 0; + } + + if(m_pSubtitlePanel) + m_pSubtitlePanel->ConnectToServer(game, IP, port); + +} + void CViewport::ActivateClientUI(void) { SetVisible(true); @@ -952,24 +958,20 @@ void CViewport::HideClientUI(void) SetVisible(false); } -double CViewport::GetSystemTime(void) const +double CViewport::GetCurTime(void) const { - return m_SystemTime; + return (*cl_time); } double CViewport::GetFrameTime(void) const { - return m_FrameTime; + return (*cl_time) - (*cl_oldtime); } void CViewport::Paint(void) { BaseClass::Paint(); - m_SystemTime = system()->GetCurrentTime(); - m_FrameTime = m_SystemTime - m_OldSystemTime; - m_OldSystemTime = m_SystemTime; - m_HudMessage.Draw(); m_HudMenu.Draw(); } diff --git a/Plugins/CaptionMod/Viewport.h b/Plugins/CaptionMod/Viewport.h index cc132780..90f8083e 100644 --- a/Plugins/CaptionMod/Viewport.h +++ b/Plugins/CaptionMod/Viewport.h @@ -113,6 +113,7 @@ class CViewport : public vgui::Panel void Think(void); void Paint(void); void SetParent(vgui::VPANEL vPanel); + void ConnectToServer(const char* game, int IP, int port); void ActivateClientUI(void); void HideClientUI(void); void LoadBaseDictionary(void); @@ -141,7 +142,7 @@ class CViewport : public vgui::Panel void ChatPrintf(int iPlayerIndex, const wchar_t *buffer); void QuerySubtitlePanelVars(SubtitlePanelVars_t *vars); void UpdateSubtitlePanelVars(SubtitlePanelVars_t *vars); - double GetSystemTime(void) const; + double GetCurTime(void) const; double GetFrameTime(void) const; private: SubtitlePanel *m_pSubtitlePanel; @@ -149,9 +150,7 @@ class CViewport : public vgui::Panel CUtlVector m_Dictionary; CUtlVector m_StringsHashTable; char m_szLevelName[256]; - double m_SystemTime; - double m_OldSystemTime; - double m_FrameTime; + double m_CurTime; }; extern CViewport *g_pViewPort; \ No newline at end of file diff --git a/Plugins/CaptionMod/exportfuncs.cpp b/Plugins/CaptionMod/exportfuncs.cpp index bc1932d5..7ec640e2 100644 --- a/Plugins/CaptionMod/exportfuncs.cpp +++ b/Plugins/CaptionMod/exportfuncs.cpp @@ -1290,4 +1290,25 @@ void InitWin32Stuffs(void) g_MainWndProc = (WNDPROC)GetWindowLong(g_MainWnd, GWL_WNDPROC); SetWindowLong(g_MainWnd, GWL_WNDPROC, (LONG)VID_MainWndProc); -} \ No newline at end of file +} + + +void RemoveFileExtension(std::string& filePath) +{ + // Find the last occurrence of '.' + size_t lastDotPosition = filePath.find_last_of("."); + + // Check if the dot is part of a directory component rather than an extension + size_t lastPathSeparator = filePath.find_last_of("/\\"); + + if (lastDotPosition != std::string::npos) { + // Ensure the dot is after the last path separator + if (lastPathSeparator != std::string::npos && lastDotPosition < lastPathSeparator) { + return; // Dot is part of a directory name, not an extension + } + // Return the substring from the beginning to the dot + filePath = filePath.substr(0, lastDotPosition); + } + + // No extension found, return the original path +} diff --git a/Plugins/CaptionMod/exportfuncs.h b/Plugins/CaptionMod/exportfuncs.h index 2e5d0b40..6da391d8 100644 --- a/Plugins/CaptionMod/exportfuncs.h +++ b/Plugins/CaptionMod/exportfuncs.h @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include @@ -14,6 +13,7 @@ #include #include #include "enginedef.h" +#include extern cl_enginefunc_t gEngfuncs; @@ -59,6 +59,8 @@ void SDL_GetWindowSize(void* window, int* w, int* h); void InitWin32Stuffs(void); +void RemoveFileExtension(std::string& filePath); + extern cvar_t* cap_debug; extern cvar_t* cap_enabled; extern cvar_t* cap_max_distance; diff --git a/Plugins/CaptionMod/privatefuncs.cpp b/Plugins/CaptionMod/privatefuncs.cpp index 624d5295..403c396b 100644 --- a/Plugins/CaptionMod/privatefuncs.cpp +++ b/Plugins/CaptionMod/privatefuncs.cpp @@ -46,16 +46,15 @@ double *cl_time = NULL; double *cl_oldtime = NULL; +double *realtime = NULL; + +int* cl_viewentity = NULL; char *(*rgpszrawsentence)[CVOXFILESENTENCEMAX] = NULL; int *cszrawsentences = NULL; -int *cl_viewentity = NULL; - vec3_t *listener_origin = NULL; -//not used -//char(*s_pBaseDir)[512] = NULL; char* (*hostparam_basedir) = NULL; qboolean *scr_drawloading = NULL; @@ -173,6 +172,25 @@ PVOID VGUI2_FindPanelInit(PVOID TextBase, ULONG TextSize) void Engine_FillAddress(void) { + if (g_iEngineType == ENGINE_GOLDSRC_HL25) + { + char pattern[] = "\x01\x00\x00\x00\xF2\x0F\x10\x05\x2A\x2A\x2A\x2A\x66\x0F\x5A\xC0\x6A\x60"; + + auto addr = (PUCHAR)Search_Pattern(pattern); + Sig_AddrNotFound("realtime"); + + realtime = *(decltype(realtime)*)(addr + 8); + } + else + { + char pattern[] = "\x01\x00\x00\x00\xDD\x05\x2A\x2A\x2A\x2A\x6A\x60"; + + auto addr = (PUCHAR)Search_Pattern(pattern); + Sig_AddrNotFound("realtime"); + + realtime = *(decltype(realtime)*)(addr + 6); + } + if (1) { /* diff --git a/Plugins/CaptionMod/privatefuncs.h b/Plugins/CaptionMod/privatefuncs.h index efbc4d0c..a9313c38 100644 --- a/Plugins/CaptionMod/privatefuncs.h +++ b/Plugins/CaptionMod/privatefuncs.h @@ -121,6 +121,8 @@ extern void *gHud; extern double *cl_time; extern double *cl_oldtime; +extern double* realtime; + extern int *cl_viewentity; extern vec3_t *listener_origin; diff --git a/Plugins/Renderer/gl_rmain.cpp b/Plugins/Renderer/gl_rmain.cpp index 933c69e2..ca8a503c 100644 --- a/Plugins/Renderer/gl_rmain.cpp +++ b/Plugins/Renderer/gl_rmain.cpp @@ -2532,16 +2532,15 @@ void R_UnloadNoreferenceModels() void R_NewMap(void) { - R_GenerateSceneUBO(); - - gPrivateFuncs.R_NewMap(); - r_worldentity = gEngfuncs.GetEntityByIndex(0); r_worldmodel = r_worldentity->model; r_playermodel = NULL; - memset(&r_params, 0, sizeof(r_params)); + R_GenerateSceneUBO(); + + gPrivateFuncs.R_NewMap(); + R_NewMapWater(); R_NewMapPortal(); R_NewMapWSurf(); diff --git a/Plugins/Renderer/gl_wsurf.cpp b/Plugins/Renderer/gl_wsurf.cpp index d5f25ae3..cc787f94 100644 --- a/Plugins/Renderer/gl_wsurf.cpp +++ b/Plugins/Renderer/gl_wsurf.cpp @@ -404,20 +404,23 @@ void R_RecursiveFindLeaves(mbasenode_t *basenode, std::set &vLeafs) R_RecursiveFindLeaves(node->children[1], vLeafs); } -void R_MarkPVSForLeaf(mleaf_t *leaf, std::set& pvsnodes) +void R_MarkPVSForLeaf(mleaf_t *leaf, int visframecount) { //Decompress vis bytes from world model. auto vis = Mod_LeafPVS(leaf, r_worldmodel); for (int i = 0; i < r_worldmodel->numleafs; i++) { - if (vis[i >> 3] & (1 << (i & 7))) + if ((byte)(1 << (i & 7)) & vis[i >> 3]) { auto basenode = (mbasenode_t *)&r_worldmodel->leafs[i + 1]; do { - pvsnodes.emplace(basenode); + if (basenode->visframe == visframecount) + break; + + basenode->visframe = visframecount; basenode = basenode->parent; @@ -426,12 +429,12 @@ void R_MarkPVSForLeaf(mleaf_t *leaf, std::set& pvsnodes) } } -void R_RecursiveMarkSurfaces(mbasenode_t *basenode, const std::set& pvsnodes, std::set& marksurfs) +void R_RecursiveMarkSurfaces(mbasenode_t *basenode, int visframecount, int framecount) { if (basenode->contents == CONTENTS_SOLID) return; - if (pvsnodes.find(basenode) == pvsnodes.end()) + if (basenode->visframe != visframecount) return; if (basenode->contents < 0) @@ -443,16 +446,16 @@ void R_RecursiveMarkSurfaces(mbasenode_t *basenode, const std::set for (int i = 0; i < nummarks; ++i) { - marksurfs.emplace(marks[i]); + marks[i]->visframe = framecount; } return; } auto node = (mnode_t*)basenode; - R_RecursiveMarkSurfaces(node->children[0], pvsnodes, marksurfs); + R_RecursiveMarkSurfaces(node->children[0], visframecount, framecount); - R_RecursiveMarkSurfaces(node->children[1], pvsnodes, marksurfs); + R_RecursiveMarkSurfaces(node->children[1], visframecount, framecount); } void R_CollectWaterVBO(msurface_t* surf, int direction, wsurf_vbo_leaf_t* leaf) @@ -465,12 +468,12 @@ void R_CollectWaterVBO(msurface_t* surf, int direction, wsurf_vbo_leaf_t* leaf) } } -void R_RecursiveLinkTextureChain(mbasenode_t *basenode, const std::set& pvsnodes, const std::set& marksurfs, wsurf_vbo_leaf_t *leaf) +void R_RecursiveLinkTextureChain(mbasenode_t *basenode, int visframecount, int framecount, wsurf_vbo_leaf_t *leaf) { if (basenode->contents == CONTENTS_SOLID) return; - if (pvsnodes.find(basenode) == pvsnodes.end()) + if (basenode->visframe != visframecount) return; if (basenode->contents < 0) @@ -478,13 +481,13 @@ void R_RecursiveLinkTextureChain(mbasenode_t *basenode, const std::setchildren[0], pvsnodes, marksurfs, leaf); + R_RecursiveLinkTextureChain(node->children[0], visframecount, framecount, leaf); for (int i = 0; i < node->numsurfaces; ++i) { auto surf = R_GetWorldSurfaceByIndex(node->firstsurface + i); - if (marksurfs.find(surf) == marksurfs.end()) + if (surf->visframe != framecount) { continue; } @@ -504,7 +507,7 @@ void R_RecursiveLinkTextureChain(mbasenode_t *basenode, const std::settexinfo->texture->texturechain = surf; } - R_RecursiveLinkTextureChain(node->children[1], pvsnodes, marksurfs, leaf); + R_RecursiveLinkTextureChain(node->children[1], visframecount, framecount, leaf); } void R_BrushModelLinkTextureChain(model_t *mod, wsurf_vbo_leaf_t *leaf) @@ -986,82 +989,88 @@ void R_GenerateBufferStorage(model_t *mod, wsurf_vbo_t *modvbo) modvbo->vLeaves.resize(vPossibleLeafs.size()); + int visframecount = 0; + int framecount = 0; + for (auto &leaf : vPossibleLeafs) { - std::set pvsnodes; - std::set marksurfs; - int leafindex = leaf - mod->leafs; - - R_MarkPVSForLeaf(leaf, pvsnodes); + + framecount++; + visframecount++; + + R_MarkPVSForLeaf(leaf, visframecount); auto vboleaf = new wsurf_vbo_leaf_t; - R_RecursiveMarkSurfaces(mod->nodes, pvsnodes, marksurfs); + R_RecursiveMarkSurfaces(mod->nodes, visframecount, framecount); - R_RecursiveLinkTextureChain(mod->nodes, pvsnodes, marksurfs, vboleaf); + R_RecursiveLinkTextureChain(mod->nodes, visframecount, framecount, vboleaf); R_GenerateWaterStorages(mod, vboleaf); R_GenerateTexChain(mod, vboleaf, vIndicesBuffer); - vboleaf->hEBO = GL_GenBuffer(); - GL_UploadDataToEBOStaticDraw(vboleaf->hEBO, sizeof(GLuint) * vIndicesBuffer.size(), vIndicesBuffer.data()); - - vboleaf->hVAO = GL_GenVAO(); - GL_BindStatesForVAO(vboleaf->hVAO, r_wsurf.hSceneVBO, vboleaf->hEBO, - []() { - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_POSITION); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMAL); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_S_TANGENT); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_T_TANGENT); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXCOORD); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_LIGHTMAP_TEXCOORD); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_REPLACETEXTURE_TEXCOORD); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_DETAILTEXTURE_TEXCOORD); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMALTEXTURE_TEXCOORD); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_PARALLAXTEXTURE_TEXCOORD); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_SPECULARTEXTURE_TEXCOORD); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXINDEX); - glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_STYLES); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_POSITION, 4, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, pos)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_NORMAL, 4, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, normal)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_S_TANGENT, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, s_tangent)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_T_TANGENT, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, t_tangent)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_TEXCOORD, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, texcoord)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_LIGHTMAP_TEXCOORD, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, lightmaptexcoord)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_REPLACETEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, replacetexcoord)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_DETAILTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, detailtexcoord)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_NORMALTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, normaltexcoord)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_PARALLAXTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, parallaxtexcoord)); - glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_SPECULARTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, speculartexcoord)); - glVertexAttribIPointer(VERTEX_ATTRIBUTE_INDEX_TEXINDEX, 1, GL_INT, sizeof(brushvertex_t), OFFSET(brushvertex_t, texindex)); - glVertexAttribIPointer(VERTEX_ATTRIBUTE_INDEX_STYLES, 4, GL_UNSIGNED_BYTE, sizeof(brushvertex_t), OFFSET(brushvertex_t, styles)); - }, - []() { - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_POSITION); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMAL); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_S_TANGENT); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_T_TANGENT); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXCOORD); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_LIGHTMAP_TEXCOORD); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_REPLACETEXTURE_TEXCOORD); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_DETAILTEXTURE_TEXCOORD); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMALTEXTURE_TEXCOORD); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_PARALLAXTEXTURE_TEXCOORD); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_SPECULARTEXTURE_TEXCOORD); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXINDEX); - glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_STYLES); - }); - - vIndicesBuffer.clear(); - - R_SortTextureChain(vboleaf, WSURF_TEXCHAIN_STATIC); - R_SortTextureChain(vboleaf, WSURF_TEXCHAIN_ANIM); - - R_GenerateDrawBatch(vboleaf, WSURF_TEXCHAIN_STATIC, WSURF_DRAWBATCH_STATIC); - R_GenerateDrawBatch(vboleaf, WSURF_TEXCHAIN_STATIC, WSURF_DRAWBATCH_SOLID); - R_GenerateDrawBatch(vboleaf, WSURF_TEXCHAIN_ANIM, WSURF_DRAWBATCH_SOLID); + if (vIndicesBuffer.size() > 0) + { + vboleaf->hEBO = GL_GenBuffer(); + GL_UploadDataToEBOStaticDraw(vboleaf->hEBO, sizeof(GLuint) * vIndicesBuffer.size(), vIndicesBuffer.data()); + + vboleaf->hVAO = GL_GenVAO(); + GL_BindStatesForVAO(vboleaf->hVAO, r_wsurf.hSceneVBO, vboleaf->hEBO, + []() { + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_POSITION); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMAL); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_S_TANGENT); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_T_TANGENT); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXCOORD); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_LIGHTMAP_TEXCOORD); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_REPLACETEXTURE_TEXCOORD); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_DETAILTEXTURE_TEXCOORD); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMALTEXTURE_TEXCOORD); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_PARALLAXTEXTURE_TEXCOORD); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_SPECULARTEXTURE_TEXCOORD); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXINDEX); + glEnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_STYLES); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_POSITION, 4, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, pos)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_NORMAL, 4, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, normal)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_S_TANGENT, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, s_tangent)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_T_TANGENT, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, t_tangent)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_TEXCOORD, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, texcoord)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_LIGHTMAP_TEXCOORD, 3, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, lightmaptexcoord)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_REPLACETEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, replacetexcoord)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_DETAILTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, detailtexcoord)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_NORMALTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, normaltexcoord)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_PARALLAXTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, parallaxtexcoord)); + glVertexAttribPointer(VERTEX_ATTRIBUTE_INDEX_SPECULARTEXTURE_TEXCOORD, 2, GL_FLOAT, false, sizeof(brushvertex_t), OFFSET(brushvertex_t, speculartexcoord)); + glVertexAttribIPointer(VERTEX_ATTRIBUTE_INDEX_TEXINDEX, 1, GL_INT, sizeof(brushvertex_t), OFFSET(brushvertex_t, texindex)); + glVertexAttribIPointer(VERTEX_ATTRIBUTE_INDEX_STYLES, 4, GL_UNSIGNED_BYTE, sizeof(brushvertex_t), OFFSET(brushvertex_t, styles)); + }, + []() { + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_POSITION); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMAL); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_S_TANGENT); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_T_TANGENT); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXCOORD); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_LIGHTMAP_TEXCOORD); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_REPLACETEXTURE_TEXCOORD); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_DETAILTEXTURE_TEXCOORD); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_NORMALTEXTURE_TEXCOORD); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_PARALLAXTEXTURE_TEXCOORD); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_SPECULARTEXTURE_TEXCOORD); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_TEXINDEX); + glDisableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX_STYLES); + }); + + vIndicesBuffer.clear(); + + R_SortTextureChain(vboleaf, WSURF_TEXCHAIN_STATIC); + R_SortTextureChain(vboleaf, WSURF_TEXCHAIN_ANIM); + + R_GenerateDrawBatch(vboleaf, WSURF_TEXCHAIN_STATIC, WSURF_DRAWBATCH_STATIC); + R_GenerateDrawBatch(vboleaf, WSURF_TEXCHAIN_STATIC, WSURF_DRAWBATCH_SOLID); + R_GenerateDrawBatch(vboleaf, WSURF_TEXCHAIN_ANIM, WSURF_DRAWBATCH_SOLID); + } modvbo->vLeaves[leafindex] = vboleaf; } @@ -2326,25 +2335,28 @@ void R_DrawWSurfVBO(wsurf_vbo_t *modvbo, cl_entity_t *ent) { vboleaf = modvbo->vLeaves[leafindex]; - R_DrawWSurfVBOBegin(vboleaf); - - if (R_ShouldDrawZPrePass()) + if (vboleaf->hVAO) { - glColorMask(0, 0, 0, 0); + R_DrawWSurfVBOBegin(vboleaf); + + if (R_ShouldDrawZPrePass()) + { + glColorMask(0, 0, 0, 0); - R_DrawWSurfVBOSolid(vboleaf); + R_DrawWSurfVBOSolid(vboleaf); - glColorMask(1, 1, 1, 1); + glColorMask(1, 1, 1, 1); - glDepthFunc(GL_EQUAL); + glDepthFunc(GL_EQUAL); - bUseZPrePass = true; - } + bUseZPrePass = true; + } - R_DrawWSurfVBOStatic(vboleaf, bUseZPrePass); - R_DrawWSurfVBOAnim(vboleaf, bUseZPrePass); + R_DrawWSurfVBOStatic(vboleaf, bUseZPrePass); + R_DrawWSurfVBOAnim(vboleaf, bUseZPrePass); - R_DrawWSurfVBOEnd(); + R_DrawWSurfVBOEnd(); + } } else { @@ -2357,12 +2369,15 @@ void R_DrawWSurfVBO(wsurf_vbo_t *modvbo, cl_entity_t *ent) { vboleaf = modvbo->vLeaves[0]; - R_DrawWSurfVBOBegin(vboleaf); + if (vboleaf->hVAO) + { + R_DrawWSurfVBOBegin(vboleaf); - R_DrawWSurfVBOStatic(vboleaf, bUseZPrePass); - R_DrawWSurfVBOAnim(vboleaf, bUseZPrePass); + R_DrawWSurfVBOStatic(vboleaf, bUseZPrePass); + R_DrawWSurfVBOAnim(vboleaf, bUseZPrePass); - R_DrawWSurfVBOEnd(); + R_DrawWSurfVBOEnd(); + } } else {