Skip to content

dxDrawModel3D reimplementation #3266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ CGameSA::CGameSA()
m_pPlantManager = new CPlantManagerSA();
m_pBuildingRemoval = new CBuildingRemovalSA();

m_pRenderer = std::make_unique<CRendererSA>();

// Normal weapon types (WEAPONSKILL_STD)
for (int i = 0; i < NUM_WeaponInfosStdSkill; i++)
{
Expand Down
6 changes: 5 additions & 1 deletion Client/game_sa/CGameSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "CStreamingSA.h"
#include "CCoverManagerSA.h"
#include "CPlantManagerSA.h"
#include "CRendererSA.h"

class CAnimBlendClumpDataSAInterface;
class CObjectGroupPhysicalPropertiesSA;
Expand Down Expand Up @@ -172,7 +173,8 @@ 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(); }

CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD);
CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false);
CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup);
Expand Down Expand Up @@ -346,6 +348,8 @@ class CGameSA : public CGame
CPlantManagerSA* m_pPlantManager;
CBuildingRemoval* m_pBuildingRemoval;

std::unique_ptr<CRendererSA> m_pRenderer;

CPad* m_pPad;
CAERadioTrackManager* m_pCAERadioTrackManager;
CAudioEngine* m_pAudioEngine;
Expand Down
5 changes: 4 additions & 1 deletion Client/game_sa/CModelInfoSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2028,7 +2028,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)
Expand Down
55 changes: 55 additions & 0 deletions Client/game_sa/CRendererSA.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*****************************************************************************
*
* 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"
#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<RpAtomic*>(pRwObject);
pRpAtomic->renderCallback(reinterpret_cast<RpAtomic*>(pRwObject));
}
else
{
RpClump* pClump = reinterpret_cast<RpClump*>(pRwObject);
RpClumpRender(pClump);
}
}
23 changes: 23 additions & 0 deletions Client/game_sa/CRendererSA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CRendererSA.h
* PURPOSE: Game renderer class
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once

#include <game/CRenderer.h>

class CRendererSA : public CRenderer
{
public:
CRendererSA();
~CRendererSA();

void RenderModel(CModelInfo* pModelInfo, const CMatrix& matrix) override;
};
7 changes: 7 additions & 0 deletions Client/game_sa/CVisibilityPluginsSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
2 changes: 2 additions & 0 deletions Client/game_sa/CVisibilityPluginsSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
4 changes: 4 additions & 0 deletions Client/game_sa/gamesa_renderware.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions Client/game_sa/gamesa_renderware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions Client/mods/deathmatch/StdInc.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
#include <CScriptFile.h>
#include <CWeaponNames.h>
#include <CVehicleNames.h>
#include <CModelRenderer.h>
#include <lua/CLuaCFunctions.h>
#include <lua/CLuaArguments.h>
#include <lua/CLuaMain.h>
Expand Down
12 changes: 12 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,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<CModelRenderer>();

// Register the message and the net packet handler
g_pMultiplayer->SetPreWeaponFireHandler(CClientGame::PreWeaponFire);
g_pMultiplayer->SetPostWeaponFireHandler(CClientGame::PostWeaponFire);
Expand All @@ -267,6 +270,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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -3546,6 +3551,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);
Expand Down Expand Up @@ -3853,6 +3863,8 @@ void CClientGame::PostWorldProcessPedsAfterPreRenderHandler()
{
CLuaArguments Arguments;
m_pRootEntity->CallEvent("onClientPedsProcessed", Arguments, false);

g_pClientGame->GetModelRenderer()->Update();
}

void CClientGame::IdleHandler()
Expand Down
5 changes: 5 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,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
Expand Down Expand Up @@ -504,6 +506,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();
Expand Down Expand Up @@ -698,6 +701,8 @@ class CClientGame
CRemoteCalls* m_pRemoteCalls;
CResourceFileDownloadManager* m_pResourceFileDownloadManager;

std::unique_ptr<CModelRenderer> m_pModelRenderer;

// Revised facilities
CServer m_Server;

Expand Down
72 changes: 72 additions & 0 deletions Client/mods/deathmatch/logic/CModelRenderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*****************************************************************************
*
* 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"
#include "game\CVisibilityPlugins.h"

bool CModelRenderer::EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix)
{
if (g_pCore->IsWindowMinimized())
return false;

if (pModelInfo && pModelInfo->IsLoaded())
{
m_Queue.emplace_back(pModelInfo, matrix);
return true;
}

return false;
}

void CModelRenderer::Update()
{
CVisibilityPlugins* pVisibilityPlugins = g_pGame->GetVisibilityPlugins();
assert(pVisibilityPlugins);

for (auto& modelDesc : m_Queue)
{
// 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);

// Draw opaque entities
for (auto& modelDesc : m_Queue)
{
if (modelDesc.pModelInfo->IsLoaded() && !modelDesc.pModelInfo->GetIdeFlag(eModelIdeFlag::DRAW_LAST))
pRenderer->RenderModel(modelDesc.pModelInfo, modelDesc.matrix);
}

m_Queue.clear();
}

void CModelRenderer::RenderEntity(SModelToRender* modelDesc, float distance)
{
if (!modelDesc->pModelInfo->IsLoaded())
return;

CRenderer* pRenderer = g_pGame->GetRenderer();
assert(pRenderer);

pRenderer->RenderModel(modelDesc->pModelInfo, modelDesc->matrix);
}
40 changes: 40 additions & 0 deletions Client/mods/deathmatch/logic/CModelRenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*****************************************************************************
*
* 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

class CModelRenderer final
{
public:
struct SModelToRender final
{
CModelInfo* pModelInfo;
CMatrix matrix;

SModelToRender(CModelInfo* pModelInfo, const CMatrix& matrix) :
pModelInfo(pModelInfo),
matrix(matrix)
{
}
};

bool EnqueueModel(CModelInfo* pModelInfo, const CMatrix& matrix);

void Update();

void Render();

static void RenderEntity(SModelToRender* entity, float distance);

private:

std::vector<SModelToRender> m_Queue;
};
Loading
Loading