From 435c11c688da5efdf9ee8f870256cfdf3c0a1376 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Sat, 9 Dec 2023 16:45:45 +0700 Subject: [PATCH 01/10] Add dxDrawModel3D function --- Client/game_sa/CGameSA.cpp | 2 + Client/game_sa/CGameSA.h | 4 ++ Client/game_sa/CModelInfoSA.cpp | 5 ++- Client/game_sa/CRendererSA.cpp | 44 +++++++++++++++++++ Client/game_sa/CRendererSA.h | 23 ++++++++++ Client/game_sa/gamesa_renderware.h | 4 ++ Client/game_sa/gamesa_renderware.hpp | 2 + Client/mods/deathmatch/StdInc.h | 1 + Client/mods/deathmatch/logic/CClientGame.cpp | 12 +++++ Client/mods/deathmatch/logic/CClientGame.h | 5 +++ .../mods/deathmatch/logic/CModelRenderer.cpp | 44 +++++++++++++++++++ Client/mods/deathmatch/logic/CModelRenderer.h | 32 ++++++++++++++ .../logic/lua/CLuaFunctionParseHelpers.cpp | 6 +++ .../logic/lua/CLuaFunctionParseHelpers.h | 1 + .../logic/luadefs/CLuaDrawingDefs.cpp | 22 ++++++++++ .../logic/luadefs/CLuaDrawingDefs.h | 2 + Client/multiplayer_sa/CMultiplayerSA.h | 1 + .../CMultiplayerSA_Rendering.cpp | 37 ++++++++++++++++ Client/sdk/game/CGame.h | 2 + Client/sdk/game/CModelInfo.h | 1 + Client/sdk/game/CRenderer.h | 23 ++++++++++ Client/sdk/multiplayer/CMultiplayer.h | 2 + 22 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 Client/game_sa/CRendererSA.cpp create mode 100644 Client/game_sa/CRendererSA.h create mode 100644 Client/mods/deathmatch/logic/CModelRenderer.cpp create mode 100644 Client/mods/deathmatch/logic/CModelRenderer.h create mode 100644 Client/sdk/game/CRenderer.h diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 43ea348489..2ff0328a3a 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -142,6 +142,8 @@ CGameSA::CGameSA() m_pCoverManager = new CCoverManagerSA(); m_pPlantManager = new CPlantManagerSA(); + m_pRenderer = std::make_unique(); + // Normal weapon types (WEAPONSKILL_STD) for (int i = 0; i < NUM_WeaponInfosStdSkill; i++) { diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index 61c68de445..b3b73b17f0 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -17,6 +17,7 @@ #include "CStreamingSA.h" #include "CCoverManagerSA.h" #include "CPlantManagerSA.h" +#include "CRendererSA.h" class CAnimBlendClumpDataSAInterface; class CObjectGroupPhysicalPropertiesSA; @@ -171,6 +172,7 @@ class CGameSA : public CGame CIplStore* GetIplStore() { return m_pIplStore; }; CCoverManagerSA* GetCoverManager() const noexcept { return m_pCoverManager; }; CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; }; + CRenderer* GetRenderer() const override { return m_pRenderer.get(); } CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD); CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false); @@ -340,6 +342,8 @@ class CGameSA : public CGame CCoverManagerSA* m_pCoverManager; CPlantManagerSA* m_pPlantManager; + std::unique_ptr m_pRenderer; + CPad* m_pPad; CAERadioTrackManager* m_pCAERadioTrackManager; CAudioEngine* m_pAudioEngine; diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index da81fb4f23..34714f946c 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -2022,7 +2022,10 @@ void CModelInfoSA::RestoreAllObjectsPropertiesGroups() eModelInfoType CModelInfoSA::GetModelType() { - return ((eModelInfoType(*)())m_pInterface->VFTBL->GetModelType)(); + if (auto pInterface = GetInterface()) + return ((eModelInfoType(*)())pInterface->VFTBL->GetModelType)(); + + return eModelInfoType::UNKNOWN; } bool CModelInfoSA::IsTowableBy(CModelInfo* towingModel) diff --git a/Client/game_sa/CRendererSA.cpp b/Client/game_sa/CRendererSA.cpp new file mode 100644 index 0000000000..d00a0ef4bb --- /dev/null +++ b/Client/game_sa/CRendererSA.cpp @@ -0,0 +1,44 @@ +#include "StdInc.h" +#include "CRendererSA.h" +#include "CModelInfoSA.h" +#include "CMatrix.h" +#include "gamesa_renderware.h" + +CRendererSA::CRendererSA() +{ +} + +CRendererSA::~CRendererSA() +{ +} + +void CRendererSA::RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix) +{ + CBaseModelInfoSAInterface* pModelInfoSAInterface = pModelInfo->GetInterface(); + if (!pModelInfoSAInterface) + return; + + RwObject* pRwObject = pModelInfoSAInterface->pRwObject; + if (!pRwObject) + return; + + RwFrame* pFrame = RpGetFrame(pRwObject); + + static RwMatrix rwMatrix; + rwMatrix.right = (RwV3d&)matrix.vRight; + rwMatrix.up = (RwV3d&)matrix.vFront; + rwMatrix.at = (RwV3d&)matrix.vUp; + rwMatrix.pos = (RwV3d&)matrix.vPos; + RwFrameTransform(pFrame, &rwMatrix, rwCOMBINEREPLACE); + + if (pRwObject->type == RP_TYPE_ATOMIC) + { + RpAtomic* pRpAtomic = reinterpret_cast(pRwObject); + pRpAtomic->renderCallback(reinterpret_cast(pRwObject)); + } + else + { + RpClump* pClump = reinterpret_cast(pRwObject); + RpClumpRender(pClump); + } +} diff --git a/Client/game_sa/CRendererSA.h b/Client/game_sa/CRendererSA.h new file mode 100644 index 0000000000..f11da7f1f8 --- /dev/null +++ b/Client/game_sa/CRendererSA.h @@ -0,0 +1,23 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CRendererSA.h + * PURPOSE: Header file for renderer class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include + +class CRendererSA : public CRenderer +{ +public: + CRendererSA(); + ~CRendererSA(); + + void RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix) override; +}; diff --git a/Client/game_sa/gamesa_renderware.h b/Client/game_sa/gamesa_renderware.h index e2f2d9a472..594c203b59 100644 --- a/Client/game_sa/gamesa_renderware.h +++ b/Client/game_sa/gamesa_renderware.h @@ -38,6 +38,7 @@ typedef RwFrame*(__cdecl* RwFrameAddChild_t)(RwFrame* parent, RwFrame* child); typedef RwFrame*(__cdecl* RwFrameRemoveChild_t)(RwFrame* child); typedef RwFrame*(__cdecl* RwFrameForAllObjects_t)(RwFrame* frame, void* callback, void* data); typedef RwFrame*(__cdecl* RwFrameTranslate_t)(RwFrame* frame, const RwV3d* v, RwTransformOrder order); +typedef RwFrame*(__cdecl* RwFrameTransform_t)(RwFrame* frame, const RwMatrix* m, RwOpCombineType combine); typedef RwFrame*(__cdecl* RwFrameScale_t)(RwFrame* frame, const RwV3d* v, RwTransformOrder order); typedef RwFrame*(__cdecl* RwFrameUpdateObjects_t)(RwFrame*); typedef RwFrame*(__cdecl* RwFrameCreate_t)(); @@ -69,6 +70,7 @@ typedef RwTexture*(__cdecl* RwTexDictionaryAddTexture_t)(RwTexDictionary* dict, typedef RwTexDictionary*(__cdecl* RwTexDictionaryGetCurrent_t)(); typedef RwTexture*(__cdecl* RwTexDictionaryFindNamedTexture_t)(RwTexDictionary* dict, const char* name); typedef void(__cdecl* RpPrtStdGlobalDataSetStreamEmbedded_t)(void* value); +typedef RpClump*(__cdecl* RpClumpRender_t)(RpClump* clump); typedef RpWorld*(__cdecl* RpWorldAddAtomic_t)(RpWorld* world, RpAtomic* atomic); typedef RpWorld*(__cdecl* RpWorldAddClump_t)(RpWorld* world, RpClump* clump); typedef RpWorld*(__cdecl* RpWorldAddLight_t)(RpWorld* world, RpLight* light); @@ -125,6 +127,7 @@ RWFUNC(RwStreamSkip_t RwStreamSkip, (RwStreamSkip_t)0xDEAD) RWFUNC(RpClumpDestroy_t RpClumpDestroy, (RpClumpDestroy_t)0xDEAD) RWFUNC(RpClumpGetNumAtomics_t RpClumpGetNumAtomics, (RpClumpGetNumAtomics_t)0xDEAD) RWFUNC(RwFrameTranslate_t RwFrameTranslate, (RwFrameTranslate_t)0xDEAD) +RWFUNC(RwFrameTransform_t RwFrameTransform, (RwFrameTransform_t)0xDEAD) RWFUNC(RpClumpForAllAtomics_t RpClumpForAllAtomics, (RpClumpForAllAtomics_t)0xDEAD) RWFUNC(RwFrameAddChild_t RwFrameAddChild, (RwFrameAddChild_t)0xDEAD) RWFUNC(RpClumpAddAtomic_t RpClumpAddAtomic, (RpClumpAddAtomic_t)0xDEAD) @@ -138,6 +141,7 @@ RWFUNC(RwTexDictionaryAddTexture_t RwTexDictionaryAddTexture, (RwTexDictionaryAd RWFUNC(RwTexDictionaryStreamWrite_t RwTexDictionaryStreamWrite, (RwTexDictionaryStreamWrite_t)0xDEAD) RWFUNC(rwD3D9NativeTextureRead_t rwD3D9NativeTextureRead, (rwD3D9NativeTextureRead_t)0xDEAD) RWFUNC(RpPrtStdGlobalDataSetStreamEmbedded_t RpPrtStdGlobalDataSetStreamEmbedded, (RpPrtStdGlobalDataSetStreamEmbedded_t)0xDEAD) +RWFUNC(RpClumpRender_t RpClumpRender, (RpClumpRender_t)0xDEAD) RWFUNC(RpClumpRemoveAtomic_t RpClumpRemoveAtomic, (RpClumpRemoveAtomic_t)0xDEAD) RWFUNC(RpAtomicClone_t RpAtomicClone, (RpAtomicClone_t)0xDEAD) RWFUNC(RwTexDictionaryFindNamedTexture_t RwTexDictionaryFindNamedTexture, (RwTexDictionaryFindNamedTexture_t)0xDEAD) diff --git a/Client/game_sa/gamesa_renderware.hpp b/Client/game_sa/gamesa_renderware.hpp index 804040c802..a638cfede0 100644 --- a/Client/game_sa/gamesa_renderware.hpp +++ b/Client/game_sa/gamesa_renderware.hpp @@ -20,6 +20,7 @@ void InitRwFunctions() RwStreamSkip = (RwStreamSkip_t)0x007ECD00; RpClumpDestroy = (RpClumpDestroy_t)0x0074A310; RpClumpGetNumAtomics = (RpClumpGetNumAtomics_t)0x007498E0; + RwFrameTransform = (RwFrameTransform_t)0x007F0F70; RwFrameTranslate = (RwFrameTranslate_t)0x007F0E30; RpClumpForAllAtomics = (RpClumpForAllAtomics_t)0x00749B70; RwFrameAddChild = (RwFrameAddChild_t)0x007F0B00; @@ -34,6 +35,7 @@ void InitRwFunctions() RwTexDictionaryStreamWrite = (RwTexDictionaryStreamWrite_t)0x008049F0; rwD3D9NativeTextureRead = (rwD3D9NativeTextureRead_t)0x004CD820; RpPrtStdGlobalDataSetStreamEmbedded = (RpPrtStdGlobalDataSetStreamEmbedded_t)0x0041B350; + RpClumpRender = (RpClumpRender_t)0x00749B20; RpClumpRemoveAtomic = (RpClumpRemoveAtomic_t)0x0074A4C0; RpAtomicClone = (RpAtomicClone_t)0x00749E60; RwTexDictionaryFindNamedTexture = (RwTexDictionaryFindNamedTexture_t)0x007F39F0; diff --git a/Client/mods/deathmatch/StdInc.h b/Client/mods/deathmatch/StdInc.h index 68b18a6ab5..465478454f 100644 --- a/Client/mods/deathmatch/StdInc.h +++ b/Client/mods/deathmatch/StdInc.h @@ -105,6 +105,7 @@ #include #include #include +#include #include #include #include diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 34946f7141..522cf7d1a4 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -249,6 +249,9 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) // Singular file download manager m_pSingularFileDownloadManager = new CSingularFileDownloadManager(); + // 3D model renderer + m_pModelRenderer = std::make_unique(); + // Register the message and the net packet handler g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire); g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire); @@ -265,6 +268,7 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo()) g_pMultiplayer->SetRender3DStuffHandler(CClientGame::StaticRender3DStuffHandler); g_pMultiplayer->SetPreRenderSkyHandler(CClientGame::StaticPreRenderSkyHandler); g_pMultiplayer->SetRenderHeliLightHandler(CClientGame::StaticRenderHeliLightHandler); + g_pMultiplayer->SetRenderEverythingBarRoadsHandler(CClientGame::StaticRenderEverythingBarRoadsHandler); g_pMultiplayer->SetChokingHandler(CClientGame::StaticChokingHandler); g_pMultiplayer->SetPreWorldProcessHandler(CClientGame::StaticPreWorldProcessHandler); g_pMultiplayer->SetPostWorldProcessHandler(CClientGame::StaticPostWorldProcessHandler); @@ -470,6 +474,7 @@ CClientGame::~CClientGame() g_pMultiplayer->SetRender3DStuffHandler(NULL); g_pMultiplayer->SetPreRenderSkyHandler(NULL); g_pMultiplayer->SetRenderHeliLightHandler(nullptr); + g_pMultiplayer->SetRenderEverythingBarRoadsHandler(nullptr); g_pMultiplayer->SetChokingHandler(NULL); g_pMultiplayer->SetPreWorldProcessHandler(NULL); g_pMultiplayer->SetPostWorldProcessHandler(NULL); @@ -3559,6 +3564,11 @@ void CClientGame::StaticRenderHeliLightHandler() g_pClientGame->GetManager()->GetPointLightsManager()->RenderHeliLightHandler(); } +void CClientGame::StaticRenderEverythingBarRoadsHandler() +{ + g_pClientGame->GetModelRenderer()->Render(); +} + bool CClientGame::StaticChokingHandler(unsigned char ucWeaponType) { return g_pClientGame->ChokingHandler(ucWeaponType); @@ -3861,6 +3871,8 @@ void CClientGame::PostWorldProcessPedsAfterPreRenderHandler() { CLuaArguments Arguments; m_pRootEntity->CallEvent("onClientPedsProcessed", Arguments, false); + + g_pClientGame->GetModelRenderer()->Update(); } void CClientGame::IdleHandler() diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index 96d82c37a7..080d5fc61a 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -309,6 +309,8 @@ class CClientGame CRemoteCalls* GetRemoteCalls() { return m_pRemoteCalls; } CResourceFileDownloadManager* GetResourceFileDownloadManager() { return m_pResourceFileDownloadManager; } + CModelRenderer* GetModelRenderer() const noexcept { return m_pModelRenderer.get(); } + SharedUtil::CAsyncTaskScheduler* GetAsyncTaskScheduler() { return m_pAsyncTaskScheduler; } // Status toggles @@ -506,6 +508,7 @@ class CClientGame static void StaticRender3DStuffHandler(); static void StaticPreRenderSkyHandler(); static void StaticRenderHeliLightHandler(); + static void StaticRenderEverythingBarRoadsHandler(); static bool StaticChokingHandler(unsigned char ucWeaponType); static void StaticPreWorldProcessHandler(); static void StaticPostWorldProcessHandler(); @@ -699,6 +702,8 @@ class CClientGame CRemoteCalls* m_pRemoteCalls; CResourceFileDownloadManager* m_pResourceFileDownloadManager; + std::unique_ptr m_pModelRenderer; + // Revised facilities CServer m_Server; diff --git a/Client/mods/deathmatch/logic/CModelRenderer.cpp b/Client/mods/deathmatch/logic/CModelRenderer.cpp new file mode 100644 index 0000000000..f333c0ba60 --- /dev/null +++ b/Client/mods/deathmatch/logic/CModelRenderer.cpp @@ -0,0 +1,44 @@ +#include "StdInc.h" +#include "game\CRenderer.h" + +SModelToRender& CModelRenderer::EnqueueModel(CModelInfo* pModelInfo) +{ + static SModelToRender DEFAULT_MODEL_TO_RENDER{}; + + if (!pModelInfo || g_pCore->IsWindowMinimized()) + return DEFAULT_MODEL_TO_RENDER; + + SModelToRender& entry = m_Queue.emplace_back(); + entry.pModelInfo = pModelInfo; + return entry; +} + +void CModelRenderer::Update() +{ + for (auto& modelDesc : m_Queue) + { + if (modelDesc.bLoaded = modelDesc.pModelInfo->IsLoaded(); !modelDesc.bLoaded) + { + if (modelDesc.scheme != EModelLoadingScheme::Loaded) + modelDesc.pModelInfo->Request(modelDesc.scheme == EModelLoadingScheme::Blocking ? + EModelRequestType::BLOCKING : EModelRequestType::NON_BLOCKING, "Lua::DxDrawModel3D"); + + if (modelDesc.scheme == EModelLoadingScheme::Blocking) + modelDesc.bLoaded = modelDesc.pModelInfo->IsLoaded(); + } + } +} + +void CModelRenderer::Render() +{ + CRenderer* pRenderer = g_pGame->GetRenderer(); + assert(pRenderer); + + for (const auto& modelDesc : m_Queue) + { + if (modelDesc.bLoaded) + pRenderer->RenderModel(modelDesc.pModelInfo, modelDesc.matrix); + } + + m_Queue.clear(); +} diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h new file mode 100644 index 0000000000..6edf0f0b0c --- /dev/null +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -0,0 +1,32 @@ +#pragma once + +enum class EModelLoadingScheme : uint8_t +{ + Loaded = 0, + Async, + Blocking +}; + +struct SModelToRender final +{ + EModelLoadingScheme scheme{EModelLoadingScheme::Loaded}; + CMatrix matrix; + + // Invariants +private: + friend class CModelRenderer; + CModelInfo* pModelInfo{}; + bool bLoaded{}; +}; + +class CModelRenderer final +{ +public: + SModelToRender& EnqueueModel(CModelInfo* pModelInfo); + + void Update(); + + void Render(); + + std::vector m_Queue; +}; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index e037494a1b..e5fe478a74 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -593,6 +593,12 @@ ADD_ENUM(eGrainMultiplierType::OVERLAY, "overlay") ADD_ENUM(eGrainMultiplierType::ALL, "all") IMPLEMENT_ENUM_CLASS_END("grain-multiplier-type") +IMPLEMENT_ENUM_CLASS_BEGIN(EModelLoadingScheme) +ADD_ENUM(EModelLoadingScheme::Loaded, "loaded") +ADD_ENUM(EModelLoadingScheme::Async, "async") +ADD_ENUM(EModelLoadingScheme::Blocking, "blocking") +IMPLEMENT_ENUM_CLASS_END("model-loading-scheme") + IMPLEMENT_ENUM_CLASS_BEGIN(eResizableVehicleWheelGroup) ADD_ENUM(eResizableVehicleWheelGroup::FRONT_AXLE, "front_axle") ADD_ENUM(eResizableVehicleWheelGroup::REAR_AXLE, "rear_axle") diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 3c8af2144c..158e9785ea 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -83,6 +83,7 @@ DECLARE_ENUM_CLASS(eModelIdeFlag); DECLARE_ENUM_CLASS(_D3DFORMAT); DECLARE_ENUM_CLASS(eRenderStage); DECLARE_ENUM(ePools); +DECLARE_ENUM_CLASS(EModelLoadingScheme); class CRemoteCall; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index e30b7f3ba2..f76a53e117 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -36,6 +36,7 @@ void CLuaDrawingDefs::LoadFunctions() {"dxDrawMaterialPrimitive", DxDrawMaterialPrimitive}, {"dxDrawMaterialPrimitive3D", DxDrawMaterialPrimitive3D}, {"dxDrawWiredSphere", ArgumentParser}, + {"dxDrawModel3D", ArgumentParser}, {"dxGetTextWidth", DxGetTextWidth}, {"dxGetTextSize", ArgumentParser}, {"dxGetFontHeight", DxGetFontHeight}, @@ -2121,3 +2122,24 @@ bool CLuaDrawingDefs::DxDrawWiredSphere(lua_State* const luaVM, const CVector po g_pCore->GetGraphics()->DrawWiredSphere(position, radius, color.value(), lineWidth.value_or(1), iterations.value_or(1)); return true; } + +bool CLuaDrawingDefs::DxDrawModel3D(uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme) +{ + CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelID); + if (!pModelInfo) + throw std::invalid_argument("Invalid model ID"); + + if (auto modelType = pModelInfo->GetModelType(); + modelType == eModelInfoType::UNKNOWN || modelType == eModelInfoType::VEHICLE || modelType == eModelInfoType::PED) + { + throw std::invalid_argument("Invalid model type"); + } + + ConvertDegreesToRadians(rotation); + + SModelToRender& modelDesc = g_pClientGame->GetModelRenderer()->EnqueueModel(pModelInfo); + modelDesc.matrix = {position, rotation, scale.value_or(CVector(1.0f, 1.0f, 1.0f))}; + modelDesc.scheme = loadingScheme.value_or(EModelLoadingScheme::Async); + + return true; +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h index 0bda34f5e9..a1069508fc 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h @@ -82,6 +82,8 @@ class CLuaDrawingDefs : public CLuaDefs static bool DxDrawWiredSphere(lua_State* const luaVM, const CVector position, const float radius, const std::optional color, const std::optional lineWidth, const std::optional iterations); + static bool DxDrawModel3D(uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme); + private: static void AddDxMaterialClass(lua_State* luaVM); static void AddDxTextureClass(lua_State* luaVM); diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index fd81a18828..1820b0d4c7 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -214,6 +214,7 @@ class CMultiplayerSA : public CMultiplayer void SetRender3DStuffHandler(Render3DStuffHandler* pHandler); void SetPreRenderSkyHandler(PreRenderSkyHandler* pHandler); void SetRenderHeliLightHandler(RenderHeliLightHandler* pHandler); + void SetRenderEverythingBarRoadsHandler(RenderEverythingBarRoadsHandler* pHandler) override; void Reset(); diff --git a/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp b/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp index 03a27688d2..b346f25874 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_Rendering.cpp @@ -13,6 +13,7 @@ extern CCoreInterface* g_pCore; GameEntityRenderHandler* pGameEntityRenderHandler = nullptr; PreRenderSkyHandler* pPreRenderSkyHandlerHandler = nullptr; RenderHeliLightHandler* pRenderHeliLightHandler = nullptr; +RenderEverythingBarRoadsHandler* pRenderEverythingBarRoadsHandler = nullptr; #define VAR_CCullZones_NumMirrorAttributeZones 0x0C87AC4 // int #define VAR_CMirrors_d3dRestored 0x0C7C729 // uchar @@ -581,6 +582,17 @@ void CMultiplayerSA::SetRenderHeliLightHandler(RenderHeliLightHandler* pHandler) pRenderHeliLightHandler = pHandler; } +////////////////////////////////////////////////////////////////////////////////////////// +// +// CMultiplayerSA::SetRenderEverythingBarRoadsHandler +// +// +////////////////////////////////////////////////////////////////////////////////////////// +void CMultiplayerSA::SetRenderEverythingBarRoadsHandler(RenderEverythingBarRoadsHandler* pHandler) +{ + pRenderEverythingBarRoadsHandler = pHandler; +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::SetIsMinimizedAndNotConnected @@ -703,6 +715,30 @@ void _declspec(naked) HOOK_CVisibilityPlugins_RenderPedCB() } } +// Hook info +#define HOOKPOS_CRenderer_EverythingBarRoads 0x553C78 +#define HOOKSIZE_CRenderer_EverythingBarRoads 5 +DWORD RETURN_CRenderer_EverythingBarRoads = 0x553C7D; +DWORD DO_CRenderer_EverythingBarRoads = 0x7EE180; +void _declspec(naked) HOOK_CRenderer_EverythingBarRoads() +{ + _asm + { + pushad + } + + if (pRenderEverythingBarRoadsHandler) + pRenderEverythingBarRoadsHandler(); + + _asm + { + popad + call DO_CRenderer_EverythingBarRoads + jmp RETURN_CRenderer_EverythingBarRoads + + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CMultiplayerSA::InitHooks_Rendering @@ -726,4 +762,5 @@ void CMultiplayerSA::InitHooks_Rendering() EZHookInstallChecked(CClouds_RenderSkyPolys); EZHookInstallChecked(RwCameraSetNearClipPlane); EZHookInstall(RenderEffects_HeliLight); + EZHookInstall(CRenderer_EverythingBarRoads); } diff --git a/Client/sdk/game/CGame.h b/Client/sdk/game/CGame.h index 77c2be24d9..93765abd25 100644 --- a/Client/sdk/game/CGame.h +++ b/Client/sdk/game/CGame.h @@ -67,6 +67,7 @@ class CWeaponStatManager; class CWeather; class CWorld; class CIplStore; +class CRenderer; enum eEntityType; enum ePedPieceTypes; @@ -147,6 +148,7 @@ class __declspec(novtable) CGame virtual CWeaponStatManager* GetWeaponStatManager() = 0; virtual CPointLights* GetPointLights() = 0; virtual CColStore* GetCollisionStore() = 0; + virtual CRenderer* GetRenderer() const = 0; virtual CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD) = 0; virtual CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false) = 0; diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index 440f079be6..9bc5702618 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -60,6 +60,7 @@ enum class eModelInfoType : unsigned char VEHICLE = 6, PED = 7, LOD_ATOMIC = 8, + UNKNOWN = 9 }; enum eVehicleUpgradePosn diff --git a/Client/sdk/game/CRenderer.h b/Client/sdk/game/CRenderer.h new file mode 100644 index 0000000000..65d6a8bdca --- /dev/null +++ b/Client/sdk/game/CRenderer.h @@ -0,0 +1,23 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/CRenderer.h + * PURPOSE: Renderer interface + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +class CModelInfo; +class CMatrix; + +class CRenderer +{ +public: + virtual ~CRenderer() {} + + virtual void RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix) = 0; +}; diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index 23c6f2ac15..2630b8d9c0 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -103,6 +103,7 @@ typedef void(PostWorldProcessPedsAfterPreRenderHandler)(); typedef void(IdleHandler)(); typedef void(PreFxRenderHandler)(); typedef void(PreHudRenderHandler)(); +typedef void(RenderEverythingBarRoadsHandler)(); typedef CAnimBlendAssociationSAInterface*(AddAnimationHandler)(RpClump* pClump, AssocGroupId animGroup, AnimationId animID); typedef CAnimBlendAssociationSAInterface*(AddAnimationAndSyncHandler)(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith, AssocGroupId animGroup, AnimationId animID); @@ -331,6 +332,7 @@ class CMultiplayer virtual void SetRender3DStuffHandler(Render3DStuffHandler* pHandler) = 0; virtual void SetPreRenderSkyHandler(PreRenderSkyHandler* pHandler) = 0; virtual void SetRenderHeliLightHandler(RenderHeliLightHandler* pHandler) = 0; + virtual void SetRenderEverythingBarRoadsHandler(RenderEverythingBarRoadsHandler* pHandler) = 0; virtual void Reset() = 0; From 1ab6c5f8e9b9606fc07859307dc12a9ece599a12 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Sat, 9 Dec 2023 17:10:58 +0700 Subject: [PATCH 02/10] Make m_Queue private --- Client/mods/deathmatch/logic/CModelRenderer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h index 6edf0f0b0c..a2d1fa8d5b 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.h +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -28,5 +28,6 @@ class CModelRenderer final void Render(); +private: std::vector m_Queue; }; From 247b37de44d871fd91cc927b7b0e9c0f79a972b2 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Sat, 9 Dec 2023 17:17:43 +0700 Subject: [PATCH 03/10] Add copyrights --- Client/game_sa/CRendererSA.cpp | 11 +++++++++++ Client/game_sa/CRendererSA.h | 2 +- Client/mods/deathmatch/logic/CModelRenderer.cpp | 11 +++++++++++ Client/mods/deathmatch/logic/CModelRenderer.h | 11 +++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Client/game_sa/CRendererSA.cpp b/Client/game_sa/CRendererSA.cpp index d00a0ef4bb..bad607d5ba 100644 --- a/Client/game_sa/CRendererSA.cpp +++ b/Client/game_sa/CRendererSA.cpp @@ -1,3 +1,14 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CRendererSA.cpp + * PURPOSE: Game renderer class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + #include "StdInc.h" #include "CRendererSA.h" #include "CModelInfoSA.h" diff --git a/Client/game_sa/CRendererSA.h b/Client/game_sa/CRendererSA.h index f11da7f1f8..e71a83665e 100644 --- a/Client/game_sa/CRendererSA.h +++ b/Client/game_sa/CRendererSA.h @@ -3,7 +3,7 @@ * PROJECT: Multi Theft Auto v1.0 * LICENSE: See LICENSE in the top level directory * FILE: game_sa/CRendererSA.h - * PURPOSE: Header file for renderer class + * PURPOSE: Game renderer class * * Multi Theft Auto is available from http://www.multitheftauto.com/ * diff --git a/Client/mods/deathmatch/logic/CModelRenderer.cpp b/Client/mods/deathmatch/logic/CModelRenderer.cpp index f333c0ba60..b54580c9ad 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.cpp +++ b/Client/mods/deathmatch/logic/CModelRenderer.cpp @@ -1,3 +1,14 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CModelRenderer.cpp + * PURPOSE: 3D models renderer + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + #include "StdInc.h" #include "game\CRenderer.h" diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h index a2d1fa8d5b..546633d8b4 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.h +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -1,3 +1,14 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: mods/deathmatch/logic/CModelRenderer.h + * PURPOSE: 3D models renderer + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + #pragma once enum class EModelLoadingScheme : uint8_t From 1ef20fc08a23c7bac1f3e5fcd2328c18c0f9fdf4 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Sat, 9 Dec 2023 17:37:37 +0700 Subject: [PATCH 04/10] Better model enqueueing --- .../mods/deathmatch/logic/CModelRenderer.cpp | 11 +++---- Client/mods/deathmatch/logic/CModelRenderer.h | 30 +++++++++++-------- .../logic/luadefs/CLuaDrawingDefs.cpp | 8 ++--- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Client/mods/deathmatch/logic/CModelRenderer.cpp b/Client/mods/deathmatch/logic/CModelRenderer.cpp index b54580c9ad..7da378b287 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.cpp +++ b/Client/mods/deathmatch/logic/CModelRenderer.cpp @@ -12,16 +12,13 @@ #include "StdInc.h" #include "game\CRenderer.h" -SModelToRender& CModelRenderer::EnqueueModel(CModelInfo* pModelInfo) +bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme) { - static SModelToRender DEFAULT_MODEL_TO_RENDER{}; - if (!pModelInfo || g_pCore->IsWindowMinimized()) - return DEFAULT_MODEL_TO_RENDER; + return false; - SModelToRender& entry = m_Queue.emplace_back(); - entry.pModelInfo = pModelInfo; - return entry; + m_Queue.emplace_back(pModelInfo, matrix, scheme); + return true; } void CModelRenderer::Update() diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h index 546633d8b4..de3558ef87 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.h +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -18,27 +18,31 @@ enum class EModelLoadingScheme : uint8_t Blocking }; -struct SModelToRender final -{ - EModelLoadingScheme scheme{EModelLoadingScheme::Loaded}; - CMatrix matrix; - - // Invariants -private: - friend class CModelRenderer; - CModelInfo* pModelInfo{}; - bool bLoaded{}; -}; - class CModelRenderer final { public: - SModelToRender& EnqueueModel(CModelInfo* pModelInfo); + bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme); void Update(); void Render(); private: + struct SModelToRender final + { + CModelInfo* pModelInfo; + CMatrix matrix; + EModelLoadingScheme scheme; + bool bLoaded; + + SModelToRender(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme) : + pModelInfo(pModelInfo), + matrix(matrix), + scheme(scheme), + bLoaded(false) + { + } + }; + std::vector m_Queue; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index f76a53e117..501d8fc78b 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -2137,9 +2137,7 @@ bool CLuaDrawingDefs::DxDrawModel3D(uint32_t modelID, CVector position, CVector ConvertDegreesToRadians(rotation); - SModelToRender& modelDesc = g_pClientGame->GetModelRenderer()->EnqueueModel(pModelInfo); - modelDesc.matrix = {position, rotation, scale.value_or(CVector(1.0f, 1.0f, 1.0f))}; - modelDesc.scheme = loadingScheme.value_or(EModelLoadingScheme::Async); - - return true; + return g_pClientGame->GetModelRenderer()->EnqueueModel(pModelInfo, + CMatrix{position, rotation, scale.value_or(CVector{1.0f, 1.0f, 1.0f})}, + loadingScheme.value_or(EModelLoadingScheme::Async)); } From d4f94f8e0c7dfd6efc40506e6b4166fd68087d2c Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Thu, 15 Aug 2024 11:48:23 +0700 Subject: [PATCH 05/10] Dedicated render path for transparent entities --- Client/game_sa/CVisibilityPluginsSA.cpp | 7 ++++ Client/game_sa/CVisibilityPluginsSA.h | 2 ++ .../mods/deathmatch/logic/CModelRenderer.cpp | 36 ++++++++++++++++--- Client/mods/deathmatch/logic/CModelRenderer.h | 17 +++++---- Client/sdk/game/CVisibilityPlugins.h | 2 ++ 5 files changed, 52 insertions(+), 12 deletions(-) diff --git a/Client/game_sa/CVisibilityPluginsSA.cpp b/Client/game_sa/CVisibilityPluginsSA.cpp index d7cf9849bc..b5fe2d92c6 100644 --- a/Client/game_sa/CVisibilityPluginsSA.cpp +++ b/Client/game_sa/CVisibilityPluginsSA.cpp @@ -12,6 +12,8 @@ #include "StdInc.h" #include "CVisibilityPluginsSA.h" +#define FUNC_CVisibilityPlugins_InsertEntityIntoEntityList 0x733DD0 + void CVisibilityPluginsSA::SetClumpAlpha(RpClump* pClump, int iAlpha) { DWORD dwFunc = FUNC_CVisiblityPlugins_SetClumpAlpha; @@ -51,3 +53,8 @@ int CVisibilityPluginsSA::GetAtomicId(RwObject* pAtomic) } return iResult; } + +bool CVisibilityPluginsSA::InsertEntityIntoEntityList(void* entity, float distance, void* callback) +{ + return ((bool(_cdecl*)(void*, float, void*))FUNC_CVisibilityPlugins_InsertEntityIntoEntityList)(entity, distance, callback); +} diff --git a/Client/game_sa/CVisibilityPluginsSA.h b/Client/game_sa/CVisibilityPluginsSA.h index 57cab620c0..f4a583bcf2 100644 --- a/Client/game_sa/CVisibilityPluginsSA.h +++ b/Client/game_sa/CVisibilityPluginsSA.h @@ -21,4 +21,6 @@ class CVisibilityPluginsSA : public CVisibilityPlugins public: void SetClumpAlpha(RpClump* pClump, int iAlpha); int GetAtomicId(RwObject* pAtomic); + + bool InsertEntityIntoEntityList(void* entity, float distance, void* callback); }; diff --git a/Client/mods/deathmatch/logic/CModelRenderer.cpp b/Client/mods/deathmatch/logic/CModelRenderer.cpp index 7da378b287..8fec128627 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.cpp +++ b/Client/mods/deathmatch/logic/CModelRenderer.cpp @@ -11,6 +11,7 @@ #include "StdInc.h" #include "game\CRenderer.h" +#include "game\CVisibilityPlugins.h" bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme) { @@ -23,10 +24,15 @@ bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, void CModelRenderer::Update() { + CVisibilityPlugins* pVisibilityPlugins = g_pGame->GetVisibilityPlugins(); + assert(pVisibilityPlugins); + for (auto& modelDesc : m_Queue) { - if (modelDesc.bLoaded = modelDesc.pModelInfo->IsLoaded(); !modelDesc.bLoaded) - { + // Make sure that a model is loaded + modelDesc.bLoaded = modelDesc.pModelInfo->IsLoaded(); + if (!modelDesc.bLoaded) + { if (modelDesc.scheme != EModelLoadingScheme::Loaded) modelDesc.pModelInfo->Request(modelDesc.scheme == EModelLoadingScheme::Blocking ? EModelRequestType::BLOCKING : EModelRequestType::NON_BLOCKING, "Lua::DxDrawModel3D"); @@ -34,19 +40,39 @@ void CModelRenderer::Update() if (modelDesc.scheme == EModelLoadingScheme::Blocking) modelDesc.bLoaded = modelDesc.pModelInfo->IsLoaded(); } + + // Insert transparent entities into a sorted list + if (modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) + { + const CVector& vecCameraPosition = *(CVector*)0xB76870; // CRenderer::ms_vecCameraPosition + const float fDistance = (modelDesc.matrix.GetPosition() - vecCameraPosition).Length(); + + pVisibilityPlugins->InsertEntityIntoEntityList(&modelDesc, fDistance, RenderEntity); + } } } void CModelRenderer::Render() { CRenderer* pRenderer = g_pGame->GetRenderer(); - assert(pRenderer); + assert(pRenderer); - for (const auto& modelDesc : m_Queue) + for (auto& modelDesc : m_Queue) { - if (modelDesc.bLoaded) + if (modelDesc.bLoaded && !modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) pRenderer->RenderModel(modelDesc.pModelInfo, modelDesc.matrix); } m_Queue.clear(); } + +void CModelRenderer::RenderEntity(SModelToRender* modelDesc, float distance) +{ + if (!modelDesc->bLoaded) + return; + + CRenderer* pRenderer = g_pGame->GetRenderer(); + assert(pRenderer); + + pRenderer->RenderModel(modelDesc->pModelInfo, modelDesc->matrix); +} diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h index de3558ef87..289f6ec42e 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.h +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -21,13 +21,6 @@ enum class EModelLoadingScheme : uint8_t class CModelRenderer final { public: - bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme); - - void Update(); - - void Render(); - -private: struct SModelToRender final { CModelInfo* pModelInfo; @@ -44,5 +37,15 @@ class CModelRenderer final } }; + bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme); + + void Update(); + + void Render(); + + static void RenderEntity(SModelToRender* entity, float distance); + +private: + std::vector m_Queue; }; diff --git a/Client/sdk/game/CVisibilityPlugins.h b/Client/sdk/game/CVisibilityPlugins.h index 1d8d1b47cc..f2e948f65a 100644 --- a/Client/sdk/game/CVisibilityPlugins.h +++ b/Client/sdk/game/CVisibilityPlugins.h @@ -22,4 +22,6 @@ class CVisibilityPlugins public: virtual void SetClumpAlpha(RpClump* pClump, int iAlpha) = 0; virtual int GetAtomicId(RwObject* pAtomic) = 0; + + virtual bool InsertEntityIntoEntityList(void* entity, float distance, void* callback) = 0; }; From 6437ee479e1beef666f88db82f7f1cdbb4178887 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Thu, 22 Aug 2024 15:52:59 +0700 Subject: [PATCH 06/10] Remove spaces --- Client/game_sa/CGameSA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index 66ae64632a..03622919eb 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -171,7 +171,7 @@ class CGameSA : public CGame CFxManagerSA* GetFxManagerSA() { return m_pFxManager; } CIplStore* GetIplStore() { return m_pIplStore; }; CCoverManagerSA* GetCoverManager() const noexcept { return m_pCoverManager; }; - CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; }; + CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; }; CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; } CRenderer* GetRenderer() const override { return m_pRenderer.get(); } From f398f2ea1786742f8ecac2f22c73dc4e54482c02 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Thu, 22 Aug 2024 21:03:35 +0700 Subject: [PATCH 07/10] Update CLuaDrawingDefs.cpp --- Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index 501d8fc78b..f62147ea68 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -2123,7 +2123,7 @@ bool CLuaDrawingDefs::DxDrawWiredSphere(lua_State* const luaVM, const CVector po return true; } -bool CLuaDrawingDefs::DxDrawModel3D(uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme) +bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme) { CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelID); if (!pModelInfo) From 4ef5a66c61a451460906aa37adcb1ddf21f23277 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Thu, 22 Aug 2024 21:04:29 +0700 Subject: [PATCH 08/10] Update CLuaDrawingDefs.h --- Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h index a1069508fc..5faf04fe65 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h @@ -82,7 +82,7 @@ class CLuaDrawingDefs : public CLuaDefs static bool DxDrawWiredSphere(lua_State* const luaVM, const CVector position, const float radius, const std::optional color, const std::optional lineWidth, const std::optional iterations); - static bool DxDrawModel3D(uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme); + static bool DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme); private: static void AddDxMaterialClass(lua_State* luaVM); From f24c043445c54f43722ca215ae9da1d2e6f51176 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Sun, 25 Aug 2024 11:11:40 +0700 Subject: [PATCH 09/10] Remove loading scheme --- .../mods/deathmatch/logic/CModelRenderer.cpp | 30 ++++++++----------- Client/mods/deathmatch/logic/CModelRenderer.h | 17 ++--------- .../logic/lua/CLuaFunctionParseHelpers.cpp | 6 ---- .../logic/lua/CLuaFunctionParseHelpers.h | 1 - .../logic/luadefs/CLuaDrawingDefs.cpp | 5 ++-- .../logic/luadefs/CLuaDrawingDefs.h | 2 +- 6 files changed, 18 insertions(+), 43 deletions(-) diff --git a/Client/mods/deathmatch/logic/CModelRenderer.cpp b/Client/mods/deathmatch/logic/CModelRenderer.cpp index 8fec128627..2f06c836ec 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.cpp +++ b/Client/mods/deathmatch/logic/CModelRenderer.cpp @@ -13,13 +13,18 @@ #include "game\CRenderer.h" #include "game\CVisibilityPlugins.h" -bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme) +bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix) { - if (!pModelInfo || g_pCore->IsWindowMinimized()) + if (g_pCore->IsWindowMinimized()) return false; - m_Queue.emplace_back(pModelInfo, matrix, scheme); - return true; + if (pModelInfo && pModelInfo->IsLoaded()) + { + m_Queue.emplace_back(pModelInfo, matrix); + return true; + } + + return false; } void CModelRenderer::Update() @@ -29,18 +34,6 @@ void CModelRenderer::Update() for (auto& modelDesc : m_Queue) { - // Make sure that a model is loaded - modelDesc.bLoaded = modelDesc.pModelInfo->IsLoaded(); - if (!modelDesc.bLoaded) - { - if (modelDesc.scheme != EModelLoadingScheme::Loaded) - modelDesc.pModelInfo->Request(modelDesc.scheme == EModelLoadingScheme::Blocking ? - EModelRequestType::BLOCKING : EModelRequestType::NON_BLOCKING, "Lua::DxDrawModel3D"); - - if (modelDesc.scheme == EModelLoadingScheme::Blocking) - modelDesc.bLoaded = modelDesc.pModelInfo->IsLoaded(); - } - // Insert transparent entities into a sorted list if (modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) { @@ -57,9 +50,10 @@ void CModelRenderer::Render() CRenderer* pRenderer = g_pGame->GetRenderer(); assert(pRenderer); + // Draw opaque entities for (auto& modelDesc : m_Queue) { - if (modelDesc.bLoaded && !modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) + if (modelDesc.pModelInfo->IsLoaded() && !modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST)) pRenderer->RenderModel(modelDesc.pModelInfo, modelDesc.matrix); } @@ -68,7 +62,7 @@ void CModelRenderer::Render() void CModelRenderer::RenderEntity(SModelToRender* modelDesc, float distance) { - if (!modelDesc->bLoaded) + if (!modelDesc->pModelInfo->IsLoaded()) return; CRenderer* pRenderer = g_pGame->GetRenderer(); diff --git a/Client/mods/deathmatch/logic/CModelRenderer.h b/Client/mods/deathmatch/logic/CModelRenderer.h index 289f6ec42e..d923db6c7f 100644 --- a/Client/mods/deathmatch/logic/CModelRenderer.h +++ b/Client/mods/deathmatch/logic/CModelRenderer.h @@ -11,13 +11,6 @@ #pragma once -enum class EModelLoadingScheme : uint8_t -{ - Loaded = 0, - Async, - Blocking -}; - class CModelRenderer final { public: @@ -25,19 +18,15 @@ class CModelRenderer final { CModelInfo* pModelInfo; CMatrix matrix; - EModelLoadingScheme scheme; - bool bLoaded; - SModelToRender(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme) : + SModelToRender(CModelInfo* pModelInfo, const CMatrix& matrix) : pModelInfo(pModelInfo), - matrix(matrix), - scheme(scheme), - bLoaded(false) + matrix(matrix) { } }; - bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix, EModelLoadingScheme scheme); + bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix); void Update(); diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index e2a1286c0a..64708dea0c 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -593,12 +593,6 @@ ADD_ENUM(eGrainMultiplierType::OVERLAY, "overlay") ADD_ENUM(eGrainMultiplierType::ALL, "all") IMPLEMENT_ENUM_CLASS_END("grain-multiplier-type") -IMPLEMENT_ENUM_CLASS_BEGIN(EModelLoadingScheme) -ADD_ENUM(EModelLoadingScheme::Loaded, "loaded") -ADD_ENUM(EModelLoadingScheme::Async, "async") -ADD_ENUM(EModelLoadingScheme::Blocking, "blocking") -IMPLEMENT_ENUM_CLASS_END("model-loading-scheme") - IMPLEMENT_ENUM_CLASS_BEGIN(eResizableVehicleWheelGroup) ADD_ENUM(eResizableVehicleWheelGroup::FRONT_AXLE, "front_axle") ADD_ENUM(eResizableVehicleWheelGroup::REAR_AXLE, "rear_axle") diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 7e9aa5732e..e134a73bea 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -88,7 +88,6 @@ DECLARE_ENUM(ePools); DECLARE_ENUM(eWorldProperty); DECLARE_ENUM_CLASS(eModelLoadState); DECLARE_ENUM_CLASS(PreloadAreaOption); -DECLARE_ENUM_CLASS(EModelLoadingScheme); class CRemoteCall; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp index f62147ea68..f54378944d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp @@ -2123,7 +2123,7 @@ bool CLuaDrawingDefs::DxDrawWiredSphere(lua_State* const luaVM, const CVector po return true; } -bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme) +bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale) { CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelID); if (!pModelInfo) @@ -2138,6 +2138,5 @@ bool CLuaDrawingDefs::DxDrawModel3D(std::uint32_t modelID, CVector position, CVe ConvertDegreesToRadians(rotation); return g_pClientGame->GetModelRenderer()->EnqueueModel(pModelInfo, - CMatrix{position, rotation, scale.value_or(CVector{1.0f, 1.0f, 1.0f})}, - loadingScheme.value_or(EModelLoadingScheme::Async)); + CMatrix{position, rotation, scale.value_or(CVector{1.0f, 1.0f, 1.0f})}); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h index 5faf04fe65..55dc3adda1 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.h @@ -82,7 +82,7 @@ class CLuaDrawingDefs : public CLuaDefs static bool DxDrawWiredSphere(lua_State* const luaVM, const CVector position, const float radius, const std::optional color, const std::optional lineWidth, const std::optional iterations); - static bool DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale, const std::optional loadingScheme); + static bool DxDrawModel3D(std::uint32_t modelID, CVector position, CVector rotation, const std::optional scale); private: static void AddDxMaterialClass(lua_State* luaVM); From 5a5d289665700518a1446995080de0cdeebc58a0 Mon Sep 17 00:00:00 2001 From: TEDERIs Date: Thu, 29 Aug 2024 19:01:09 +0700 Subject: [PATCH 10/10] Additional noexcept --- Client/game_sa/CGameSA.h | 2 +- Client/sdk/game/CGame.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/game_sa/CGameSA.h b/Client/game_sa/CGameSA.h index 03622919eb..cf4788d953 100644 --- a/Client/game_sa/CGameSA.h +++ b/Client/game_sa/CGameSA.h @@ -173,7 +173,7 @@ class CGameSA : public CGame CCoverManagerSA* GetCoverManager() const noexcept { return m_pCoverManager; }; CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; }; CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; } - CRenderer* GetRenderer() const override { return m_pRenderer.get(); } + CRenderer* GetRenderer() const noexcept override { return m_pRenderer.get(); } CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD); CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false); diff --git a/Client/sdk/game/CGame.h b/Client/sdk/game/CGame.h index 4e5dedb6d7..2314fdad0e 100644 --- a/Client/sdk/game/CGame.h +++ b/Client/sdk/game/CGame.h @@ -150,7 +150,7 @@ class __declspec(novtable) CGame virtual CPointLights* GetPointLights() = 0; virtual CColStore* GetCollisionStore() = 0; virtual CBuildingRemoval* GetBuildingRemoval() = 0; - virtual CRenderer* GetRenderer() const = 0; + virtual CRenderer* GetRenderer() const noexcept = 0; virtual CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD) = 0; virtual CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false) = 0;