Skip to content

Feature: dxDrawModel3d #3172

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 9 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from 7 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
29 changes: 29 additions & 0 deletions Client/game_sa/CModelInfoSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2100,3 +2100,32 @@ bool CModelInfoSA::ForceUnload()

return true;
}

bool CModelInfoSA::Render(CMatrix& matrix)
{
CBaseModelInfoSAInterface* pModelInfoSAInterface = GetInterface();
RwObject* pRwObject = pModelInfoSAInterface->pRwObject;
// RwEngineInstance->dOpenDevice.fpRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, 100u);
RwFrame* pFrame = RpGetFrame(pRwObject);
RwFrameSetIdentity(pFrame);
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);
RwFrameUpdateObjects(pFrame);
//RwFrameRotate(pFrame, &yaxis, rotation.fX, RwOpCombineType::rwCOMBINEREPLACE);

if (pRwObject->type == RP_TYPE_ATOMIC)
{
RpAtomic* pRpAtomic = reinterpret_cast<RpAtomic*>(pRwObject);
pRpAtomic->renderCallback(pRpAtomic);
}
else
{
RpClump* pRpClump = reinterpret_cast<RpClump*>(pRwObject);
RpClumpRender(pRpClump);
}
return true;
}
3 changes: 3 additions & 0 deletions Client/game_sa/CModelInfoSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ class CModelInfoSA : public CModelInfo
// Vehicle towing functions
bool IsTowableBy(CModelInfo* towingModel) override;

// It can crash when called in wrong moment, be careful. Good moment is when all objects are rendered.
bool Render(CMatrix& matrix);

private:
void CopyStreamingInfoFromModel(ushort usCopyFromModelID);
void RwSetSupportedUpgrades(RwFrame* parent, DWORD dwModel);
Expand Down
13 changes: 13 additions & 0 deletions Client/game_sa/CWorldSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,23 @@ bool CWorldSA::ResetSurfaceInfo(short sSurfaceID)
void HOOK_FallenPeds();
void HOOK_FallenCars();

DWORD CONTINUE_HookDefaultRender = 0x7491C5;

void _declspec(naked) HookDefaultRender()
{
_asm
{
push esi
mov esi, [esp+4+4]
jmp CONTINUE_HookDefaultRender
}
}

void CWorldSA::InstallHooks()
{
HookInstall(0x565CB0, (DWORD)HOOK_FallenPeds, 5);
HookInstall(0x565E80, (DWORD)HOOK_FallenCars, 5);
HookInstall(0x7491C0, (DWORD)HookDefaultRender, 5);
}

DWORD CONTINUE_CWorld_FallenPeds = 0x00565CBA;
Expand Down
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
4 changes: 4 additions & 0 deletions Client/game_sa/gamesa_renderware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ void InitRwFunctions(eGameVersion version)
RwStreamSkip = (RwStreamSkip_t)0x007ECD40; // check
RpClumpDestroy = (RpClumpDestroy_t)0x0074A360;
RpClumpGetNumAtomics = (RpClumpGetNumAtomics_t)0x00749930;
RwFrameTransform = (RwFrameTransform_t)0x007F0F70;
RwFrameTranslate = (RwFrameTranslate_t)0x007F0E70;
RpClumpForAllAtomics = (RpClumpForAllAtomics_t)0x00749BC0;
RwFrameAddChild = (RwFrameAddChild_t)0x007F0B40;
Expand All @@ -40,6 +41,7 @@ void InitRwFunctions(eGameVersion version)
RwTexDictionaryStreamWrite = (RwTexDictionaryStreamWrite_t)0x00804A30;
rwD3D9NativeTextureRead = (rwD3D9NativeTextureRead_t)0x004CD820;
RpPrtStdGlobalDataSetStreamEmbedded = (RpPrtStdGlobalDataSetStreamEmbedded_t)0x0041B350;
RpClumpRender = (RpClumpRender_t)0x00749B20;
RpClumpRemoveAtomic = (RpClumpRemoveAtomic_t)0x0074A510;
RpAtomicClone = (RpAtomicClone_t)0x00749EB0;
RwTexDictionaryFindNamedTexture = (RwTexDictionaryFindNamedTexture_t)0x007F3A30;
Expand Down Expand Up @@ -123,6 +125,7 @@ void InitRwFunctions(eGameVersion version)
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 @@ -137,6 +140,7 @@ void InitRwFunctions(eGameVersion version)
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
33 changes: 33 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3551,8 +3551,36 @@ void CClientGame::StaticGameRunNamedAnimDestructorHandler(class CTaskSimpleRunNa
g_pClientGame->GameRunNamedAnimDestructorHandler(pTask);
}

void CClientGame::EnqueueModelToRender(SModelToRender modelToRender)
{
m_vecModelsToRender.push_back(modelToRender);
}

void CClientGame::GameEntityRenderHandler(CEntitySAInterface* pGameEntity)
{
if (m_vecModelsToRender.empty())
return;

for (auto& extraEntity : m_vecModelsToRender)
{
auto modelInfo = g_pGame->GetModelInfo(extraEntity.usModel);
if (modelInfo == nullptr)
continue;
if (!modelInfo->IsLoaded())
modelInfo->Request(EModelRequestType::BLOCKING, "Lua::DxDrawModel3d");
if (!modelInfo->IsLoaded())
continue;

modelInfo->Render(extraEntity.matrix);
}

m_vecModelsToRender.clear();
}

void CClientGame::StaticGameEntityRenderHandler(CEntitySAInterface* pGameEntity)
{
g_pClientGame->GameEntityRenderHandler(pGameEntity);

if (pGameEntity)
{
CPools* pPools = g_pGame->GetPools();
Expand Down Expand Up @@ -3690,6 +3718,11 @@ void CClientGame::ProjectileInitiateHandler(CClientProjectile* pProjectile)

void CClientGame::Render3DStuffHandler()
{
//auto modelInfo = g_pGame->GetModelInfo(1632);
//if (!modelInfo->IsLoaded())
// return;

//modelInfo->Render(CVector(0,30,6.0f));
}

void CClientGame::PreRenderSkyHandler()
Expand Down
10 changes: 10 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ struct SMiscGameSettings
bool bAllowShotgunDamageFix;
};

struct SModelToRender
{
uint16_t usModel;
CMatrix matrix;
};

class CClientGame
{
friend class CPacketHandler;
Expand Down Expand Up @@ -585,6 +591,7 @@ class CClientGame
void TaskSimpleBeHitHandler(CPedSAInterface* pPedAttacker, ePedPieceTypes hitBodyPart, int hitBodySide, int weaponId);
AnimationId DrivebyAnimationHandler(AnimationId animGroup, AssocGroupId animId);
void AudioZoneRadioSwitchHandler(DWORD dwStationID);
void GameEntityRenderHandler(CEntitySAInterface* pGameEntity);

static bool StaticProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
bool ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
Expand Down Expand Up @@ -637,6 +644,7 @@ class CClientGame

void PedStepHandler(CPedSAInterface* pPed, bool bFoot);
void VehicleWeaponHitHandler(SVehicleWeaponHitEvent& event);
void EnqueueModelToRender(SModelToRender modelToRender);

private:
eStatus m_Status;
Expand Down Expand Up @@ -812,6 +820,8 @@ class CClientGame
bool m_bShowCollision;
bool m_bShowSound;

std::vector<SModelToRender> m_vecModelsToRender;

// Debug class. Empty in release.
public:
CFoo m_Foo;
Expand Down
12 changes: 12 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@
#define MIN_CLIENT_REQ_DXSETRENDERTARGET_CALL_RESTRICTIONS "1.3.0-9.04431"
extern bool g_bAllowAspectRatioAdjustment;

bool DxDrawModel3d(uint16_t usModel, CVector position, CVector rotation, std::optional<CVector> scale)
{
SModelToRender modelToRender;
modelToRender.usModel = usModel;
ConvertDegreesToRadians(rotation);
CMatrix matrix(position, rotation, scale.value_or(CVector(1.0f, 1.0f, 1.0f)));
modelToRender.matrix = matrix;
g_pClientGame->EnqueueModelToRender(modelToRender);
return true;
}

void CLuaDrawingDefs::LoadFunctions()
{
constexpr static const std::pair<const char*, lua_CFunction> functions[]{
Expand Down Expand Up @@ -64,6 +75,7 @@ void CLuaDrawingDefs::LoadFunctions()
{"dxSetAspectRatioAdjustmentEnabled", DxSetAspectRatioAdjustmentEnabled},
{"dxIsAspectRatioAdjustmentEnabled", DxIsAspectRatioAdjustmentEnabled},
{"dxSetTextureEdge", DxSetTextureEdge},
{"dxDrawModel3d", ArgumentParser<DxDrawModel3d>},
};

// Add functions
Expand Down
23 changes: 22 additions & 1 deletion Client/multiplayer_sa/CMultiplayerSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ const DWORD RETURN_Idle_CWorld_ProcessPedsAfterPreRender = 0x53EA08;
#define HOOKPOS_CWeapon__TakePhotograph 0x73C26E

#define HOOKPOS_CCollision__CheckCameraCollisionObjects 0x41AB8E
#define HOOKPOS_CRenderer__RenderFadingInEntities_MID 0x55320E

CPed* pContextSwitchedPed = 0;
CVector vecCenterOfWorld;
Expand Down Expand Up @@ -542,6 +543,7 @@ void HOOK_CAutomobile__dmgDrawCarCollidingParticles();
void HOOK_CWeapon__TakePhotograph();

void HOOK_CCollision__CheckCameraCollisionObjects();
void HOOK_CRenderer__RenderFadingInEntities_MID();

CMultiplayerSA::CMultiplayerSA()
{
Expand Down Expand Up @@ -749,6 +751,7 @@ void CMultiplayerSA::InitHooks()
HookInstall(HOOKPOS_CWeapon__TakePhotograph, (DWORD)HOOK_CWeapon__TakePhotograph, 3 + 2);

HookInstall(HOOKPOS_CCollision__CheckCameraCollisionObjects, (DWORD)HOOK_CCollision__CheckCameraCollisionObjects, 6 + 4);
HookInstall(HOOKPOS_CRenderer__RenderFadingInEntities_MID, (DWORD)HOOK_CRenderer__RenderFadingInEntities_MID, 5);

// Disable GTA setting g_bGotFocus to false when we minimize
MemSet((void*)ADDR_GotFocus, 0x90, 10);
Expand Down Expand Up @@ -3050,7 +3053,7 @@ void _declspec(naked) HOOK_Render3DStuff()
{
pushad
}
if (m_pRender3DStuffHandler) m_pRender3DStuffHandler();
//if (m_pRender3DStuffHandler) m_pRender3DStuffHandler();

_asm
{
Expand Down Expand Up @@ -7024,6 +7027,24 @@ bool CanEntityCollideWithCamera(CEntitySAInterface* pEntity)
return true;
}

constexpr DWORD _Z17SetAmbientColoursv = 0x735D30;

constexpr DWORD CONTINUE_CRenderer__RenderFadingInEntities_MID = 0x553213;
void _declspec(naked) HOOK_CRenderer__RenderFadingInEntities_MID()
{
_asm {
call _Z17SetAmbientColoursv
pushad
}

if (m_pRender3DStuffHandler) m_pRender3DStuffHandler();

_asm {
popad
jmp CONTINUE_CRenderer__RenderFadingInEntities_MID
}
}

void _declspec(naked) HOOK_CCollision__CheckCameraCollisionObjects()
{
_asm
Expand Down
3 changes: 3 additions & 0 deletions Client/sdk/game/CModelInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
class CBaseModelInfoSAInterface;
class CColModel;
class CPedModelInfo;
class CMatrix;
struct RpClump;
struct RwObject;

Expand Down Expand Up @@ -246,4 +247,6 @@ class CModelInfo
virtual bool IsTowableBy(CModelInfo* towingModel) = 0;

virtual unsigned int GetParentID() = 0;

virtual bool Render(CMatrix& transform) = 0;
};