From c8621a22d0127e5ef621dd58d4efce08910266db Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sat, 18 May 2024 00:45:18 +0200 Subject: [PATCH 01/48] Add RtxDrv --- .vimrc | 5 ++ CT.sln | 4 ++ CT/Src/Launcher.cpp | 49 ++++++++++-------- RtxDrv/RtxDrv.vcproj | 113 ++++++++++++++++++++++++++++++++++++++++++ RtxDrv/Src/RtxDrv.cpp | 4 ++ RtxDrv/Src/RtxDrv.h | 23 +++++++++ compile_flags.txt | 1 + 7 files changed, 178 insertions(+), 21 deletions(-) create mode 100644 RtxDrv/RtxDrv.vcproj create mode 100644 RtxDrv/Src/RtxDrv.cpp create mode 100644 RtxDrv/Src/RtxDrv.h diff --git a/.vimrc b/.vimrc index d4a6f061..cf1c2316 100644 --- a/.vimrc +++ b/.vimrc @@ -3,8 +3,13 @@ set errorformat^=%f(%l):\ %m,%f(%l)\ :\ %m,%f\ :\ error\ %m,LINK\ :\ fatal\ erro map :wa let &makeprg='..\GameData\System\UCC.exe' make! make "ini=../../Code/UCC/UCC.ini" -noprompt -fullsourcepath -noincremental :cwindow map :wa let &makeprg='build.bat' make! debug :cwindow +<<<<<<< Updated upstream map :!start "../GameData/System/CT.exe" dm_canyon?game=mpgame.dmgame?maxplayers=32?Listen -windowed -log -nosaveconfig -rendev=opengl map :!start "../GameData/System/CTEditor.exe" +======= +map :!start "../GameData/System/CT.exe" dm_canyon?game=mpgame.dmgame?maxplayers=32?Listen -windowed -log -nosaveconfig -rendev=rtx +map :!start "../GameData/System/ModEd.exe" +>>>>>>> Stashed changes augroup customhighlight autocmd! diff --git a/CT.sln b/CT.sln index f3c0df37..5f353b5f 100644 --- a/CT.sln +++ b/CT.sln @@ -23,6 +23,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ModEd", "ModEd\ModEd.vcproj ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RtxDrv", "RtxDrv\RtxDrv.vcproj", "{D7878929-5402-468A-811D-1591523609F3}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug diff --git a/CT/Src/Launcher.cpp b/CT/Src/Launcher.cpp index 95bdfa33..f45f25ca 100644 --- a/CT/Src/Launcher.cpp +++ b/CT/Src/Launcher.cpp @@ -11,6 +11,21 @@ #pragma comment(lib, "Winmm.lib") // timeBeginPeriod, timeEndPeriod +// Allow short form of known render devices. +static FStringTemp GetFullRenderDeviceClassName(const FString& RenderDeviceClass) +{ + if(RenderDeviceClass == "D3D") + return "D3DDrv.D3DRenderDevice"; + else if(RenderDeviceClass == "OpenGL") + return "OpenGLDrv.OpenGLRenderDevice"; + else if(RenderDeviceClass == "Mod") + return "Mod.ModRenderDevice"; + else if(RenderDeviceClass == "Rtx") + return "RtxDrv.RtxRenderDevice"; + + return RenderDeviceClass; +} + static void EndFullscreen() { if(GEngine && GEngine->Client && GEngine->Client->Viewports.Num() > 0 && GEngine->Client->Viewports[0]) @@ -393,18 +408,18 @@ static struct FExecHook : public FExec, FNotifyHook{ SetFocus(Preferences->hWnd); return 1; - } - else if(!GIsEditor && GIsClient && ParseCommand(&Cmd, "USERENDEV")) - { - FString RenderDeviceClass = Cmd; - - if(RenderDeviceClass == "D3D") - RenderDeviceClass = "D3DDrv.D3DRenderDevice"; - else if(RenderDeviceClass == "OpenGL") - RenderDeviceClass = "OpenGLDrv.OpenGLRenderDevice"; - else if(RenderDeviceClass == "Mod") - RenderDeviceClass = "Mod.ModRenderDevice"; + }else if(GIsClient && ParseCommand(&Cmd, "GETRES")){ + Ar.Logf("%ix%i", GEngine->Client->Viewports[0]->SizeX, GEngine->Client->Viewports[0]->SizeY); + return 1; + }else if(ParseCommand(&Cmd, "GETRENDEV")){ + if(GEngine && GEngine->GRenDev) + Ar.Log(GEngine->GRenDev->GetClass()->GetPathName()); + else + Ar.Logf("No render device in use"); + return 1; + }else if(!GIsEditor && GIsClient && ParseCommand(&Cmd, "USERENDEV")){ + FString RenderDeviceClass = GetFullRenderDeviceClassName(Cmd); UClass* Class = LoadClass(NULL, *RenderDeviceClass, NULL, LOAD_NoWarn | LOAD_Quiet, NULL); if(Class) @@ -459,16 +474,8 @@ static void InitEngine() FString RenderDeviceClass; - if(Parse(appCmdLine(), "RenDev=", RenderDeviceClass)) - { - // Allow short form of known render devices. - if(RenderDeviceClass == "D3D") - RenderDeviceClass = "D3DDrv.D3DRenderDevice"; - else if(RenderDeviceClass == "OpenGL") - RenderDeviceClass = "OpenGLDrv.OpenGLRenderDevice"; - else if(RenderDeviceClass == "Mod") - RenderDeviceClass = "Mod.ModRenderDevice"; - + if(Parse(appCmdLine(), "RenDev=", RenderDeviceClass)){ + RenderDeviceClass = GetFullRenderDeviceClassName(RenderDeviceClass); debugf("RenderDevice set on command line: %s", *RenderDeviceClass); GConfig->SetString("Engine.Engine", "RenderDevice", *RenderDeviceClass); RenDevSetOnCommandLine = true; diff --git a/RtxDrv/RtxDrv.vcproj b/RtxDrv/RtxDrv.vcproj new file mode 100644 index 00000000..9db69304 --- /dev/null +++ b/RtxDrv/RtxDrv.vcproj @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RtxDrv/Src/RtxDrv.cpp b/RtxDrv/Src/RtxDrv.cpp new file mode 100644 index 00000000..32c009a7 --- /dev/null +++ b/RtxDrv/Src/RtxDrv.cpp @@ -0,0 +1,4 @@ +#include "RtxDrv.h" + +IMPLEMENT_PACKAGE(RtxDrv) +IMPLEMENT_CLASS(URtxRenderDevice) diff --git a/RtxDrv/Src/RtxDrv.h b/RtxDrv/Src/RtxDrv.h new file mode 100644 index 00000000..5693efa9 --- /dev/null +++ b/RtxDrv/Src/RtxDrv.h @@ -0,0 +1,23 @@ +#ifndef RTXDRV_NATIVE_DEFS +#define RTXDRV_NATIVE_DEFS + +#include "../../D3DDrv/Inc/D3DDrv.h" + +#if SUPPORTS_PRAGMA_PACK +#pragma pack (push,4) +#endif + +#ifndef RTXDRV_API +#define RTXDRV_API DLL_IMPORT +#endif + +class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ + DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) +public: +}; + +#if SUPPORTS_PRAGMA_PACK +#pragma pack (pop) +#endif + +#endif // RTXDRV_NATIVE_DEFS diff --git a/compile_flags.txt b/compile_flags.txt index 5e36b4e1..7f0e90da 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -6,6 +6,7 @@ -DCTGAME_API= -DCTMARKERS_API= -DD3DDRV_API= +-DRTXDRV_API= -DEDITOR_API= -DENGINE_API= -DGAMEPLAY_API= From 96875d0c36026271b2a4917ec4f2f7afd18f2a0f Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sat, 18 May 2024 01:07:03 +0200 Subject: [PATCH 02/48] Add FRtxRenderInterface --- RtxDrv/Src/RtxDrv.cpp | 12 +++++++++ RtxDrv/Src/RtxDrv.h | 61 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/RtxDrv/Src/RtxDrv.cpp b/RtxDrv/Src/RtxDrv.cpp index 32c009a7..ea177873 100644 --- a/RtxDrv/Src/RtxDrv.cpp +++ b/RtxDrv/Src/RtxDrv.cpp @@ -2,3 +2,15 @@ IMPLEMENT_PACKAGE(RtxDrv) IMPLEMENT_CLASS(URtxRenderDevice) + +FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) +{ + RenderInterface.Impl = Super::Lock(Viewport, HitData, HitSize); + + return RenderInterface.Impl ? &RenderInterface : NULL; +} + +void URtxRenderDevice::Unlock(FRenderInterface* RI) +{ + Super::Unlock(static_cast(RI)->Impl); +} diff --git a/RtxDrv/Src/RtxDrv.h b/RtxDrv/Src/RtxDrv.h index 5693efa9..045b0f3e 100644 --- a/RtxDrv/Src/RtxDrv.h +++ b/RtxDrv/Src/RtxDrv.h @@ -11,9 +11,70 @@ #define RTXDRV_API DLL_IMPORT #endif +class FRtxRenderInterface : public FRenderInterface{ +public: + FRenderInterface* Impl; + + virtual void PushState(DWORD Flags = 0){ Impl->PushState(Flags); } + virtual void PopState(DWORD Flags = 0){ Impl->PopState(Flags); } + virtual UBOOL SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer){ return Impl->SetRenderTarget(RenderTarget, bOwnDepthBuffer); } + virtual UBOOL SetCubeRenderTarget(class FDynamicCubemap* Target, int A, int B){ return Impl->SetCubeRenderTarget(Target, A, B); } + virtual void SetViewport(INT X, INT Y, INT Width, INT Height){ Impl->SetViewport(X, Y, Width, Height); } + virtual void Clear(UBOOL UseColor = 1, FColor Color = FColor(0, 0, 0), UBOOL UseDepth = 1, FLOAT Depth = 1.0f, UBOOL UseStencil = 1, DWORD Stencil = 0){ Impl->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); } + virtual void PushHit(const BYTE* Data, INT Count){ Impl->PushHit(Data, Count); } + virtual void PopHit(INT Count, UBOOL Force){ Impl->PopHit(Count, Force); } + virtual void SetCullMode(ECullMode CullMode){ Impl->SetCullMode(CullMode); } + virtual void SetAmbientLight(FColor Color){ Impl->SetAmbientLight(Color); } + virtual void EnableLighting(UBOOL UseDynamic, UBOOL UseStatic = 1, UBOOL Modulate2X = 0, FBaseTexture* Lightmap = NULL, UBOOL LightingOnly = 0, const FSphere& LitSphere = FSphere(FVector(0, 0, 0), 0), int IntValue = 0){ Impl->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); } + virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetLight(LightIndex, Light, Scale); } + virtual void SetShaderLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetShaderLight(LightIndex, Light, Scale); } + virtual void SetNPatchTesselation(FLOAT Tesselation){ Impl->SetNPatchTesselation(Tesselation); } + virtual void SetDistanceFog(UBOOL Enable, FLOAT FogStart, FLOAT FogEnd, FColor Color){ Impl->SetDistanceFog(Enable, FogStart, FogEnd, Color); } + virtual UBOOL EnableFog(UBOOL Enable){ return Impl->EnableFog(Enable); } + virtual UBOOL IsFogEnabled(){ return Impl->IsFogEnabled(); } + virtual void SetGlobalColor(FColor Color){ Impl->SetGlobalColor(Color); } + virtual void SetTransform(ETransformType Type, const FMatrix& Matrix){ Impl->SetTransform(Type, Matrix); } + virtual FMatrix GetTransform(ETransformType Type) const { return Impl->GetTransform(Type); } + virtual void SetMaterial(UMaterial* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL, INT* NumPasses = NULL){ + if(Material->IsA()) + static_cast(Material)->Bumpmap = NULL; + else if(Material->IsA() || Material->IsA()) + Material = GetDefault()->DefaultMaterial; + Impl->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); + } + virtual UBOOL SetHardwareShaderMaterial(UHardwareShader* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL){ return Impl->SetHardwareShaderMaterial(Material, ErrorString, ErrorMaterial); } + virtual UBOOL ShowAlpha(UMaterial* Material){ return Impl->ShowAlpha(Material); } + virtual UBOOL IsShadowInterface(){ return Impl->IsShadowInterface(); } + virtual void SetAntiAliasing(INT Level){ Impl->SetAntiAliasing(Level); } + virtual void CopyBackBufferToTarget(FAuxRenderTarget* Target){ Impl->CopyBackBufferToTarget(Target); } + virtual void SetLODDiffuseFade(FLOAT Distance){ Impl->SetLODDiffuseFade(Distance); } + virtual void SetLODSpecularFade(FLOAT Distance){ Impl->SetLODSpecularFade(Distance); } + virtual void SetStencilOp(ECompareFunction Test, DWORD Ref, DWORD Mask, EStencilOp FailOp, EStencilOp ZFailOp, EStencilOp PassOp, DWORD WriteMask){ Impl->SetStencilOp(Test, Ref, Mask, FailOp, ZFailOp, PassOp, WriteMask); } + virtual void EnableStencil(UBOOL Enable){ Impl->EnableStencil(Enable); } + virtual void EnableDepth(UBOOL Enable){ Impl->EnableDepth(Enable); } + virtual void SetPrecacheMode(EPrecacheMode PrecacheMode){ Impl->SetPrecacheMode(PrecacheMode); } + virtual void SetZBias(INT ZBias){ Impl->SetZBias(ZBias); } + virtual INT SetVertexStreams(EVertexShader Shader, FVertexStream** Streams, INT NumStreams){ return Impl->SetVertexStreams(Shader, Streams, NumStreams); } + virtual INT SetDynamicStream(EVertexShader Shader, FVertexStream* Stream){ return Impl->SetDynamicStream(Shader, Stream); } + virtual INT SetIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetIndexBuffer(IndexBuffer, BaseIndex); } + virtual INT SetDynamicIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetDynamicIndexBuffer(IndexBuffer, BaseIndex); } + virtual void DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex = INDEX_NONE, INT MaxIndex = INDEX_NONE){ Impl->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); } + virtual void PixoSetHint(DWORD Hint){ Impl->PixoSetHint(Hint); } + virtual void PixoResetHint(DWORD Hint){ Impl->PixoResetHint(Hint); } + virtual UTexture* PixoCreateTexture(FRenderTarget* RenderTarget, UBOOL CreateMips){ return Impl->PixoCreateTexture(RenderTarget, CreateMips); } + virtual UBOOL PixoIsVisible(FBox& Box){ return Impl->PixoIsVisible(Box); } + virtual bool IsVertexBufferBusy(FVertexStream* Stream){ return Impl->IsVertexBufferBusy(Stream); } + virtual void SetFillMode(EFillMode FillMode){ Impl->SetFillMode(FillMode); } +}; + class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) public: + + FRtxRenderInterface RenderInterface; + + virtual FRenderInterface* Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize); + virtual void Unlock(FRenderInterface* RI); }; #if SUPPORTS_PRAGMA_PACK From beacea07043e57b9588d03bc891814f6f1283a80 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sat, 18 May 2024 02:18:58 +0200 Subject: [PATCH 03/48] Set graphics effects to low at startup --- .vimrc | 9 +++------ CT/Src/Launcher.cpp | 3 ++- RtxDrv/Src/RtxDrv.cpp | 10 ++++++++++ RtxDrv/Src/RtxDrv.h | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.vimrc b/.vimrc index cf1c2316..2340e9a2 100644 --- a/.vimrc +++ b/.vimrc @@ -3,13 +3,10 @@ set errorformat^=%f(%l):\ %m,%f(%l)\ :\ %m,%f\ :\ error\ %m,LINK\ :\ fatal\ erro map :wa let &makeprg='..\GameData\System\UCC.exe' make! make "ini=../../Code/UCC/UCC.ini" -noprompt -fullsourcepath -noincremental :cwindow map :wa let &makeprg='build.bat' make! debug :cwindow -<<<<<<< Updated upstream -map :!start "../GameData/System/CT.exe" dm_canyon?game=mpgame.dmgame?maxplayers=32?Listen -windowed -log -nosaveconfig -rendev=opengl + +" map :!start "../GameData/System/CT.exe" dm_canyon?game=mpgame.dmgame?maxplayers=32?Listen -windowed -log -nosaveconfig -rendev=rtx +map :!start "../GameData/System/CT.exe" geo_01a -windowed -log -nosaveconfig -rendev=rtx map :!start "../GameData/System/CTEditor.exe" -======= -map :!start "../GameData/System/CT.exe" dm_canyon?game=mpgame.dmgame?maxplayers=32?Listen -windowed -log -nosaveconfig -rendev=rtx -map :!start "../GameData/System/ModEd.exe" ->>>>>>> Stashed changes augroup customhighlight autocmd! diff --git a/CT/Src/Launcher.cpp b/CT/Src/Launcher.cpp index f45f25ca..814a2c9a 100644 --- a/CT/Src/Launcher.cpp +++ b/CT/Src/Launcher.cpp @@ -675,7 +675,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine appPreExit(); GIsGuarded = 0; - }catch(...) + } + catch(...) { GIsGuarded = 0; ExitCode = EXIT_FAILURE; diff --git a/RtxDrv/Src/RtxDrv.cpp b/RtxDrv/Src/RtxDrv.cpp index ea177873..d44bb1c4 100644 --- a/RtxDrv/Src/RtxDrv.cpp +++ b/RtxDrv/Src/RtxDrv.cpp @@ -3,6 +3,16 @@ IMPLEMENT_PACKAGE(RtxDrv) IMPLEMENT_CLASS(URtxRenderDevice) +UBOOL URtxRenderDevice::Init() +{ + UClient* Client = UTexture::__Client; + Client->Shadows = 0; + Client->FrameFXDisabled = 1; + Client->BloomQuality = 0; + Client->BumpmappingQuality = 0; + return Super::Init(); +} + FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) { RenderInterface.Impl = Super::Lock(Viewport, HitData, HitSize); diff --git a/RtxDrv/Src/RtxDrv.h b/RtxDrv/Src/RtxDrv.h index 045b0f3e..aa250ff2 100644 --- a/RtxDrv/Src/RtxDrv.h +++ b/RtxDrv/Src/RtxDrv.h @@ -73,6 +73,7 @@ class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ FRtxRenderInterface RenderInterface; + virtual UBOOL Init(); virtual FRenderInterface* Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize); virtual void Unlock(FRenderInterface* RI); }; From f5fb3abe4fc938c4609ff4f63f6f7e1feffc96a2 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 20 May 2024 21:01:54 +0200 Subject: [PATCH 04/48] Restore UD3DRenderDevice variables --- D3DDrv/Inc/D3DDrv.h | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/D3DDrv/Inc/D3DDrv.h b/D3DDrv/Inc/D3DDrv.h index 46c01977..c5558373 100644 --- a/D3DDrv/Inc/D3DDrv.h +++ b/D3DDrv/Inc/D3DDrv.h @@ -18,10 +18,39 @@ struct IDirect3DDevice8; class D3DDRV_API UD3DRenderDevice : public URenderDevice{ DECLARE_CLASS(UD3DRenderDevice,URenderDevice,CLASS_Config,D3DDrv); public: - char Padding1[17920]; + char Padding1[16412]; // Padding + UBOOL UsePrecaching; + UBOOL UseTrilinear; + char Padding2; // Padding + UBOOL UseVSync; + UBOOL UseHardwareTL; + UBOOL UseHardwareVS; + UBOOL UseCubemaps; + char PADDING3[16]; // Padding + UBOOL UseTripleBuffering; + UBOOL ReduceMouseLag; + UBOOL UseXBoxFSAA; + char Padding4[16]; // Padding + UBOOL CheckForOverflow; + UBOOL UseNPatches; + UBOOL DecompressTextures; + UBOOL AvoidHitches; + UBOOL OverrideDesktopRefreshRate; + char Padding5[4]; // Padding + INT AdapterNumber; + char Padding6[4]; // Padding + INT MaxPixelShaderVersion; + INT LevelOfAnisotropy; + FLOAT DetailTexMipBias; + FLOAT DefaultTexMipBias; + FLOAT TesselationFactor; + FLOAT DesiredRefreshRate; + INT VideoResetAttempts; + UBOOL StateCachingDisabled; + char Padding7[1370]; // Padding IDirect3D8* Direct3D8; IDirect3DDevice8* Direct3DDevice8; - char Padding2[47868]; + char Padding8[47868]; // Padding //Overrides virtual UBOOL Exec(const TCHAR* Cmd, FOutputDevice& Ar); From 1ca868069e0eec72f03d875fb04a406e892a701d Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 17 Jun 2024 20:14:15 +0200 Subject: [PATCH 05/48] Fix ULodMesh variables --- Core/Inc/FConfigCacheIni.h | 12 ++++---- Engine/Inc/UnMesh.h | 60 ++++++++++++++++++++++++++++++-------- Mod/Inc/ModRenderDevice.h | 2 +- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/Core/Inc/FConfigCacheIni.h b/Core/Inc/FConfigCacheIni.h index f3923dd8..fb19f173 100644 --- a/Core/Inc/FConfigCacheIni.h +++ b/Core/Inc/FConfigCacheIni.h @@ -248,7 +248,7 @@ class FConfigCacheIni : public FConfigCache, public TMap{ UBOOL& Value, const TCHAR* Filename ) -{ + { guard(FConfigCacheIni::GetBool); const TCHAR* Text = GetStr(Section, Key, Filename); @@ -274,7 +274,7 @@ class FConfigCacheIni : public FConfigCache, public TMap{ INT& Value, const TCHAR* Filename ) -{ + { guard(FConfigCacheIni::GetInt); const TCHAR* Text = GetStr(Section, Key, Filename); @@ -297,7 +297,7 @@ class FConfigCacheIni : public FConfigCache, public TMap{ FLOAT& Value, const TCHAR* Filename ) -{ + { guard(FConfigCacheIni::GetFloat); const TCHAR* Text = GetStr(Section, Key, Filename); @@ -457,7 +457,7 @@ class FConfigCacheIni : public FConfigCache, public TMap{ UBOOL Value, const TCHAR* Filename ) -{ + { guard(FConfigCacheIni::SetBool); SetString(Section, Key, Value ? "True" : "False", Filename); @@ -471,7 +471,7 @@ class FConfigCacheIni : public FConfigCache, public TMap{ INT Value, const TCHAR* Filename ) -{ + { guard(FConfigCacheIni::SetInt); TCHAR Text[30]; @@ -487,7 +487,7 @@ class FConfigCacheIni : public FConfigCache, public TMap{ FLOAT Value, const TCHAR* Filename ) -{ + { guard(FConfigCacheIni::SetFloat); TCHAR Text[30]; diff --git a/Engine/Inc/UnMesh.h b/Engine/Inc/UnMesh.h index 9920200d..e5b84171 100644 --- a/Engine/Inc/UnMesh.h +++ b/Engine/Inc/UnMesh.h @@ -220,26 +220,62 @@ class ENGINE_API UMeshInstance : public UPrimitive{ ULodMesh. -----------------------------------------------------------------------------*/ +struct FImpostorProps{ + UMaterial* Material; + FVector Scale3D; + FRotator RelativeRotation; + FVector RelativeLocation; + FColor ImpColor; + INT ImpSpaceMode; + INT ImpDrawMode; + INT ImpLightMode; +}; + class ENGINE_API ULodMesh : public UMesh{ DECLARE_CLASS(ULodMesh,UMesh,CLASS_SafeReplace,Engine) public: - INT InternalVersion; + INT InternalVersion; // General LOD mesh data - INT ModelVerts; - TArray Verts; - TArray Materials; + INT ModelVerts; + TArray Verts; + TArray Materials; // Scaling. - FVector Scale; // Mesh scaling. - FVector Origin; // Origin in original coordinate system. - FRotator RotOrigin; // Amount to rotate when importing (mostly for yawing). + FVector Scale; // Mesh scaling. + FVector Origin; // Origin in original coordinate system. + FRotator RotOrigin; // Amount to rotate when importing (mostly for yawing). // LOD-specific objects. - TArray Faces; // Faces - - // TODO: Variables - char Padding[140]; - // TODO: Virtual functions + TArray<_WORD> FaceLevel; // Minimum lod-level indicator for each face. + TArray Faces; // Faces + TArray<_WORD> CollapseWedgeThus; // Lod-collapse single-linked list for the wedges. + TArray Wedges; // 'Hoppe-style' textured vertices. + TArray MeshMaterials; // Materials + + // Max of x/y/z mesh scale for LOD gauging (works on top of drawscale). + FLOAT MeshScaleMax; + + // Script-settable LOD controlling parameters. + FLOAT LODStrength; // Scales the (not necessarily linear) falloff of vertices with distance. + INT LODMinVerts; // Minimum number of vertices with which to draw a model. + FLOAT LODMorph; // >0.0 = allow morphing ; 0.0-1.0 = range of vertices to morph. + FLOAT LODZDisplace; // Z displacement for LOD distance-dependency tweaking. + FLOAT LODHysteresis; // Controls LOD-level change delay and morphing. + + FLOAT FadeSpecNear; + FLOAT FadeSpecFar; + FLOAT FadeDiffNear; + FLOAT FadeDiffFar; + + // Impostor support. + UBOOL bImpostorPresent; + FImpostorProps ImpostorProps; + + // Hardware specific. + FLOAT SkinTesselationFactor; // Hardware triangle subdivision factor ( <=1.0 means inactive ) + + // Multi-purpose content authentication key. + DWORD AuthenticationKey; }; /*---------------------------------------------------------------------------- diff --git a/Mod/Inc/ModRenderDevice.h b/Mod/Inc/ModRenderDevice.h index c52e4900..24f1af99 100644 --- a/Mod/Inc/ModRenderDevice.h +++ b/Mod/Inc/ModRenderDevice.h @@ -66,7 +66,7 @@ class FSelectionRenderInterface : public FRenderInterface{ * - Adds alternative selection mechanism for much better performance in the Editor */ class MOD_API UModRenderDevice : public UD3DRenderDevice{ - DECLARE_CLASS(UModRenderDevice, UD3DRenderDevice, 0, Mod) + DECLARE_CLASS(UModRenderDevice,UD3DRenderDevice,0,Mod) public: UViewport* LockedViewport; FSelectionRenderInterface SelectionRI; From 6e115a652838622f2e378f48439183ee43048cf1 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 17 Jun 2024 21:33:11 +0200 Subject: [PATCH 06/48] Draw triangles for specific materials to id them in remix --- RtxDrv/Src/RtxDrv.cpp | 134 +++++++++++++++++++++++++++++++++++++++++- RtxDrv/Src/RtxDrv.h | 101 +++++++++++++++++++++++-------- 2 files changed, 208 insertions(+), 27 deletions(-) diff --git a/RtxDrv/Src/RtxDrv.cpp b/RtxDrv/Src/RtxDrv.cpp index d44bb1c4..85cb8b2a 100644 --- a/RtxDrv/Src/RtxDrv.cpp +++ b/RtxDrv/Src/RtxDrv.cpp @@ -5,22 +5,154 @@ IMPLEMENT_CLASS(URtxRenderDevice) UBOOL URtxRenderDevice::Init() { + // Init SWRCFix if it exists. Hacky but RenderDevice is always loaded at startup... + HMODULE ModDLL = LoadLibraryA("Mod.dll"); + + if(ModDLL) + { + void(CDECL*InitSWRCFix)(void) = reinterpret_cast(GetProcAddress(ModDLL, "InitSWRCFix")); + + if(InitSWRCFix) + InitSWRCFix(); + } + + FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 0, 1, StaticConfigName()); + + if(Section) + { + for(FConfigSection::TIterator It(*Section); It; ++It) + { + const INT Id = appAtoi(*It.Value()); + MaterialIdsByPath.AddItem(TestDraw(Id, *It.Key())); + } + } + + RenderInterface.RenDev = this; + RenderInterface.Impl = NULL; + + UMaterial::ClearFallbacks(); UClient* Client = UTexture::__Client; Client->Shadows = 0; Client->FrameFXDisabled = 1; Client->BloomQuality = 0; + Client->BlurEnabled = 0; Client->BumpmappingQuality = 0; + GetDefault()->bVisor = 0; + GetDefault()->VisorModeDefault = 1; + UseStencil = 0; return Super::Init(); } +void URtxRenderDevice::Flush(UViewport* Viewport) +{ + Super::Flush(Viewport); +} + FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) { RenderInterface.Impl = Super::Lock(Viewport, HitData, HitSize); - return RenderInterface.Impl ? &RenderInterface : NULL; } +class RTXDRV_API UConstantColorMaterial : public UConstantMaterial{ +public: + DECLARE_CLASS(UConstantColorMaterial,UConstantMaterial,0,RtxDrv) + virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0); } +}; +IMPLEMENT_CLASS(UConstantColorMaterial) + void URtxRenderDevice::Unlock(FRenderInterface* RI) { + static bool Exited = false; + + if(!Exited && GIsRequestingExit) + { + Exited = true; + FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 1, 0, StaticConfigName()); + check(Section); + + for(TArray::TIterator It(MaterialIdsByPath); It; ++It) + { + FConfigString& Value = (*Section)[It->Path]; + Value = appItoa(It->Id); + Value.Dirty = true; + } + } + Super::Unlock(static_cast(RI)->Impl); } + +void FRtxRenderInterface::SetTransform(ETransformType Type, const FMatrix& Matrix) +{ + Impl->SetTransform(Type, Matrix); +} + +void FRtxRenderInterface::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) +{ + CurrentMaterial = Material; + + UMaterial* ActualMaterial = Material; + + while(ActualMaterial && ActualMaterial->IsA()) + ActualMaterial = static_cast(ActualMaterial)->Material; + + if(ActualMaterial && ActualMaterial->IsA()) + ActualMaterial = static_cast(ActualMaterial)->BitmapMaterial; + + CurrentActualMaterial = ActualMaterial; + + if(ActualMaterial && !ActualMaterial->UseFallback) + { + ActualMaterial->UseFallback = 1; + + if(ActualMaterial->GetFName() != NAME_InGameTempName) + { + const TCHAR* Path = ActualMaterial->GetPathName(); + for(INT i = 0; i < RenDev->MaterialIdsByPath.Num(); ++i) + { + if(RenDev->MaterialIdsByPath[i].Path == Path) + { + reinterpret_cast(ActualMaterial)[24] = (reinterpret_cast(ActualMaterial)[24] & 0x3) | ((i + 1) << 3); + break; + } + } + } + } + + DrawParticleTriangles = ActualMaterial && (reinterpret_cast(ActualMaterial)[24] >> 3) != 0; + + Impl->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); +} + +void FRtxRenderInterface::DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex, INT MaxIndex) +{ + Impl->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); + + if(DrawParticleTriangles) + { + DECLARE_STATIC_UOBJECT(UConstantColorMaterial, TestConstantColorMaterial, {}); + DECLARE_STATIC_UOBJECT(UFinalBlend, TestFinalBlend, { + TestFinalBlend->Material = TestConstantColorMaterial; + }); + + PushState(); + + Impl->SetCullMode(CM_None); + Impl->SetMaterial(TestFinalBlend); + FVertexStream* TestStreamPtr = &RenDev->MaterialIdsByPath[(reinterpret_cast(CurrentActualMaterial)[24] >> 3) - 1].Stream; + Impl->SetVertexStreams(VS_FixedFunction, &TestStreamPtr, 1); + Impl->SetIndexBuffer(NULL, 0); + Impl->DrawPrimitive(PT_TriangleList, 0, 1); + Impl->SetMaterial(CurrentMaterial); + + PopState(); + } +} + +FRenderCaps* URtxRenderDevice::GetRenderCaps() +{ + /* return Super::GetRenderCaps(); */ + static FRenderCaps RenderCaps(1, 14, 1); + + return &RenderCaps; +} diff --git a/RtxDrv/Src/RtxDrv.h b/RtxDrv/Src/RtxDrv.h index aa250ff2..833ba3d4 100644 --- a/RtxDrv/Src/RtxDrv.h +++ b/RtxDrv/Src/RtxDrv.h @@ -3,29 +3,67 @@ #include "../../D3DDrv/Inc/D3DDrv.h" -#if SUPPORTS_PRAGMA_PACK -#pragma pack (push,4) -#endif - #ifndef RTXDRV_API #define RTXDRV_API DLL_IMPORT #endif +class URtxRenderDevice; + +class FSingleTriangleVertexStream : public FVertexStream{ +public: + FSingleTriangleVertexStream(FLOAT Width, FLOAT Height) : HalfWidth(Width / 2), HalfHeight(Height / 2) + { + CacheId = MakeCacheID(CID_RenderVertices); + } + + FLOAT HalfWidth; + FLOAT HalfHeight; + + virtual INT GetStride(){ return sizeof(FVector); } + virtual INT GetSize(){ return sizeof(FVector) * 3; } + + virtual INT GetComponents(FVertexComponent* Components) + { + Components->Type = CT_Float3; + Components->Function = FVF_Position; + return 1; + } + + virtual void GetStreamData(void* Dest) + { + FVector* D = static_cast(Dest); + D[0] = FVector(-HalfWidth, -HalfHeight, 0); + D[1] = FVector(HalfHeight, -HalfHeight, 0); + D[2] = FVector(0, HalfHeight, 0); + } +}; + class FRtxRenderInterface : public FRenderInterface{ public: + URtxRenderDevice* RenDev; FRenderInterface* Impl; + UBOOL DrawParticleTriangles; + UMaterial* CurrentMaterial; + UMaterial* CurrentActualMaterial; + virtual void PushState(DWORD Flags = 0){ Impl->PushState(Flags); } virtual void PopState(DWORD Flags = 0){ Impl->PopState(Flags); } - virtual UBOOL SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer){ return Impl->SetRenderTarget(RenderTarget, bOwnDepthBuffer); } + virtual UBOOL SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer){ + return Impl->SetRenderTarget(RenderTarget, bOwnDepthBuffer); + } virtual UBOOL SetCubeRenderTarget(class FDynamicCubemap* Target, int A, int B){ return Impl->SetCubeRenderTarget(Target, A, B); } virtual void SetViewport(INT X, INT Y, INT Width, INT Height){ Impl->SetViewport(X, Y, Width, Height); } - virtual void Clear(UBOOL UseColor = 1, FColor Color = FColor(0, 0, 0), UBOOL UseDepth = 1, FLOAT Depth = 1.0f, UBOOL UseStencil = 1, DWORD Stencil = 0){ Impl->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); } + virtual void Clear(UBOOL UseColor = 1, FColor Color = FColor(0, 0, 0), UBOOL UseDepth = 1, FLOAT Depth = 1.0f, UBOOL UseStencil = 1, DWORD Stencil = 0){ + Impl->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); + } virtual void PushHit(const BYTE* Data, INT Count){ Impl->PushHit(Data, Count); } virtual void PopHit(INT Count, UBOOL Force){ Impl->PopHit(Count, Force); } virtual void SetCullMode(ECullMode CullMode){ Impl->SetCullMode(CullMode); } virtual void SetAmbientLight(FColor Color){ Impl->SetAmbientLight(Color); } - virtual void EnableLighting(UBOOL UseDynamic, UBOOL UseStatic = 1, UBOOL Modulate2X = 0, FBaseTexture* Lightmap = NULL, UBOOL LightingOnly = 0, const FSphere& LitSphere = FSphere(FVector(0, 0, 0), 0), int IntValue = 0){ Impl->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); } + virtual void EnableLighting(UBOOL UseDynamic, UBOOL UseStatic = 1, UBOOL Modulate2X = 0, FBaseTexture* Lightmap = NULL, UBOOL LightingOnly = 0, const FSphere& LitSphere = FSphere(FVector(0, 0, 0), 0), int IntValue = 0){ + Impl->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); + } virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetLight(LightIndex, Light, Scale); } virtual void SetShaderLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetShaderLight(LightIndex, Light, Scale); } virtual void SetNPatchTesselation(FLOAT Tesselation){ Impl->SetNPatchTesselation(Tesselation); } @@ -33,15 +71,9 @@ class FRtxRenderInterface : public FRenderInterface{ virtual UBOOL EnableFog(UBOOL Enable){ return Impl->EnableFog(Enable); } virtual UBOOL IsFogEnabled(){ return Impl->IsFogEnabled(); } virtual void SetGlobalColor(FColor Color){ Impl->SetGlobalColor(Color); } - virtual void SetTransform(ETransformType Type, const FMatrix& Matrix){ Impl->SetTransform(Type, Matrix); } + virtual void SetTransform(ETransformType Type, const FMatrix& Matrix); virtual FMatrix GetTransform(ETransformType Type) const { return Impl->GetTransform(Type); } - virtual void SetMaterial(UMaterial* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL, INT* NumPasses = NULL){ - if(Material->IsA()) - static_cast(Material)->Bumpmap = NULL; - else if(Material->IsA() || Material->IsA()) - Material = GetDefault()->DefaultMaterial; - Impl->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); - } + virtual void SetMaterial(UMaterial* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL, INT* NumPasses = NULL); virtual UBOOL SetHardwareShaderMaterial(UHardwareShader* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL){ return Impl->SetHardwareShaderMaterial(Material, ErrorString, ErrorMaterial); } virtual UBOOL ShowAlpha(UMaterial* Material){ return Impl->ShowAlpha(Material); } virtual UBOOL IsShadowInterface(){ return Impl->IsShadowInterface(); } @@ -58,28 +90,45 @@ class FRtxRenderInterface : public FRenderInterface{ virtual INT SetDynamicStream(EVertexShader Shader, FVertexStream* Stream){ return Impl->SetDynamicStream(Shader, Stream); } virtual INT SetIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetIndexBuffer(IndexBuffer, BaseIndex); } virtual INT SetDynamicIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetDynamicIndexBuffer(IndexBuffer, BaseIndex); } - virtual void DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex = INDEX_NONE, INT MaxIndex = INDEX_NONE){ Impl->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); } - virtual void PixoSetHint(DWORD Hint){ Impl->PixoSetHint(Hint); } - virtual void PixoResetHint(DWORD Hint){ Impl->PixoResetHint(Hint); } - virtual UTexture* PixoCreateTexture(FRenderTarget* RenderTarget, UBOOL CreateMips){ return Impl->PixoCreateTexture(RenderTarget, CreateMips); } - virtual UBOOL PixoIsVisible(FBox& Box){ return Impl->PixoIsVisible(Box); } - virtual bool IsVertexBufferBusy(FVertexStream* Stream){ return Impl->IsVertexBufferBusy(Stream); } + virtual void DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex = INDEX_NONE, INT MaxIndex = INDEX_NONE); virtual void SetFillMode(EFillMode FillMode){ Impl->SetFillMode(FillMode); } }; class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) + static const TCHAR* StaticConfigName(){ return "RtxDrv"; } public: - FRtxRenderInterface RenderInterface; virtual UBOOL Init(); + virtual void Flush(UViewport* Viewport); virtual FRenderInterface* Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize); virtual void Unlock(FRenderInterface* RI); -}; + virtual FRenderCaps* GetRenderCaps(); -#if SUPPORTS_PRAGMA_PACK -#pragma pack (pop) -#endif + struct TestDraw{ + INT Id; + FSingleTriangleVertexStream Stream; + FString Path; + + TestDraw(INT InId = 0, const TCHAR* InPath = NULL) + : Id(InId), + Stream(InId + 32, InId + 32), + Path(InPath) + { + ++Stream.Revision; + } + + void UpdateId(INT InId) + { + Id = InId, + Stream.HalfWidth = (InId + 32) / 2.0f; + Stream.HalfHeight = Stream.HalfWidth; + ++Stream.Revision; + } + }; + + TArray MaterialIdsByPath; +}; #endif // RTXDRV_NATIVE_DEFS From 0d3a622476d951b912405657bcecf4636f972e70 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 18 Jun 2024 16:45:53 +0200 Subject: [PATCH 07/48] Don't use UMaterial::UseFallbacks since the d3d8 renderer also uses it --- RtxDrv/Src/RtxDrv.cpp | 23 +++++++++++++++++++---- RtxDrv/Src/RtxDrv.h | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/RtxDrv/Src/RtxDrv.cpp b/RtxDrv/Src/RtxDrv.cpp index 85cb8b2a..998c9e1b 100644 --- a/RtxDrv/Src/RtxDrv.cpp +++ b/RtxDrv/Src/RtxDrv.cpp @@ -30,7 +30,7 @@ UBOOL URtxRenderDevice::Init() RenderInterface.RenDev = this; RenderInterface.Impl = NULL; - UMaterial::ClearFallbacks(); + ClearMaterialFlags(); UClient* Client = UTexture::__Client; Client->Shadows = 0; Client->FrameFXDisabled = 1; @@ -45,6 +45,7 @@ UBOOL URtxRenderDevice::Init() void URtxRenderDevice::Flush(UViewport* Viewport) { + ClearMaterialFlags(); Super::Flush(Viewport); } @@ -89,6 +90,7 @@ void FRtxRenderInterface::SetTransform(ETransformType Type, const FMatrix& Matri void FRtxRenderInterface::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) { + guardFunc; CurrentMaterial = Material; UMaterial* ActualMaterial = Material; @@ -101,9 +103,11 @@ void FRtxRenderInterface::SetMaterial(UMaterial* Material, FString* ErrorString, CurrentActualMaterial = ActualMaterial; - if(ActualMaterial && !ActualMaterial->UseFallback) + INT Mask = (reinterpret_cast(ActualMaterial)[24] & 0x3) >> 2; + + if(ActualMaterial && (Mask & 0x1) == 0) { - ActualMaterial->UseFallback = 1; + Mask |= 0x1; if(ActualMaterial->GetFName() != NAME_InGameTempName) { @@ -112,16 +116,19 @@ void FRtxRenderInterface::SetMaterial(UMaterial* Material, FString* ErrorString, { if(RenDev->MaterialIdsByPath[i].Path == Path) { - reinterpret_cast(ActualMaterial)[24] = (reinterpret_cast(ActualMaterial)[24] & 0x3) | ((i + 1) << 3); + Mask |= (i + 1) << 1; break; } } } + + reinterpret_cast(ActualMaterial)[24] = (reinterpret_cast(ActualMaterial)[24] & 0x3) | (Mask << 2); } DrawParticleTriangles = ActualMaterial && (reinterpret_cast(ActualMaterial)[24] >> 3) != 0; Impl->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); + unguardf(("%s", Material->GetPathName())) } void FRtxRenderInterface::DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex, INT MaxIndex) @@ -156,3 +163,11 @@ FRenderCaps* URtxRenderDevice::GetRenderCaps() return &RenderCaps; } + +void URtxRenderDevice::ClearMaterialFlags() +{ + foreachobj(UMaterial, Material) + { + reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); + } +} diff --git a/RtxDrv/Src/RtxDrv.h b/RtxDrv/Src/RtxDrv.h index 833ba3d4..fbdd416d 100644 --- a/RtxDrv/Src/RtxDrv.h +++ b/RtxDrv/Src/RtxDrv.h @@ -129,6 +129,9 @@ class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ }; TArray MaterialIdsByPath; + +private: + void ClearMaterialFlags(); }; #endif // RTXDRV_NATIVE_DEFS From 8e910eb945248cf4555c4f891e4cd8d90a04be0f Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 30 Jul 2024 02:56:59 +0200 Subject: [PATCH 08/48] Place lights for projectiles using remix bridge api --- Core/Inc/UnVcWin32.h | 4 + ModEd/Src/ModEd.cpp | 44 +++ RtxDrv/Classes/Rtx.uc | 3 + RtxDrv/Inc/RtxDrvClasses.h | 44 +++ RtxDrv/RtxDrv.vcproj | 13 +- RtxDrv/Src/RtxDrv.cpp | 173 --------- RtxDrv/Src/RtxDrvClasses.cpp | 18 + RtxDrv/Src/RtxDrvPrivate.h | 2 + RtxDrv/Src/RtxRenderDevice.cpp | 220 +++++++++++ RtxDrv/Src/{RtxDrv.h => RtxRenderDevice.h} | 66 ++-- RtxDrv/Src/bridge_c.h | 409 +++++++++++++++++++++ UCC/UCC.ini | 1 + 12 files changed, 788 insertions(+), 209 deletions(-) create mode 100644 RtxDrv/Classes/Rtx.uc create mode 100644 RtxDrv/Inc/RtxDrvClasses.h delete mode 100644 RtxDrv/Src/RtxDrv.cpp create mode 100644 RtxDrv/Src/RtxDrvClasses.cpp create mode 100644 RtxDrv/Src/RtxDrvPrivate.h create mode 100644 RtxDrv/Src/RtxRenderDevice.cpp rename RtxDrv/Src/{RtxDrv.h => RtxRenderDevice.h} (90%) create mode 100644 RtxDrv/Src/bridge_c.h diff --git a/Core/Inc/UnVcWin32.h b/Core/Inc/UnVcWin32.h index 6dc5ed4d..0aa133f3 100644 --- a/Core/Inc/UnVcWin32.h +++ b/Core/Inc/UnVcWin32.h @@ -3,6 +3,8 @@ Copyright 1997-1999 Epic Games, Inc. All Rights Reserved. =============================================================================*/ +#pragma once + /*---------------------------------------------------------------------------- Platform compiler definitions. ----------------------------------------------------------------------------*/ @@ -15,6 +17,8 @@ Platform specifics types and defines. ----------------------------------------------------------------------------*/ +#define WINVER 0x501 +#define _WIN32_WINNT 0x501 #include #include diff --git a/ModEd/Src/ModEd.cpp b/ModEd/Src/ModEd.cpp index 1bdc40d5..f30a90b9 100644 --- a/ModEd/Src/ModEd.cpp +++ b/ModEd/Src/ModEd.cpp @@ -71,6 +71,33 @@ static WWindow* GetMainWindow() return *reinterpret_cast(0x10FE39D4); } +static WNDPROC OriginalMainWindowProc = NULL; + +LRESULT CALLBACK MainWindowProcOverride(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if(Msg == WM_INPUT) + { + RAWINPUT RawInput; + UINT RawInputSize = sizeof(RawInput); + + if(GET_RAWINPUT_CODE_WPARAM(wParam) != RIM_INPUT) + return 0; + + if(GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, &RawInput, &RawInputSize, sizeof(RAWINPUTHEADER)) != (UINT)-1) + { + if(RawInput.header.dwType == RIM_TYPEMOUSE) + { + + } + } + + DefWindowProcA(hWnd, Msg, wParam, lParam); + return 0; + } + + return OriginalMainWindowProc(hWnd, Msg, wParam, lParam); +} + static void(__fastcall*OriginalUUnrealEdEngineTick)(UEditorEngine*, DWORD, FLOAT) = NULL; /* @@ -112,6 +139,22 @@ static void __fastcall UnrealEdEngineTickOverride(UEditorEngine* Self, DWORD Edx SendMessageA(GetMainWindow()->hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); } + OriginalMainWindowProc = reinterpret_cast(GetWindowLongA(GetMainWindow()->hWnd, GWLP_WNDPROC)); + SetWindowLongA(GetMainWindow()->hWnd, GWLP_WNDPROC, reinterpret_cast(MainWindowProcOverride)); + +#ifndef HID_USAGE_PAGE_GENERIC +#define HID_USAGE_PAGE_GENERIC ((USHORT)0x01) +#define HID_USAGE_GENERIC_MOUSE ((USHORT)0x02) +#endif + + RAWINPUTDEVICE RawInput; + RawInput.usUsagePage = HID_USAGE_PAGE_GENERIC; + RawInput.usUsage = HID_USAGE_GENERIC_MOUSE; + RawInput.dwFlags = 0; + RawInput.hwndTarget = GetMainWindow()->hWnd; + + RegisterRawInputDevices(&RawInput, 1, sizeof(RAWINPUTDEVICE)); + // Restore original tick function now that the initial setup is done. PatchVTable(Self, 32, OriginalUUnrealEdEngineTick); } @@ -167,5 +210,6 @@ DLL_EXPORT void ModEdInit(const TCHAR* InPackage, const TCHAR* InCmdLine, FOutpu InitSWRCFix(); + // Hook UUnrealEdEngine::Tick for initialization OriginalUUnrealEdEngineTick = static_cast(PatchDllClassVTable(*(FString(appPackage()) + ".exe"), "UUnrealEdEngine", "UObject", 32, UnrealEdEngineTickOverride)); } diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc new file mode 100644 index 00000000..4e07f6dc --- /dev/null +++ b/RtxDrv/Classes/Rtx.uc @@ -0,0 +1,3 @@ +class Rtx extends Object native; + +native static final function TestFunc(); diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h new file mode 100644 index 00000000..23af0e26 --- /dev/null +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -0,0 +1,44 @@ +/*=========================================================================== + C++ class definitions exported from UnrealScript. + This is automatically generated by the tools. + DO NOT modify this manually! Edit the corresponding .uc files instead! +===========================================================================*/ + +#ifndef RTXDRV_NATIVE_DEFS +#define RTXDRV_NATIVE_DEFS + +#if SUPPORTS_PRAGMA_PACK +#pragma pack (push,4) +#endif + +#ifndef RTXDRV_API +#define RTXDRV_API DLL_IMPORT +#endif + + + +class RTXDRV_API URtx : public UObject +{ +public: + void execTestFunc(FFrame& Stack, void* Result); + DECLARE_CLASS(URtx,UObject,0,RtxDrv) + NO_DEFAULT_CONSTRUCTOR(URtx) + DECLARE_NATIVES(URtx) +}; + + + +#if SUPPORTS_PRAGMA_PACK +#pragma pack (pop) +#endif + +#if __STATIC_LINK + +#define AUTO_INITIALIZE_REGISTRANTS_RTXDRV \ + UConstantColorMaterial::StaticClass(); \ + URtx::StaticClass(); \ + URtxRenderDevice::StaticClass(); \ + +#endif // __STATIC_LINK + +#endif // CORE_NATIVE_DEFS diff --git a/RtxDrv/RtxDrv.vcproj b/RtxDrv/RtxDrv.vcproj index 9db69304..96a2fdd7 100644 --- a/RtxDrv/RtxDrv.vcproj +++ b/RtxDrv/RtxDrv.vcproj @@ -95,16 +95,25 @@ + + + RelativePath=".\Src\RtxDrvPrivate.h"> + + + + + RelativePath=".\Src\RtxDrvClasses.cpp"> diff --git a/RtxDrv/Src/RtxDrv.cpp b/RtxDrv/Src/RtxDrv.cpp deleted file mode 100644 index 998c9e1b..00000000 --- a/RtxDrv/Src/RtxDrv.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "RtxDrv.h" - -IMPLEMENT_PACKAGE(RtxDrv) -IMPLEMENT_CLASS(URtxRenderDevice) - -UBOOL URtxRenderDevice::Init() -{ - // Init SWRCFix if it exists. Hacky but RenderDevice is always loaded at startup... - HMODULE ModDLL = LoadLibraryA("Mod.dll"); - - if(ModDLL) - { - void(CDECL*InitSWRCFix)(void) = reinterpret_cast(GetProcAddress(ModDLL, "InitSWRCFix")); - - if(InitSWRCFix) - InitSWRCFix(); - } - - FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 0, 1, StaticConfigName()); - - if(Section) - { - for(FConfigSection::TIterator It(*Section); It; ++It) - { - const INT Id = appAtoi(*It.Value()); - MaterialIdsByPath.AddItem(TestDraw(Id, *It.Key())); - } - } - - RenderInterface.RenDev = this; - RenderInterface.Impl = NULL; - - ClearMaterialFlags(); - UClient* Client = UTexture::__Client; - Client->Shadows = 0; - Client->FrameFXDisabled = 1; - Client->BloomQuality = 0; - Client->BlurEnabled = 0; - Client->BumpmappingQuality = 0; - GetDefault()->bVisor = 0; - GetDefault()->VisorModeDefault = 1; - UseStencil = 0; - return Super::Init(); -} - -void URtxRenderDevice::Flush(UViewport* Viewport) -{ - ClearMaterialFlags(); - Super::Flush(Viewport); -} - -FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) -{ - RenderInterface.Impl = Super::Lock(Viewport, HitData, HitSize); - return RenderInterface.Impl ? &RenderInterface : NULL; -} - -class RTXDRV_API UConstantColorMaterial : public UConstantMaterial{ -public: - DECLARE_CLASS(UConstantColorMaterial,UConstantMaterial,0,RtxDrv) - virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0); } -}; -IMPLEMENT_CLASS(UConstantColorMaterial) - -void URtxRenderDevice::Unlock(FRenderInterface* RI) -{ - static bool Exited = false; - - if(!Exited && GIsRequestingExit) - { - Exited = true; - FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 1, 0, StaticConfigName()); - check(Section); - - for(TArray::TIterator It(MaterialIdsByPath); It; ++It) - { - FConfigString& Value = (*Section)[It->Path]; - Value = appItoa(It->Id); - Value.Dirty = true; - } - } - - Super::Unlock(static_cast(RI)->Impl); -} - -void FRtxRenderInterface::SetTransform(ETransformType Type, const FMatrix& Matrix) -{ - Impl->SetTransform(Type, Matrix); -} - -void FRtxRenderInterface::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) -{ - guardFunc; - CurrentMaterial = Material; - - UMaterial* ActualMaterial = Material; - - while(ActualMaterial && ActualMaterial->IsA()) - ActualMaterial = static_cast(ActualMaterial)->Material; - - if(ActualMaterial && ActualMaterial->IsA()) - ActualMaterial = static_cast(ActualMaterial)->BitmapMaterial; - - CurrentActualMaterial = ActualMaterial; - - INT Mask = (reinterpret_cast(ActualMaterial)[24] & 0x3) >> 2; - - if(ActualMaterial && (Mask & 0x1) == 0) - { - Mask |= 0x1; - - if(ActualMaterial->GetFName() != NAME_InGameTempName) - { - const TCHAR* Path = ActualMaterial->GetPathName(); - for(INT i = 0; i < RenDev->MaterialIdsByPath.Num(); ++i) - { - if(RenDev->MaterialIdsByPath[i].Path == Path) - { - Mask |= (i + 1) << 1; - break; - } - } - } - - reinterpret_cast(ActualMaterial)[24] = (reinterpret_cast(ActualMaterial)[24] & 0x3) | (Mask << 2); - } - - DrawParticleTriangles = ActualMaterial && (reinterpret_cast(ActualMaterial)[24] >> 3) != 0; - - Impl->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); - unguardf(("%s", Material->GetPathName())) -} - -void FRtxRenderInterface::DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex, INT MaxIndex) -{ - Impl->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); - - if(DrawParticleTriangles) - { - DECLARE_STATIC_UOBJECT(UConstantColorMaterial, TestConstantColorMaterial, {}); - DECLARE_STATIC_UOBJECT(UFinalBlend, TestFinalBlend, { - TestFinalBlend->Material = TestConstantColorMaterial; - }); - - PushState(); - - Impl->SetCullMode(CM_None); - Impl->SetMaterial(TestFinalBlend); - FVertexStream* TestStreamPtr = &RenDev->MaterialIdsByPath[(reinterpret_cast(CurrentActualMaterial)[24] >> 3) - 1].Stream; - Impl->SetVertexStreams(VS_FixedFunction, &TestStreamPtr, 1); - Impl->SetIndexBuffer(NULL, 0); - Impl->DrawPrimitive(PT_TriangleList, 0, 1); - Impl->SetMaterial(CurrentMaterial); - - PopState(); - } -} - -FRenderCaps* URtxRenderDevice::GetRenderCaps() -{ - /* return Super::GetRenderCaps(); */ - static FRenderCaps RenderCaps(1, 14, 1); - - return &RenderCaps; -} - -void URtxRenderDevice::ClearMaterialFlags() -{ - foreachobj(UMaterial, Material) - { - reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); - } -} diff --git a/RtxDrv/Src/RtxDrvClasses.cpp b/RtxDrv/Src/RtxDrvClasses.cpp new file mode 100644 index 00000000..67367eda --- /dev/null +++ b/RtxDrv/Src/RtxDrvClasses.cpp @@ -0,0 +1,18 @@ +/*=========================================================================== + C++ class definitions exported from UnrealScript. + This is automatically generated by the tools. + DO NOT modify this manually! Edit the corresponding .uc files instead! +===========================================================================*/ + +#include "RtxDrvPrivate.h" + +IMPLEMENT_PACKAGE(RtxDrv) + + + +IMPLEMENT_CLASS(URtx); +FNativeEntry URtx::StaticNativeMap[] = { + MAP_NATIVE(TestFunc,0) + {NULL,NULL} +}; +LINK_NATIVES(URtx); diff --git a/RtxDrv/Src/RtxDrvPrivate.h b/RtxDrv/Src/RtxDrvPrivate.h new file mode 100644 index 00000000..e97e8875 --- /dev/null +++ b/RtxDrv/Src/RtxDrvPrivate.h @@ -0,0 +1,2 @@ +#include "Core.h" +#include "../Inc/RtxDrvClasses.h" diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp new file mode 100644 index 00000000..64e09668 --- /dev/null +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -0,0 +1,220 @@ +#include "RtxDrvPrivate.h" +#include "RtxRenderDevice.h" + +IMPLEMENT_CLASS(URtxRenderDevice) + +UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) +{ + return Super::Exec(Cmd, Ar); +} + +UBOOL URtxRenderDevice::Init() +{ + // Init SWRCFix if it exists. Hacky but RenderDevice is always loaded at startup... + HMODULE ModDLL = LoadLibraryA("Mod.dll"); + + if(ModDLL) + { + void(CDECL*InitSWRCFix)(void) = reinterpret_cast(GetProcAddress(ModDLL, "InitSWRCFix")); + + if(InitSWRCFix) + InitSWRCFix(); + } + + FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 0, 1, StaticConfigName()); + + if(Section) + { + for(FConfigSection::TIterator It(*Section); It; ++It) + { + const INT Id = appAtoi(*It.Value()); + RenderInterface.MaterialIdsByPath.AddItem(FRtxRenderInterface::MaterialId(Id, *It.Key())); + } + } + + RenderInterface.RenDev = this; + RenderInterface.Impl = NULL; + + ClearMaterialFlags(); + UClient* Client = UTexture::__Client; + Client->Shadows = 0; + Client->FrameFXDisabled = 1; + Client->BloomQuality = 0; + Client->BlurEnabled = 0; + Client->BumpmappingQuality = 0; + GetDefault()->bVisor = 0; + GetDefault()->VisorModeDefault = 1; + UseStencil = 0; + + return Super::Init(); +} + +UBOOL URtxRenderDevice::SetRes(UViewport* Viewport, INT NewX, INT NewY, UBOOL Fullscreen, INT ColorBytes, UBOOL bSaveSize) +{ + UBOOL Result = Super::SetRes(Viewport, NewX, NewY, Fullscreen, ColorBytes, bSaveSize); + + if(Result && !BridgeInterface.initialized) + { + if(bridgeapi_initialize(&BridgeInterface) != BRIDGEAPI_ERROR_CODE_SUCCESS || !BridgeInterface.initialized) + { + appErrorf("Failed to initialize remix bridge API"); + return 0; + } + + BridgeInterface.RegisterDevice(); + } + + return Result; +} + +void URtxRenderDevice::Flush(UViewport* Viewport) +{ + ClearMaterialFlags(); + Super::Flush(Viewport); +} + +UBOOL GFirstClear = 0; +FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) +{ + if(Viewport->Actor) + { + Viewport->Actor->bVisor = 0; + Viewport->Actor->VisorModeDefault = 1; + } + + GFirstClear = 0; + RenderInterface.Impl = Super::Lock(Viewport, HitData, HitSize); + return RenderInterface.Impl ? &RenderInterface : NULL; +} + +struct FLightHandle{ + uint64_t Handle; + UBOOL bUsed; +}; +class RTXDRV_API UConstantColorMaterial : public UConstantMaterial{ +public: + DECLARE_CLASS(UConstantColorMaterial,UConstantMaterial,0,RtxDrv) + virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0); } +}; +IMPLEMENT_CLASS(UConstantColorMaterial) + +void URtxRenderDevice::Unlock(FRenderInterface* RI) +{ + static bool Exited = false; + + if(!Exited && GIsRequestingExit) + { + Exited = true; + FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 1, 0, StaticConfigName()); + check(Section); + + for(TArray::TIterator It(RenderInterface.MaterialIdsByPath); It; ++It) + { + FConfigString& Value = (*Section)[It->Path]; + Value = appItoa(It->Id); + Value.Dirty = true; + } + } + + typedef TMap FHandleMap; + static FHandleMap HandleMap; + + foreach(AllActors, AProjectile, Proj, static_cast(GEngine)->GLevel) + { + FLightHandle* HandlePtr = HandleMap.Find(*Proj); + + if(HandlePtr) + BridgeInterface.DestroyLight(HandlePtr->Handle); + else + HandlePtr = &HandleMap[*Proj]; + + x86::remixapi_LightInfo l; + l.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO; + l.hash = reinterpret_cast(*Proj); + + FPlane Col = FGetHSV(Proj->LightHue, Proj->LightSaturation, Proj->LightBrightness) * 10000; + + l.radiance.x = Col.X; + l.radiance.y = Col.Y; + l.radiance.z = Col.Z; + + FVector Loc = Proj->Location; + x86::remixapi_LightInfoSphereEXT s; + s.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT; + s.position.x = Loc.X; + s.position.y = Loc.Y; + s.position.z = Loc.Z; + s.radius = 5.0f; + s.shaping_hasvalue = FALSE; + s.shaping_value.direction.x = 0.0f; + s.shaping_value.direction.y = 1.0f; + s.shaping_value.direction.z = 0.0f; + s.shaping_value.coneAngleDegrees = 80.0f; + s.shaping_value.coneSoftness = 1.0f; + s.shaping_value.focusExponent = 0.0f; + + HandlePtr->bUsed = 1; + HandlePtr->Handle = BridgeInterface.CreateSphereLight(&l, &s); + BridgeInterface.DrawLightInstance(HandlePtr->Handle); + } + + for(FHandleMap::TIterator It(HandleMap); It; ++It) + { + if(!It->bUsed) + HandleMap.Remove(It.Key()); + else + It->bUsed = 0; + } + + Super::Unlock(static_cast(RI)->Impl); +} + +void URtxRenderDevice::Present(UViewport* Viewport) +{ + Super::Present(Viewport); +} + +FRenderCaps* URtxRenderDevice::GetRenderCaps() +{ + /* return Super::GetRenderCaps(); */ + static FRenderCaps RenderCaps(1, 14, 1); + + return &RenderCaps; +} + +UBOOL FRtxRenderInterface::SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer) +{ + debugf("SETRENDERTARGET: %p", RenderTarget); + return Impl->SetRenderTarget(RenderTarget, bOwnDepthBuffer); +} + +void FRtxRenderInterface::Clear(UBOOL UseColor, FColor Color, UBOOL UseDepth, FLOAT Depth, UBOOL UseStencil, DWORD Stencil) +{ + Impl->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); +} + +void FRtxRenderInterface::SetTransform(ETransformType Type, const FMatrix& Matrix) +{ + Impl->SetTransform(Type, Matrix); +} + +void FRtxRenderInterface::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) +{ + Impl->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); +} + +void FRtxRenderInterface::DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex, INT MaxIndex) +{ + Impl->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); +} + +void URtxRenderDevice::ClearMaterialFlags() +{ + foreachobj(UMaterial, Material) + reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); +} + +void URtx::execTestFunc(FFrame& Stack, void* Result) +{ + +} diff --git a/RtxDrv/Src/RtxDrv.h b/RtxDrv/Src/RtxRenderDevice.h similarity index 90% rename from RtxDrv/Src/RtxDrv.h rename to RtxDrv/Src/RtxRenderDevice.h index fbdd416d..3df1c7cc 100644 --- a/RtxDrv/Src/RtxDrv.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -1,7 +1,7 @@ -#ifndef RTXDRV_NATIVE_DEFS -#define RTXDRV_NATIVE_DEFS +#pragma once #include "../../D3DDrv/Inc/D3DDrv.h" +#include "bridge_c.h" #ifndef RTXDRV_API #define RTXDRV_API DLL_IMPORT @@ -43,28 +43,23 @@ class FRtxRenderInterface : public FRenderInterface{ URtxRenderDevice* RenDev; FRenderInterface* Impl; - UBOOL DrawParticleTriangles; - UMaterial* CurrentMaterial; - UMaterial* CurrentActualMaterial; - virtual void PushState(DWORD Flags = 0){ Impl->PushState(Flags); } virtual void PopState(DWORD Flags = 0){ Impl->PopState(Flags); } - virtual UBOOL SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer){ - return Impl->SetRenderTarget(RenderTarget, bOwnDepthBuffer); - } + virtual UBOOL SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer); virtual UBOOL SetCubeRenderTarget(class FDynamicCubemap* Target, int A, int B){ return Impl->SetCubeRenderTarget(Target, A, B); } virtual void SetViewport(INT X, INT Y, INT Width, INT Height){ Impl->SetViewport(X, Y, Width, Height); } - virtual void Clear(UBOOL UseColor = 1, FColor Color = FColor(0, 0, 0), UBOOL UseDepth = 1, FLOAT Depth = 1.0f, UBOOL UseStencil = 1, DWORD Stencil = 0){ - Impl->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); - } + virtual void Clear(UBOOL UseColor = 1, FColor Color = FColor(0, 0, 0), UBOOL UseDepth = 1, FLOAT Depth = 1.0f, UBOOL UseStencil = 1, DWORD Stencil = 0); virtual void PushHit(const BYTE* Data, INT Count){ Impl->PushHit(Data, Count); } virtual void PopHit(INT Count, UBOOL Force){ Impl->PopHit(Count, Force); } virtual void SetCullMode(ECullMode CullMode){ Impl->SetCullMode(CullMode); } - virtual void SetAmbientLight(FColor Color){ Impl->SetAmbientLight(Color); } + virtual void SetAmbientLight(FColor Color){} virtual void EnableLighting(UBOOL UseDynamic, UBOOL UseStatic = 1, UBOOL Modulate2X = 0, FBaseTexture* Lightmap = NULL, UBOOL LightingOnly = 0, const FSphere& LitSphere = FSphere(FVector(0, 0, 0), 0), int IntValue = 0){ + UseDynamic = 0; + Lightmap = NULL; + Modulate2X = 0; Impl->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); } - virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetLight(LightIndex, Light, Scale); } + virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){} virtual void SetShaderLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetShaderLight(LightIndex, Light, Scale); } virtual void SetNPatchTesselation(FLOAT Tesselation){ Impl->SetNPatchTesselation(Tesselation); } virtual void SetDistanceFog(UBOOL Enable, FLOAT FogStart, FLOAT FogEnd, FColor Color){ Impl->SetDistanceFog(Enable, FogStart, FogEnd, Color); } @@ -92,26 +87,13 @@ class FRtxRenderInterface : public FRenderInterface{ virtual INT SetDynamicIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetDynamicIndexBuffer(IndexBuffer, BaseIndex); } virtual void DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex = INDEX_NONE, INT MaxIndex = INDEX_NONE); virtual void SetFillMode(EFillMode FillMode){ Impl->SetFillMode(FillMode); } -}; - -class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ - DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) - static const TCHAR* StaticConfigName(){ return "RtxDrv"; } -public: - FRtxRenderInterface RenderInterface; - - virtual UBOOL Init(); - virtual void Flush(UViewport* Viewport); - virtual FRenderInterface* Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize); - virtual void Unlock(FRenderInterface* RI); - virtual FRenderCaps* GetRenderCaps(); - struct TestDraw{ - INT Id; + struct MaterialId{ + INT Id; FSingleTriangleVertexStream Stream; - FString Path; + FString Path; - TestDraw(INT InId = 0, const TCHAR* InPath = NULL) + MaterialId(INT InId = 0, const TCHAR* InPath = NULL) : Id(InId), Stream(InId + 32, InId + 32), Path(InPath) @@ -128,10 +110,26 @@ class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ } }; - TArray MaterialIdsByPath; + TArray MaterialIdsByPath; +}; + +class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ + DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) + static const TCHAR* StaticConfigName(){ return "RtxDrv"; } +public: + FRtxRenderInterface RenderInterface; + + virtual UBOOL Exec(const TCHAR* Cmd, FOutputDevice& Ar); + virtual UBOOL Init(); + virtual UBOOL SetRes(UViewport* Viewport, INT NewX, INT NewY, UBOOL Fullscreen, INT ColorBytes = 0, UBOOL bSaveSize = true); + virtual void Flush(UViewport* Viewport); + virtual FRenderInterface* Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize); + virtual void Unlock(FRenderInterface* RI); + virtual void Present(UViewport* Viewport); + virtual FRenderCaps* GetRenderCaps(); private: + bridgeapi_Interface BridgeInterface; + void ClearMaterialFlags(); }; - -#endif // RTXDRV_NATIVE_DEFS diff --git a/RtxDrv/Src/bridge_c.h b/RtxDrv/Src/bridge_c.h new file mode 100644 index 00000000..aec283a9 --- /dev/null +++ b/RtxDrv/Src/bridge_c.h @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +// Bridge API header for both the x86 bridge client and the x86 game + +#ifndef BRIDGE_C_H_ +#define BRIDGE_C_H_ + +#include "UnVcWin32.h" + +typedef BYTE uint8_t; +typedef INT int32_t; +typedef DWORD uint32_t; +typedef QWORD uint64_t; +#define nullptr NULL + +#define BRIDGEAPI_CALL __stdcall +#define BRIDGEAPI_PTR BRIDGEAPI_CALL + +#ifdef BRIDGE_API_IMPORT + #define BRIDGE_API __declspec(dllimport) +#else + #define BRIDGE_API __declspec(dllexport) +#endif + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + typedef enum bridgeapi_ErrorCode { + BRIDGEAPI_ERROR_CODE_SUCCESS = 0, + BRIDGEAPI_ERROR_CODE_GENERAL_FAILURE = 1, + // WinAPI's GetModuleHandle has failed + BRIDGEAPI_ERROR_CODE_GET_MODULE_HANDLE_FAILURE = 2, + BRIDGEAPI_ERROR_CODE_INVALID_ARGUMENTS = 3, + // Couldn't find 'remixInitialize' function in the .dll + BRIDGEAPI_ERROR_CODE_GET_PROC_ADDRESS_FAILURE = 4, + // CreateD3D9 / RegisterD3D9Device can be called only once + BRIDGEAPI_ERROR_CODE_ALREADY_EXISTS = 5, + // RegisterD3D9Device requires the device that was created with IDirect3DDevice9Ex, returned by CreateD3D9 + BRIDGEAPI_ERROR_CODE_REGISTERING_NON_REMIX_D3D9_DEVICE = 6, + // RegisterD3D9Device was not called + BRIDGEAPI_ERROR_CODE_REMIX_DEVICE_WAS_NOT_REGISTERED = 7, + BRIDGEAPI_ERROR_CODE_INCOMPATIBLE_VERSION = 8, + // WinAPI's SetDllDirectory has failed + //BRIDGEAPI_ERROR_CODE_SET_DLL_DIRECTORY_FAILURE = 9, + // WinAPI's GetFullPathName has failed + //BRIDGEAPI_ERROR_CODE_GET_FULL_PATH_NAME_FAILURE = 10, + BRIDGEAPI_ERROR_CODE_NOT_INITIALIZED = 11, + } BRIDGEAPI_ErrorCode; + + // ------------------------------------------ + // <- remix api types from the remix_c header + + typedef enum remixapi_StructType { + REMIXAPI_STRUCT_TYPE_NONE = 0, + REMIXAPI_STRUCT_TYPE_INITIALIZE_LIBRARY_INFO = 1, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO = 2, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_PORTAL_EXT = 3, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_TRANSLUCENT_EXT = 4, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_OPAQUE_EXT = 5, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO = 6, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT = 7, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT = 8, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT = 9, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT = 10, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT = 11, + REMIXAPI_STRUCT_TYPE_MESH_INFO = 12, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO = 13, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_BONE_TRANSFORMS_EXT = 14, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_BLEND_EXT = 15, + REMIXAPI_STRUCT_TYPE_CAMERA_INFO = 16, + REMIXAPI_STRUCT_TYPE_CAMERA_INFO_PARAMETERIZED_EXT = 17, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_OPAQUE_SUBSURFACE_EXT = 18, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_OBJECT_PICKING_EXT = 19, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DOME_EXT = 20, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_USD_EXT = 21, + REMIXAPI_STRUCT_TYPE_STARTUP_INFO = 22, + REMIXAPI_STRUCT_TYPE_PRESENT_INFO = 23, + // NOTE: if adding a new struct, register it in 'rtx_remix_specialization.inl' + } remixapi_StructType; + + namespace x86 + { + typedef uint32_t remixapi_Bool; + + typedef struct remixapi_Rect2D { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; + } remixapi_Rect2D; + + typedef struct remixapi_Float2D { + float x; + float y; + } remixapi_Float2D; + + typedef struct remixapi_Float3D { + float x; + float y; + float z; + } remixapi_Float3D; + + typedef struct remixapi_Float4D { + float x; + float y; + float z; + float w; + } remixapi_Float4D; + + typedef struct remixapi_Transform { + float matrix[3][4]; + } remixapi_Transform; + + //typedef struct remixapi_MaterialHandle_T* remixapi_MaterialHandle; + //typedef struct remixapi_MeshHandle_T* remixapi_MeshHandle; + //typedef struct remixapi_LightHandle_T* remixapi_LightHandle; + + typedef const wchar_t* remixapi_Path; + + typedef struct remixapi_MaterialInfoOpaqueEXT { + remixapi_StructType sType; + //void* pNext; + remixapi_Path roughnessTexture; + remixapi_Path metallicTexture; + float anisotropy; + remixapi_Float3D albedoConstant; + float opacityConstant; + float roughnessConstant; + float metallicConstant; + remixapi_Bool thinFilmThickness_hasvalue; + float thinFilmThickness_value; + remixapi_Bool alphaIsThinFilmThickness; + remixapi_Path heightTexture; + float heightTextureStrength; + // If true, InstanceInfoBlendEXT is used as a source for alpha state + remixapi_Bool useDrawCallAlphaState; + remixapi_Bool blendType_hasvalue; + int blendType_value; + remixapi_Bool invertedBlend; + int alphaTestType; + uint8_t alphaReferenceValue; + } remixapi_MaterialInfoOpaqueEXT; + + // Valid only if remixapi_MaterialInfo contains remixapi_MaterialInfoOpaqueEXT in pNext chain + typedef struct remixapi_MaterialInfoOpaqueSubsurfaceEXT { + remixapi_StructType sType; + //void* pNext; + remixapi_Path subsurfaceTransmittanceTexture; + remixapi_Path subsurfaceThicknessTexture; + remixapi_Path subsurfaceSingleScatteringAlbedoTexture; + remixapi_Float3D subsurfaceTransmittanceColor; + float subsurfaceMeasurementDistance; + remixapi_Float3D subsurfaceSingleScatteringAlbedo; + float subsurfaceVolumetricAnisotropy; + } remixapi_MaterialInfoOpaqueSubsurfaceEXT; + + typedef struct remixapi_MaterialInfoTranslucentEXT { + remixapi_StructType sType; + //void* pNext; + remixapi_Path transmittanceTexture; + float refractiveIndex; + remixapi_Float3D transmittanceColor; + float transmittanceMeasurementDistance; + remixapi_Bool thinWallThickness_hasvalue; + float thinWallThickness_value; + remixapi_Bool useDiffuseLayer; + } remixapi_MaterialInfoTranslucentEXT; + + typedef struct remixapi_MaterialInfoPortalEXT { + remixapi_StructType sType; + //void* pNext; + uint8_t rayPortalIndex; + float rotationSpeed; + } remixapi_MaterialInfoPortalEXT; + + typedef struct remixapi_MaterialInfo { + remixapi_StructType sType; + //void* pNext; + uint64_t hash; + remixapi_Path albedoTexture; + remixapi_Path normalTexture; + remixapi_Path tangentTexture; + remixapi_Path emissiveTexture; + float emissiveIntensity; + remixapi_Float3D emissiveColorConstant; + uint8_t spriteSheetRow; + uint8_t spriteSheetCol; + uint8_t spriteSheetFps; + uint8_t filterMode; // Nearest: 0 Linear: 1 + uint8_t wrapModeU; // Clamp: 0 Repeat: 1 Mirrored_Repeat: 2 Clip: 3 + uint8_t wrapModeV; // Clamp: 0 Repeat: 1 Mirrored_Repeat: 2 Clip: 3 + } remixapi_MaterialInfo; + + + typedef struct remixapi_HardcodedVertex { + float position[3]; + float normal[3]; + float texcoord[2]; + uint32_t color; + uint32_t _pad0; + uint32_t _pad1; + uint32_t _pad2; + uint32_t _pad3; + uint32_t _pad4; + uint32_t _pad5; + uint32_t _pad6; + } remixapi_HardcodedVertex; + + // # TODO remixapi_MeshInfoSkinning + + typedef struct remixapi_MeshInfoSurfaceTriangles { + const remixapi_HardcodedVertex* vertices_values; + uint64_t vertices_count; + const uint32_t* indices_values; + uint64_t indices_count; + remixapi_Bool skinning_hasvalue; + //remixapi_MeshInfoSkinning skinning_value; // # TODO + uint64_t material; // CHANGED - was remixapi_MaterialHandle + } remixapi_MeshInfoSurfaceTriangles; + + typedef struct remixapi_MeshInfo { + remixapi_StructType sType; + //void* pNext; + uint64_t hash; + const remixapi_MeshInfoSurfaceTriangles* surfaces_values; + uint32_t surfaces_count; + } remixapi_MeshInfo; + + + typedef struct remixapi_LightInfoLightShaping { + // The direction the Light Shaping is pointing in. Must be normalized. + remixapi_Float3D direction; + float coneAngleDegrees; + float coneSoftness; + float focusExponent; + } remixapi_LightInfoLightShaping; + + typedef struct remixapi_LightInfoSphereEXT { + remixapi_StructType sType; + //void* pNext; + remixapi_Float3D position; + float radius; + remixapi_Bool shaping_hasvalue; + remixapi_LightInfoLightShaping shaping_value; + } remixapi_LightInfoSphereEXT; + + typedef struct remixapi_LightInfoRectEXT { + remixapi_StructType sType; + //void* pNext; + remixapi_Float3D position; + // The X axis of the Rect Light. Must be normalized and orthogonal to the Y and direction axes. + remixapi_Float3D xAxis; + float xSize; + // The Y axis of the Rect Light. Must be normalized and orthogonal to the X and direction axes. + remixapi_Float3D yAxis; + float ySize; + // The direction the Rect Light is pointing in, should match the Shaping direction if present. + // Must be normalized and orthogonal to the X and Y axes. + remixapi_Float3D direction; + remixapi_Bool shaping_hasvalue; + remixapi_LightInfoLightShaping shaping_value; + } remixapi_LightInfoRectEXT; + + typedef struct remixapi_LightInfoDiskEXT { + remixapi_StructType sType; + //void* pNext; + remixapi_Float3D position; + // The X axis of the Disk Light. Must be normalized and orthogonal to the Y and direction axes. + remixapi_Float3D xAxis; + float xRadius; + // The Y axis of the Disk Light. Must be normalized and orthogonal to the X and direction axes. + remixapi_Float3D yAxis; + float yRadius; + // The direction the Disk Light is pointing in, should match the Shaping direction if present + // Must be normalized and orthogonal to the X and Y axes. + remixapi_Float3D direction; + remixapi_Bool shaping_hasvalue; + remixapi_LightInfoLightShaping shaping_value; + } remixapi_LightInfoDiskEXT; + + typedef struct remixapi_LightInfoCylinderEXT { + remixapi_StructType sType; + //void* pNext; + remixapi_Float3D position; + float radius; + // The "center" axis of the Cylinder Light. Must be normalized. + remixapi_Float3D axis; + float axisLength; + } remixapi_LightInfoCylinderEXT; + + typedef struct remixapi_LightInfoDistantEXT { + remixapi_StructType sType; + //void* pNext; + // The direction the Distant Light is pointing in. Must be normalized. + remixapi_Float3D direction; + float angularDiameterDegrees; + } remixapi_LightInfoDistantEXT; + + typedef struct remixapi_LightInfo { + remixapi_StructType sType; + //void* pNext; + uint64_t hash; + remixapi_Float3D radiance; + } remixapi_LightInfo; + } + + // -------------------------------------------- + // remix api types end -> + + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DebugPrint)(const char* text); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateOpaqueMaterial)(const x86::remixapi_MaterialInfo* info, const x86::remixapi_MaterialInfoOpaqueEXT* ext, const x86::remixapi_MaterialInfoOpaqueSubsurfaceEXT* ext_ss); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateTranslucentMaterial)(const x86::remixapi_MaterialInfo* info, const x86::remixapi_MaterialInfoTranslucentEXT* ext); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreatePortalMaterial)(const x86::remixapi_MaterialInfo* info, const x86::remixapi_MaterialInfoPortalEXT* ext); + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DestroyMaterial)(uint64_t handle); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateTriangleMesh)(const x86::remixapi_MeshInfo* info); + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DestroyMesh)(uint64_t handle); + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DrawMeshInstance)(uint64_t handle, const x86::remixapi_Transform* t, x86::remixapi_Bool double_sided); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateSphereLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoSphereEXT* ext); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateRectLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoRectEXT* ext); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateDiskLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoDiskEXT* ext); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateCylinderLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoCylinderEXT* ext); + typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateDistantLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoDistantEXT* ext); + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DestroyLight)(uint64_t handle); + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DrawLightInstance)(uint64_t handle); + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_SetConfigVariable)(const char* var, const char* value); + typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_RegisterDevice)(void); + typedef void(__cdecl* PFN_bridgeapi_RegisterEndSceneCallback)(void); + + typedef struct bridgeapi_Interface { + bool initialized; + PFN_bridgeapi_DebugPrint DebugPrint; // const char* text + PFN_bridgeapi_CreateOpaqueMaterial CreateOpaqueMaterial; // x86::remixapi_MaterialInfo* + PFN_bridgeapi_CreateTranslucentMaterial CreateTranslucentMaterial; // x86::remixapi_MaterialInfo* --- x86::remixapi_MaterialInfoTranslucentEXT* + PFN_bridgeapi_CreatePortalMaterial CreatePortalMaterial; // x86::remixapi_MaterialInfo* --- x86::remixapi_MaterialInfoPortalEXT* + PFN_bridgeapi_DestroyMaterial DestroyMaterial; // uint64_t handle + PFN_bridgeapi_CreateTriangleMesh CreateTriangleMesh; // x86::remixapi_MeshInfo* + PFN_bridgeapi_DestroyMesh DestroyMesh; // uint64_t handle + PFN_bridgeapi_DrawMeshInstance DrawMeshInstance; // uint64_t handle --- x86::remixapi_Transform* t --- x86::remixapi_Bool double_sided + PFN_bridgeapi_CreateSphereLight CreateSphereLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoSphereEXT* + PFN_bridgeapi_CreateRectLight CreateRectLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoRectEXT* + PFN_bridgeapi_CreateDiskLight CreateDiskLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoDiskEXT* + PFN_bridgeapi_CreateCylinderLight CreateCylinderLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoCylinderEXT* + PFN_bridgeapi_CreateDistantLight CreateDistantLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoDistantEXT* + PFN_bridgeapi_DestroyLight DestroyLight; // uint64_t handle + PFN_bridgeapi_DrawLightInstance DrawLightInstance; // uint64_t handle + PFN_bridgeapi_SetConfigVariable SetConfigVariable; // const char* var --- const char* value + PFN_bridgeapi_RegisterDevice RegisterDevice; // void + void (*RegisterEndSceneCallback)(PFN_bridgeapi_RegisterEndSceneCallback callback); + } bridgeapi_Interface; + + BRIDGE_API BRIDGEAPI_ErrorCode __cdecl bridgeapi_InitFuncs(bridgeapi_Interface* out_result); + typedef BRIDGEAPI_ErrorCode(__cdecl* PFN_bridgeapi_InitFuncs)(bridgeapi_Interface* out_result); + + // -------- + // -------- + + inline BRIDGEAPI_ErrorCode bridgeapi_initialize(bridgeapi_Interface* out_bridgeInterface) { + + PFN_bridgeapi_InitFuncs pfn_Initialize = nullptr; + HMODULE hModule = GetModuleHandleA("d3d9.dll"); + if (hModule) { + PROC func = GetProcAddress(hModule, "bridgeapi_InitFuncs"); + if (func) { + pfn_Initialize = (PFN_bridgeapi_InitFuncs) func; + } + else { + return BRIDGEAPI_ERROR_CODE_GET_PROC_ADDRESS_FAILURE; + } + + bridgeapi_Interface bridgeInterface = { 0 }; + bridgeapi_ErrorCode status = pfn_Initialize(&bridgeInterface); + if (status != BRIDGEAPI_ERROR_CODE_SUCCESS) { + return status; + } + + bridgeInterface.initialized = true; + *out_bridgeInterface = bridgeInterface; + + return status; + } + return BRIDGEAPI_ERROR_CODE_GET_MODULE_HANDLE_FAILURE; + } + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // BRIDGE_C_H_ diff --git a/UCC/UCC.ini b/UCC/UCC.ini index b8200683..4cbdef3d 100644 --- a/UCC/UCC.ini +++ b/UCC/UCC.ini @@ -18,6 +18,7 @@ MatineeCurveDetail=0.1 ;Add the packages you want to compile here in this format: Editpackages+=MyPackageName EditPackages+=Mod EditPackages+=ModMPGame +EditPackages+=RtxDrv [URL] Protocol=republiccommando From 026c134cd30ce6952ccfb4e600e344c39d3eaed5 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 6 Aug 2024 19:20:47 +0200 Subject: [PATCH 09/48] Draw anchor triangle at world origin; Spawn remix light for projectiles --- .../CTInventory.BattleDroidBlasterProj.txt | 2 + .../CTInventory.DC17BlasterProj.txt | 2 + .../Properties.BattleDroidBlasterProjTM.txt | 2 + RtxDrv/Src/RtxRenderDevice.cpp | 120 +++++++++++++----- RtxDrv/Src/RtxRenderDevice.h | 35 +---- 5 files changed, 103 insertions(+), 58 deletions(-) create mode 100644 Mod/PropertyOverrides/CTInventory.BattleDroidBlasterProj.txt create mode 100644 Mod/PropertyOverrides/CTInventory.DC17BlasterProj.txt create mode 100644 Mod/PropertyOverrides/Properties.BattleDroidBlasterProjTM.txt diff --git a/Mod/PropertyOverrides/CTInventory.BattleDroidBlasterProj.txt b/Mod/PropertyOverrides/CTInventory.BattleDroidBlasterProj.txt new file mode 100644 index 00000000..c8dfdc51 --- /dev/null +++ b/Mod/PropertyOverrides/CTInventory.BattleDroidBlasterProj.txt @@ -0,0 +1,2 @@ +LightHue=255 +LightSaturation=40 diff --git a/Mod/PropertyOverrides/CTInventory.DC17BlasterProj.txt b/Mod/PropertyOverrides/CTInventory.DC17BlasterProj.txt new file mode 100644 index 00000000..9c15c7ea --- /dev/null +++ b/Mod/PropertyOverrides/CTInventory.DC17BlasterProj.txt @@ -0,0 +1,2 @@ +LightHue=170 +LightSaturation=40 diff --git a/Mod/PropertyOverrides/Properties.BattleDroidBlasterProjTM.txt b/Mod/PropertyOverrides/Properties.BattleDroidBlasterProjTM.txt new file mode 100644 index 00000000..c8dfdc51 --- /dev/null +++ b/Mod/PropertyOverrides/Properties.BattleDroidBlasterProjTM.txt @@ -0,0 +1,2 @@ +LightHue=255 +LightSaturation=40 diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 64e09668..c5e99eb4 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -3,6 +3,13 @@ IMPLEMENT_CLASS(URtxRenderDevice) +class USolidColorMaterial : public UConstantMaterial{ + DECLARE_CLASS(USolidColorMaterial,UConstantMaterial,0,RtxDrv) +public: + virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0,255); } +}; +IMPLEMENT_CLASS(USolidColorMaterial) + UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) { return Super::Exec(Cmd, Ar); @@ -21,17 +28,6 @@ UBOOL URtxRenderDevice::Init() InitSWRCFix(); } - FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 0, 1, StaticConfigName()); - - if(Section) - { - for(FConfigSection::TIterator It(*Section); It; ++It) - { - const INT Id = appAtoi(*It.Value()); - RenderInterface.MaterialIdsByPath.AddItem(FRtxRenderInterface::MaterialId(Id, *It.Key())); - } - } - RenderInterface.RenDev = this; RenderInterface.Impl = NULL; @@ -73,16 +69,16 @@ void URtxRenderDevice::Flush(UViewport* Viewport) Super::Flush(Viewport); } -UBOOL GFirstClear = 0; FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) { + LockedViewport = Viewport; + if(Viewport->Actor) { Viewport->Actor->bVisor = 0; Viewport->Actor->VisorModeDefault = 1; } - GFirstClear = 0; RenderInterface.Impl = Super::Lock(Viewport, HitData, HitSize); return RenderInterface.Impl ? &RenderInterface : NULL; } @@ -100,22 +96,6 @@ IMPLEMENT_CLASS(UConstantColorMaterial) void URtxRenderDevice::Unlock(FRenderInterface* RI) { - static bool Exited = false; - - if(!Exited && GIsRequestingExit) - { - Exited = true; - FConfigSection* Section = GConfig->GetSectionPrivate("RtxMaterialIds", 1, 0, StaticConfigName()); - check(Section); - - for(TArray::TIterator It(RenderInterface.MaterialIdsByPath); It; ++It) - { - FConfigString& Value = (*Section)[It->Path]; - Value = appItoa(It->Id); - Value.Dirty = true; - } - } - typedef TMap FHandleMap; static FHandleMap HandleMap; @@ -144,7 +124,7 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) s.position.x = Loc.X; s.position.y = Loc.Y; s.position.z = Loc.Z; - s.radius = 5.0f; + s.radius = 2.5f; s.shaping_hasvalue = FALSE; s.shaping_value.direction.x = 0.0f; s.shaping_value.direction.y = 1.0f; @@ -166,6 +146,86 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) It->bUsed = 0; } + DECLARE_STATIC_UOBJECT(USolidColorMaterial, Material, {}); + DECLARE_STATIC_UOBJECT(UFinalBlend, FinalBlend, + { + FinalBlend->Material = Material; + FinalBlend->FrameBufferBlending = FB_Overwrite; + FinalBlend->ColorWriteEnable = 1; + }); + + // Draw anchor triangle at world center to parent stuff to in remix + if(LockedViewport && LockedViewport->Actor) + { + AActor* ViewActor = LockedViewport->Actor; + FVector CameraLocation = ViewActor->Location; + FRotator CameraRotation = ViewActor->Rotation; + LockedViewport->Actor->PlayerCalcView(ViewActor, CameraLocation, CameraRotation); + + // Initialize the view matrix. + FMatrix WorldToCamera = FTranslationMatrix(-CameraLocation); + + if(!LockedViewport->IsOrtho()) + { + WorldToCamera = WorldToCamera * FInverseRotationMatrix(CameraRotation); + WorldToCamera = WorldToCamera * FMatrix( + FPlane(0, 0, 1, 0), + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, 0, 1)); + } + else if(LockedViewport->Actor->RendMap == REN_OrthXY) + { + WorldToCamera = WorldToCamera * FMatrix( + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, -LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, -1, 0), + FPlane(0, 0, -CameraLocation.Z, 1)); + } + else if(LockedViewport->Actor->RendMap == REN_OrthXZ) + { + WorldToCamera = WorldToCamera * FMatrix( + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, 0, -1, 0), + FPlane(0, LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, -CameraLocation.Y, 1)); + } + else if(LockedViewport->Actor->RendMap == REN_OrthYZ) + { + WorldToCamera = WorldToCamera * FMatrix( + FPlane(0, 0, 1, 0), + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, CameraLocation.X, 1)); + } + + // Initialize the projection matrix. + FMatrix CameraToScreen; + if(LockedViewport->IsOrtho()) + { + const FLOAT Zoom = LockedViewport->Actor->OrthoZoom / (LockedViewport->SizeX * 15.0f); + CameraToScreen = FOrthoMatrix(Zoom * LockedViewport->SizeX / 2,Zoom * LockedViewport->SizeY / 2, 0.5f / HALF_WORLD_MAX, HALF_WORLD_MAX); + } + else + { + const FLOAT FOV = LockedViewport->Actor->FovAngle * PI / 360.0f; + CameraToScreen = FPerspectiveMatrix(FOV, FOV, 1.0f, (FLOAT)LockedViewport->SizeX / LockedViewport->SizeY, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); + } + + RenderInterface.PushState(); + RenderInterface.SetTransform(TT_LocalToWorld, FMatrix::Identity); + RenderInterface.SetTransform(TT_WorldToCamera, WorldToCamera); + RenderInterface.SetTransform(TT_CameraToScreen, CameraToScreen); + RenderInterface.SetMaterial(FinalBlend); + RenderInterface.SetIndexBuffer(NULL, 0); + FVertexStream* Stream = &AnchorTriangle; + RenderInterface.SetVertexStreams(VS_FixedFunction, &Stream, 1); + RenderInterface.DrawPrimitive(PT_TriangleList, 0, 1); + RenderInterface.PopState(); + } + + LockedViewport = NULL; + Super::Unlock(static_cast(RI)->Impl); } diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 3df1c7cc..630a356d 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -62,8 +62,8 @@ class FRtxRenderInterface : public FRenderInterface{ virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){} virtual void SetShaderLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetShaderLight(LightIndex, Light, Scale); } virtual void SetNPatchTesselation(FLOAT Tesselation){ Impl->SetNPatchTesselation(Tesselation); } - virtual void SetDistanceFog(UBOOL Enable, FLOAT FogStart, FLOAT FogEnd, FColor Color){ Impl->SetDistanceFog(Enable, FogStart, FogEnd, Color); } - virtual UBOOL EnableFog(UBOOL Enable){ return Impl->EnableFog(Enable); } + virtual void SetDistanceFog(UBOOL Enable, FLOAT FogStart, FLOAT FogEnd, FColor Color){ Impl->SetDistanceFog(0, 0.0f, 0.0f, FColor()); } + virtual UBOOL EnableFog(UBOOL Enable){ return Impl->EnableFog(0); } virtual UBOOL IsFogEnabled(){ return Impl->IsFogEnabled(); } virtual void SetGlobalColor(FColor Color){ Impl->SetGlobalColor(Color); } virtual void SetTransform(ETransformType Type, const FMatrix& Matrix); @@ -87,37 +87,13 @@ class FRtxRenderInterface : public FRenderInterface{ virtual INT SetDynamicIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetDynamicIndexBuffer(IndexBuffer, BaseIndex); } virtual void DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex = INDEX_NONE, INT MaxIndex = INDEX_NONE); virtual void SetFillMode(EFillMode FillMode){ Impl->SetFillMode(FillMode); } - - struct MaterialId{ - INT Id; - FSingleTriangleVertexStream Stream; - FString Path; - - MaterialId(INT InId = 0, const TCHAR* InPath = NULL) - : Id(InId), - Stream(InId + 32, InId + 32), - Path(InPath) - { - ++Stream.Revision; - } - - void UpdateId(INT InId) - { - Id = InId, - Stream.HalfWidth = (InId + 32) / 2.0f; - Stream.HalfHeight = Stream.HalfWidth; - ++Stream.Revision; - } - }; - - TArray MaterialIdsByPath; }; class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) static const TCHAR* StaticConfigName(){ return "RtxDrv"; } public: - FRtxRenderInterface RenderInterface; + URtxRenderDevice() : AnchorTriangle(512, 512){} virtual UBOOL Exec(const TCHAR* Cmd, FOutputDevice& Ar); virtual UBOOL Init(); @@ -129,7 +105,10 @@ class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ virtual FRenderCaps* GetRenderCaps(); private: - bridgeapi_Interface BridgeInterface; + UViewport* LockedViewport; + bridgeapi_Interface BridgeInterface; + FSingleTriangleVertexStream AnchorTriangle; + FRtxRenderInterface RenderInterface; void ClearMaterialFlags(); }; From 1977df385569b8ee022ad21f91b4635e671a6883 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Fri, 9 Aug 2024 21:28:43 +0200 Subject: [PATCH 10/48] Make FVector::Fvector(FLOAT) explicit --- Core/Inc/UnMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Inc/UnMath.h b/Core/Inc/UnMath.h index b303050a..ee673ee0 100644 --- a/Core/Inc/UnMath.h +++ b/Core/Inc/UnMath.h @@ -189,7 +189,7 @@ class FVector{ // Constructors. FVector(){} - FVector(FLOAT In) : X(In), Y(In), Z(In){} + explicit FVector(FLOAT In) : X(In), Y(In), Z(In){} FVector(FLOAT InX, FLOAT InY, FLOAT InZ) : X(InX), Y(InY), Z(InZ){} From 22235f4a74f6aaeeddfb2fd290eb2723bcd1b9c0 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Fri, 9 Aug 2024 21:49:49 +0200 Subject: [PATCH 11/48] Create a rtx light for each projectile in the level --- Core/Inc/UnObjBas.h | 2 +- RtxDrv/Inc/RtxDrvClasses.h | 1 + RtxDrv/Src/RtxRenderDevice.cpp | 99 ++++++++++++++++++++++++++-------- RtxDrv/Src/RtxRenderDevice.h | 24 ++++----- 4 files changed, 91 insertions(+), 35 deletions(-) diff --git a/Core/Inc/UnObjBas.h b/Core/Inc/UnObjBas.h index 62592648..2cf1ac14 100644 --- a/Core/Inc/UnObjBas.h +++ b/Core/Inc/UnObjBas.h @@ -555,7 +555,7 @@ class CORE_API UObject{ FORCEINLINE FStateFrame* GetStateFrame(){ return _StateFrame; } }; -#define DECLARE_NAME(name) static FName N##name(#name); +#define DECLARE_NAME(name) static FName N##name(#name) /*---------------------------------------------------------------------------- Core templates. diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 23af0e26..a65d1ebd 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -36,6 +36,7 @@ class RTXDRV_API URtx : public UObject #define AUTO_INITIALIZE_REGISTRANTS_RTXDRV \ UConstantColorMaterial::StaticClass(); \ + USolidColorMaterial::StaticClass(); \ URtx::StaticClass(); \ URtxRenderDevice::StaticClass(); \ diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index c5e99eb4..49b707d0 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -12,9 +12,24 @@ IMPLEMENT_CLASS(USolidColorMaterial) UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) { + if(ParseCommand(&Cmd, "RTX")) + { + if(ParseCommand(&Cmd, "TOGGLEANCHOR")) + { + bShowAnchorTriangle = !bShowAnchorTriangle; + return 1; + } + } + return Super::Exec(Cmd, Ar); } +void URtxRenderDevice::StaticConstructor() +{ + new(GetClass(), "ShowAnchor", RF_Public) UBoolProperty(CPP_PROPERTY(bShowAnchorTriangle), "RtxRenderDevice", CPF_Config); + new(GetClass(), "EnableD3DLights", RF_Public) UBoolProperty(CPP_PROPERTY(bEnableD3DLights), "RtxRenderDevice", CPF_Config); +} + UBOOL URtxRenderDevice::Init() { // Init SWRCFix if it exists. Hacky but RenderDevice is always loaded at startup... @@ -38,6 +53,7 @@ UBOOL URtxRenderDevice::Init() Client->BloomQuality = 0; Client->BlurEnabled = 0; Client->BumpmappingQuality = 0; + // Client->Projectors = 0; GetDefault()->bVisor = 0; GetDefault()->VisorModeDefault = 1; UseStencil = 0; @@ -51,6 +67,7 @@ UBOOL URtxRenderDevice::SetRes(UViewport* Viewport, INT NewX, INT NewY, UBOOL Fu if(Result && !BridgeInterface.initialized) { + debugf("Initializing remix bridge API"); if(bridgeapi_initialize(&BridgeInterface) != BRIDGEAPI_ERROR_CODE_SUCCESS || !BridgeInterface.initialized) { appErrorf("Failed to initialize remix bridge API"); @@ -104,38 +121,65 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) FLightHandle* HandlePtr = HandleMap.Find(*Proj); if(HandlePtr) - BridgeInterface.DestroyLight(HandlePtr->Handle); + { + if(HandlePtr->Handle) + BridgeInterface.DestroyLight(HandlePtr->Handle); + } else + { HandlePtr = &HandleMap[*Proj]; + } x86::remixapi_LightInfo l; l.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO; l.hash = reinterpret_cast(*Proj); - FPlane Col = FGetHSV(Proj->LightHue, Proj->LightSaturation, Proj->LightBrightness) * 10000; + FPlane Col = FGetHSV(Proj->LightHue, Proj->LightSaturation, Proj->LightBrightness) * 1000; l.radiance.x = Col.X; l.radiance.y = Col.Y; l.radiance.z = Col.Z; FVector Loc = Proj->Location; - x86::remixapi_LightInfoSphereEXT s; - s.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT; - s.position.x = Loc.X; - s.position.y = Loc.Y; - s.position.z = Loc.Z; - s.radius = 2.5f; - s.shaping_hasvalue = FALSE; - s.shaping_value.direction.x = 0.0f; - s.shaping_value.direction.y = 1.0f; - s.shaping_value.direction.z = 0.0f; - s.shaping_value.coneAngleDegrees = 80.0f; - s.shaping_value.coneSoftness = 1.0f; - s.shaping_value.focusExponent = 0.0f; + + DECLARE_NAME(GrenadeProj); + if(Proj->IsA(NGrenadeProj)) + { + x86::remixapi_LightInfoSphereEXT s; + s.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT; + s.position.x = Loc.X; + s.position.y = Loc.Y; + s.position.z = Loc.Z; + s.radius = 32.0f; + s.shaping_hasvalue = FALSE; + s.shaping_value.direction.x = 0.0f; + s.shaping_value.direction.y = 0.0f; + s.shaping_value.direction.z = 1.0f; + s.shaping_value.coneAngleDegrees = 80.0f; + s.shaping_value.coneSoftness = 1.0f; + s.shaping_value.focusExponent = 0.0f; + HandlePtr->Handle = BridgeInterface.CreateSphereLight(&l, &s); + } + else + { + x86::remixapi_LightInfoCylinderEXT s; + FVector Dir = Proj->Rotation.Vector().GetNormalized(); + s.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT; + s.position.x = Loc.X; + s.position.y = Loc.Y; + s.position.z = Loc.Z; + s.axis.x = Dir.X; + s.axis.y = Dir.Y; + s.axis.z = Dir.Z; + s.axisLength = 200.0f; + s.radius = 2.5f; + HandlePtr->Handle = BridgeInterface.CreateCylinderLight(&l, &s); + } HandlePtr->bUsed = 1; - HandlePtr->Handle = BridgeInterface.CreateSphereLight(&l, &s); - BridgeInterface.DrawLightInstance(HandlePtr->Handle); + + if(HandlePtr->Handle) + BridgeInterface.DrawLightInstance(HandlePtr->Handle); } for(FHandleMap::TIterator It(HandleMap); It; ++It) @@ -151,8 +195,8 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) { FinalBlend->Material = Material; FinalBlend->FrameBufferBlending = FB_Overwrite; - FinalBlend->ColorWriteEnable = 1; }); + FinalBlend->ColorWriteEnable = bShowAnchorTriangle; // Draw anchor triangle at world center to parent stuff to in remix if(LockedViewport && LockedViewport->Actor) @@ -236,10 +280,10 @@ void URtxRenderDevice::Present(UViewport* Viewport) FRenderCaps* URtxRenderDevice::GetRenderCaps() { - /* return Super::GetRenderCaps(); */ - static FRenderCaps RenderCaps(1, 14, 1); + return Super::GetRenderCaps(); + // static FRenderCaps RenderCaps(1, 14, 1); - return &RenderCaps; + // return &RenderCaps; } UBOOL FRtxRenderInterface::SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer) @@ -253,6 +297,19 @@ void FRtxRenderInterface::Clear(UBOOL UseColor, FColor Color, UBOOL UseDepth, FL Impl->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); } +void FRtxRenderInterface::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue){ + UseDynamic = 0; + Lightmap = NULL; + Modulate2X = 0; + Impl->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); +} + +void FRtxRenderInterface::SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale) +{ + if(RenDev->bEnableD3DLights) + Impl->SetLight(LightIndex, Light, Scale); +} + void FRtxRenderInterface::SetTransform(ETransformType Type, const FMatrix& Matrix) { Impl->SetTransform(Type, Matrix); diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 630a356d..1d5f95e5 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -46,21 +46,15 @@ class FRtxRenderInterface : public FRenderInterface{ virtual void PushState(DWORD Flags = 0){ Impl->PushState(Flags); } virtual void PopState(DWORD Flags = 0){ Impl->PopState(Flags); } virtual UBOOL SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer); - virtual UBOOL SetCubeRenderTarget(class FDynamicCubemap* Target, int A, int B){ return Impl->SetCubeRenderTarget(Target, A, B); } virtual void SetViewport(INT X, INT Y, INT Width, INT Height){ Impl->SetViewport(X, Y, Width, Height); } virtual void Clear(UBOOL UseColor = 1, FColor Color = FColor(0, 0, 0), UBOOL UseDepth = 1, FLOAT Depth = 1.0f, UBOOL UseStencil = 1, DWORD Stencil = 0); virtual void PushHit(const BYTE* Data, INT Count){ Impl->PushHit(Data, Count); } virtual void PopHit(INT Count, UBOOL Force){ Impl->PopHit(Count, Force); } virtual void SetCullMode(ECullMode CullMode){ Impl->SetCullMode(CullMode); } virtual void SetAmbientLight(FColor Color){} - virtual void EnableLighting(UBOOL UseDynamic, UBOOL UseStatic = 1, UBOOL Modulate2X = 0, FBaseTexture* Lightmap = NULL, UBOOL LightingOnly = 0, const FSphere& LitSphere = FSphere(FVector(0, 0, 0), 0), int IntValue = 0){ - UseDynamic = 0; - Lightmap = NULL; - Modulate2X = 0; - Impl->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); - } - virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){} - virtual void SetShaderLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){ Impl->SetShaderLight(LightIndex, Light, Scale); } + virtual void EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue); + virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f); + virtual void SetShaderLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){} virtual void SetNPatchTesselation(FLOAT Tesselation){ Impl->SetNPatchTesselation(Tesselation); } virtual void SetDistanceFog(UBOOL Enable, FLOAT FogStart, FLOAT FogEnd, FColor Color){ Impl->SetDistanceFog(0, 0.0f, 0.0f, FColor()); } virtual UBOOL EnableFog(UBOOL Enable){ return Impl->EnableFog(0); } @@ -71,13 +65,13 @@ class FRtxRenderInterface : public FRenderInterface{ virtual void SetMaterial(UMaterial* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL, INT* NumPasses = NULL); virtual UBOOL SetHardwareShaderMaterial(UHardwareShader* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL){ return Impl->SetHardwareShaderMaterial(Material, ErrorString, ErrorMaterial); } virtual UBOOL ShowAlpha(UMaterial* Material){ return Impl->ShowAlpha(Material); } - virtual UBOOL IsShadowInterface(){ return Impl->IsShadowInterface(); } - virtual void SetAntiAliasing(INT Level){ Impl->SetAntiAliasing(Level); } + virtual UBOOL IsShadowInterface(){ return 0; } + virtual void SetAntiAliasing(INT Level){} virtual void CopyBackBufferToTarget(FAuxRenderTarget* Target){ Impl->CopyBackBufferToTarget(Target); } virtual void SetLODDiffuseFade(FLOAT Distance){ Impl->SetLODDiffuseFade(Distance); } virtual void SetLODSpecularFade(FLOAT Distance){ Impl->SetLODSpecularFade(Distance); } - virtual void SetStencilOp(ECompareFunction Test, DWORD Ref, DWORD Mask, EStencilOp FailOp, EStencilOp ZFailOp, EStencilOp PassOp, DWORD WriteMask){ Impl->SetStencilOp(Test, Ref, Mask, FailOp, ZFailOp, PassOp, WriteMask); } - virtual void EnableStencil(UBOOL Enable){ Impl->EnableStencil(Enable); } + virtual void SetStencilOp(ECompareFunction Test, DWORD Ref, DWORD Mask, EStencilOp FailOp, EStencilOp ZFailOp, EStencilOp PassOp, DWORD WriteMask){} + virtual void EnableStencil(UBOOL Enable){} virtual void EnableDepth(UBOOL Enable){ Impl->EnableDepth(Enable); } virtual void SetPrecacheMode(EPrecacheMode PrecacheMode){ Impl->SetPrecacheMode(PrecacheMode); } virtual void SetZBias(INT ZBias){ Impl->SetZBias(ZBias); } @@ -94,6 +88,10 @@ class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ static const TCHAR* StaticConfigName(){ return "RtxDrv"; } public: URtxRenderDevice() : AnchorTriangle(512, 512){} + void StaticConstructor(); + + UBOOL bShowAnchorTriangle; + UBOOL bEnableD3DLights; virtual UBOOL Exec(const TCHAR* Cmd, FOutputDevice& Ar); virtual UBOOL Init(); From 4592a08e69172088f957ec62fbdf9caa7cfb3a5a Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sun, 11 Aug 2024 17:06:55 +0200 Subject: [PATCH 12/48] Add rtx unrealscript interface --- Core/Inc/UnTemplate.h | 8 +- Core/Inc/UnType.h | 2 +- RtxDrv/Classes/Rtx.uc | 3 - RtxDrv/Classes/RtxInterface.uc | 29 +++ RtxDrv/Classes/RtxLight.uc | 71 ++++++ RtxDrv/Inc/RtxDrvClasses.h | 104 +++++++- RtxDrv/RtxDrv.vcproj | 3 + RtxDrv/Src/Rtx.cpp | 230 ++++++++++++++++++ RtxDrv/Src/RtxDrvClasses.cpp | 18 +- RtxDrv/Src/RtxDrvPrivate.h | 2 + RtxDrv/Src/RtxRenderDevice.cpp | 428 +++++++++++++++++---------------- RtxDrv/Src/RtxRenderDevice.h | 129 ++++------ 12 files changed, 719 insertions(+), 308 deletions(-) delete mode 100644 RtxDrv/Classes/Rtx.uc create mode 100644 RtxDrv/Classes/RtxInterface.uc create mode 100644 RtxDrv/Classes/RtxLight.uc create mode 100644 RtxDrv/Src/Rtx.cpp diff --git a/Core/Inc/UnTemplate.h b/Core/Inc/UnTemplate.h index 18066762..b3aba5af 100644 --- a/Core/Inc/UnTemplate.h +++ b/Core/Inc/UnTemplate.h @@ -459,11 +459,9 @@ class TArray : public FArray{ T Pop() { - T Result = (*this)[Num() - 1]; - - Remove(Num() - 1); - - return Result; + checkSlow(ArrayNum > 0); + --ArrayNum; + return GetData()[ArrayNum]; } INT AddItem(const T& Item) diff --git a/Core/Inc/UnType.h b/Core/Inc/UnType.h index 89ea309f..a27f6153 100644 --- a/Core/Inc/UnType.h +++ b/Core/Inc/UnType.h @@ -483,7 +483,7 @@ inline UBOOL UObject::IsIn(UObject* SomeOuter) const{ -----------------------------------------------------------------------------*/ #define CPP_PROPERTY(name) \ - EC_CppProperty, (BYTE*)&((ThisClass*)NULL)->name - (BYTE*)NULL + EC_CppProperty, STRUCT_OFFSET(ThisClass, name) /*----------------------------------------------------------------------------- The End. diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc deleted file mode 100644 index 4e07f6dc..00000000 --- a/RtxDrv/Classes/Rtx.uc +++ /dev/null @@ -1,3 +0,0 @@ -class Rtx extends Object native; - -native static final function TestFunc(); diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc new file mode 100644 index 00000000..12de7bfc --- /dev/null +++ b/RtxDrv/Classes/RtxInterface.uc @@ -0,0 +1,29 @@ +class RtxInterface extends Object within RtxRenderDevice native transient config(RtxDrv) hidecategories(Object, None); + +// uint64_t +struct noexport RtxHandle{ + var const int lo; + var const int hi; +}; + +var(General) config bool bShowAnchorTriangle; +var(Lighting) editinline array Lights; +var array DestroyedLights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights + +native final function RtxLight CreateLight(); +native final function DestroyLight(RtxLight Light); +native final function DestroyAllLights(); + +native static final function RtxInterface GetInstance(); + +cpptext +{ + void Init(); + void Exit(); + URtxLight* CreateLight(bool ForceDefaultConstructed = false); + void DestroyLight(URtxLight* Light); + void DestroyAllLights(); + void RenderLights(); + + static bridgeapi_Interface BridgeInterface; +} diff --git a/RtxDrv/Classes/RtxLight.uc b/RtxDrv/Classes/RtxLight.uc new file mode 100644 index 00000000..4ee48a74 --- /dev/null +++ b/RtxDrv/Classes/RtxLight.uc @@ -0,0 +1,71 @@ +class RtxLight extends Object within RtxInterface native transient hidecategories(Object, None); + +var editconst RtxInterface.RtxHandle Handle; + +var(Common) enum ERtxLightType{ + RTXLIGHT_Sphere, + RTXLIGHT_Rect, + RTXLIGHT_Disk, + RTXLIGHT_Cylinder, + RTXLIGHT_Distant +} Type; + +var(Common) bool bEnabled; +var(Common) bool bUseShaping; +var(Common) vector Position; +var(Common) vector Radiance; + +// Used by sphere, rect and disc if bUseShaping +var(Common) struct RtxLightShaping{ + var() vector Direction; + var() float ConeAngleDegrees; + var() float ConeSoftness; + var() float FocusExponent; +} Shaping; + +var(SphereLight) struct RtxSphereLight{ + var() float Radius; +} Sphere; + +var(RectLight) struct RtxRectLight{ + var() vector XAxis; + var() vector YAxis; + var() float XSize; + var() float YSize; + var() vector Direction; +} Rect; + +var(DiskLight) struct RtxDiskLight{ + var() vector XAxis; + var() vector YAxis; + var() float XRadius; + var() float YRadius; + var() vector Direction; +} Disk; + +var(CylinderLight) struct RtxCylinderLight{ + var() vector Axis; + var() float Length; + var() float Radius; +} Cylinder; + +var(DistantLight) struct RtxDistantLight{ + var() vector Direction; + var() float AngularDiameterDegrees; +} Distant; + +native final function Update(); // Must be called whenever a property value has changed + +cpptext +{ + virtual void Destroy(); + virtual void PostEditChange(){ Super::PostEditChange(); Update(); } + void Update(); +} + +defaultproperties +{ + bEnabled=True + Radiance=(X=1000,Y=1000,Z=1000) + Sphere=(Radius=2.5) +} diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index a65d1ebd..ab9988ea 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -17,13 +17,103 @@ -class RTXDRV_API URtx : public UObject +class RTXDRV_API URtxInterface : public UObject { public: - void execTestFunc(FFrame& Stack, void* Result); - DECLARE_CLASS(URtx,UObject,0,RtxDrv) - NO_DEFAULT_CONSTRUCTOR(URtx) - DECLARE_NATIVES(URtx) + BITFIELD bShowAnchorTriangle:1 GCC_PACK(4); + TArrayNoInit Lights GCC_PACK(4); + TArrayNoInit DestroyedLights; + void execCreateLight(FFrame& Stack, void* Result); + void execDestroyLight(FFrame& Stack, void* Result); + void execDestroyAllLights(FFrame& Stack, void* Result); + void execGetInstance(FFrame& Stack, void* Result); + DECLARE_CLASS(URtxInterface,UObject,0|CLASS_Transient|CLASS_Config,RtxDrv) + void Init(); + void Exit(); + URtxLight* CreateLight(bool ForceDefaultConstructed = false); + void DestroyLight(URtxLight* Light); + void DestroyAllLights(); + void RenderLights(); + + static bridgeapi_Interface BridgeInterface; + DECLARE_NATIVES(URtxInterface) +}; + +enum ERtxLightType +{ + RTXLIGHT_Sphere, + RTXLIGHT_Rect, + RTXLIGHT_Disk, + RTXLIGHT_Cylinder, + RTXLIGHT_Distant, + RTXLIGHT_MAX +}; +struct RTXDRV_API FRtxLightShaping +{ + FVector Direction; + FLOAT ConeAngleDegrees; + FLOAT ConeSoftness; + FLOAT FocusExponent; +}; + +struct RTXDRV_API FRtxSphereLight +{ + FLOAT Radius; +}; + +struct RTXDRV_API FRtxRectLight +{ + FVector XAxis; + FVector YAxis; + FLOAT XSize; + FLOAT YSize; + FVector Direction; +}; + +struct RTXDRV_API FRtxDiskLight +{ + FVector XAxis; + FVector YAxis; + FLOAT XRadius; + FLOAT YRadius; + FVector Direction; +}; + +struct RTXDRV_API FRtxCylinderLight +{ + FVector Axis; + FLOAT Length; + FLOAT Radius; +}; + +struct RTXDRV_API FRtxDistantLight +{ + FVector Direction; + FLOAT AngularDiameterDegrees; +}; + + +class RTXDRV_API URtxLight : public UObject +{ +public: + FRtxHandle Handle; + BYTE Type; + BITFIELD bEnabled:1 GCC_PACK(4); + BITFIELD bUseShaping:1; + FVector Position GCC_PACK(4); + FVector Radiance; + FRtxLightShaping Shaping; + FRtxSphereLight Sphere; + FRtxRectLight Rect; + FRtxDiskLight Disk; + FRtxCylinderLight Cylinder; + FRtxDistantLight Distant; + void execUpdate(FFrame& Stack, void* Result); + DECLARE_CLASS(URtxLight,UObject,0|CLASS_Transient,RtxDrv) + virtual void Destroy(); + virtual void PostEditChange(){ Super::PostEditChange(); Update(); } + void Update(); + DECLARE_NATIVES(URtxLight) }; @@ -35,9 +125,9 @@ class RTXDRV_API URtx : public UObject #if __STATIC_LINK #define AUTO_INITIALIZE_REGISTRANTS_RTXDRV \ - UConstantColorMaterial::StaticClass(); \ USolidColorMaterial::StaticClass(); \ - URtx::StaticClass(); \ + URtxInterface::StaticClass(); \ + URtxLight::StaticClass(); \ URtxRenderDevice::StaticClass(); \ #endif // __STATIC_LINK diff --git a/RtxDrv/RtxDrv.vcproj b/RtxDrv/RtxDrv.vcproj index 96a2fdd7..b1fd874c 100644 --- a/RtxDrv/RtxDrv.vcproj +++ b/RtxDrv/RtxDrv.vcproj @@ -112,6 +112,9 @@ + + diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp new file mode 100644 index 00000000..557f837c --- /dev/null +++ b/RtxDrv/Src/Rtx.cpp @@ -0,0 +1,230 @@ +#include "RtxDrvPrivate.h" +#include "RtxRenderDevice.h" + +bridgeapi_Interface URtxInterface::BridgeInterface; + +void URtxInterface::Init() +{ + if(!BridgeInterface.initialized) + { + debugf("Initializing remix bridge API"); + + if(bridgeapi_initialize(&BridgeInterface) != BRIDGEAPI_ERROR_CODE_SUCCESS || !BridgeInterface.initialized) + appErrorf("Failed to initialize remix bridge API"); + + BridgeInterface.RegisterDevice(); + } +} + +void URtxInterface::Exit() +{ + BridgeInterface.initialized = false; +} + +URtxLight* URtxInterface::CreateLight(bool ForceDefaultConstructed) +{ + URtxLight* Light; + + if(!ForceDefaultConstructed && DestroyedLights.Num() > 0) + Light = DestroyedLights.Pop(); + else + Light = ConstructObject(URtxLight::StaticClass(), this); + + Light->bEnabled = 1; + Lights.AddItem(Light); + return Light; +} + +void URtxInterface::DestroyLight(URtxLight* Light) +{ + if(Light) + { + Lights.RemoveItem(Light); + DestroyedLights.AddItem(Light); + } +} + +void URtxInterface::DestroyAllLights() +{ + INT Index = DestroyedLights.Add(Lights.Num(), false); + appMemcpy(&DestroyedLights[Index], &Lights[0], Lights.Num() * sizeof(URtxLight*)); + Lights.Empty(); +} + +void URtxInterface::RenderLights() +{ + for(INT i = 0; i < Lights.Num(); ++i) + { + URtxLight* Light = Lights[i]; + + if(!Light) // NULL entry can happen if a light was added via the property window UI. In that case just create it + { + Light = ConstructObject(URtxLight::StaticClass(), this); + Lights[i] = Light; + + TObjectIterator It; + if(It && It->Actor) + Lights[i]->Position = It->Actor->Location; + } + + if(Light->bEnabled) + { + if(!Light->Handle) + Light->Update(); + + if(Light->Handle) + BridgeInterface.DrawLightInstance(Light->Handle); + } + } +} + +void URtxInterface::execCreateLight(FFrame& Stack, void* Result) +{ + P_FINISH; + *static_cast(Result) = CreateLight(); +} + +void URtxInterface::execDestroyLight(FFrame& Stack, void* Result) +{ + P_GET_OBJECT(URtxLight, Light); + P_FINISH; + DestroyLight(Light); +} + +void URtxInterface::execDestroyAllLights(FFrame& Stack, void* Result) +{ + P_FINISH; + DestroyAllLights(); +} + +void URtxInterface::execGetInstance(FFrame& Stack, void* Result) +{ + P_FINISH; + + URtxRenderDevice* RenDev = Cast(GEngine->GRenDev); + + if(RenDev) + *static_cast(Result) = RenDev->GetRtxInterface(); +} + + +void URtxLight::execUpdate(FFrame& Stack, void* Result) +{ + P_FINISH; + Update(); +} + +void URtxLight::Destroy() +{ + if(Handle) + { + if(URtxInterface::BridgeInterface.initialized) + URtxInterface::BridgeInterface.DestroyLight(Handle); + + Handle = 0; + } + + Super::Destroy(); +} + +static void InitFloat3D(x86::remixapi_Float3D& Dest, const FVector& Src) +{ + Dest.x = Src.X; + Dest.y = Src.Y; + Dest.z = Src.Z; +} + +static void InitShaping(x86::remixapi_LightInfoLightShaping& Dest, const FRtxLightShaping& Src) +{ + Dest.coneAngleDegrees = Src.ConeAngleDegrees; + Dest.coneSoftness = Src.ConeSoftness; + Dest.focusExponent = Src.FocusExponent; +} + +void URtxLight::Update() +{ + const bridgeapi_Interface& Bridge = URtxInterface::BridgeInterface; + + if(Handle) + { + Bridge.DestroyLight(Handle); + Handle = 0; + } + + x86::remixapi_LightInfo LightInfo; + LightInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO; + LightInfo.hash = reinterpret_cast(this); + InitFloat3D(LightInfo.radiance, Radiance); + + switch(Type) + { + case RTXLIGHT_Sphere: + { + x86::remixapi_LightInfoSphereEXT SphereInfo; + SphereInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT; + InitFloat3D(SphereInfo.position, Position); + SphereInfo.radius = Sphere.Radius; + SphereInfo.shaping_hasvalue = bUseShaping; + + if(SphereInfo.shaping_hasvalue) + InitShaping(SphereInfo.shaping_value, Shaping); + + Handle = Bridge.CreateSphereLight(&LightInfo, &SphereInfo); + break; + } + case RTXLIGHT_Rect: + { + x86::remixapi_LightInfoRectEXT RectInfo; + RectInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT; + InitFloat3D(RectInfo.position, Position); + InitFloat3D(RectInfo.xAxis, Rect.XAxis.GetNormalized()); + RectInfo.xSize = Rect.XSize; + InitFloat3D(RectInfo.yAxis, Rect.YAxis.GetNormalized()); + RectInfo.ySize = Rect.YSize; + InitFloat3D(RectInfo.direction, Rect.Direction.GetNormalized()); + + if(RectInfo.shaping_hasvalue) + InitShaping(RectInfo.shaping_value, Shaping); + + Handle = Bridge.CreateRectLight(&LightInfo, &RectInfo); + break; + } + case RTXLIGHT_Disk: + { + x86::remixapi_LightInfoDiskEXT DiskInfo; + DiskInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT; + InitFloat3D(DiskInfo.position, Position); + InitFloat3D(DiskInfo.xAxis, Disk.XAxis.GetNormalized()); + DiskInfo.xRadius = Disk.XRadius; + InitFloat3D(DiskInfo.yAxis, Disk.YAxis.GetNormalized()); + DiskInfo.yRadius = Disk.YRadius; + InitFloat3D(DiskInfo.direction, Disk.Direction.GetNormalized()); + + if(DiskInfo.shaping_hasvalue) + InitShaping(DiskInfo.shaping_value, Shaping); + + Handle = Bridge.CreateDiskLight(&LightInfo, &DiskInfo); + break; + } + case RTXLIGHT_Cylinder: + { + x86::remixapi_LightInfoCylinderEXT CylinderInfo; + CylinderInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT; + InitFloat3D(CylinderInfo.position, Position); + InitFloat3D(CylinderInfo.axis, Cylinder.Axis.GetNormalized()); + CylinderInfo.radius = Cylinder.Radius; + CylinderInfo.axisLength = Cylinder.Length; + Handle = Bridge.CreateCylinderLight(&LightInfo, &CylinderInfo); + break; + } + case RTXLIGHT_Distant: + { + x86::remixapi_LightInfoDistantEXT DistantInfo; + DistantInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT; + InitFloat3D(DistantInfo.direction, Distant.Direction.GetNormalized()); + DistantInfo.angularDiameterDegrees = Distant.AngularDiameterDegrees; + Handle = Bridge.CreateDistantLight(&LightInfo, &DistantInfo); + break; + } + } +} diff --git a/RtxDrv/Src/RtxDrvClasses.cpp b/RtxDrv/Src/RtxDrvClasses.cpp index 67367eda..92da0d54 100644 --- a/RtxDrv/Src/RtxDrvClasses.cpp +++ b/RtxDrv/Src/RtxDrvClasses.cpp @@ -10,9 +10,19 @@ IMPLEMENT_PACKAGE(RtxDrv) -IMPLEMENT_CLASS(URtx); -FNativeEntry URtx::StaticNativeMap[] = { - MAP_NATIVE(TestFunc,0) +IMPLEMENT_CLASS(URtxInterface); +FNativeEntry URtxInterface::StaticNativeMap[] = { + MAP_NATIVE(CreateLight,0) + MAP_NATIVE(DestroyLight,0) + MAP_NATIVE(DestroyAllLights,0) + MAP_NATIVE(GetInstance,0) {NULL,NULL} }; -LINK_NATIVES(URtx); +LINK_NATIVES(URtxInterface); + +IMPLEMENT_CLASS(URtxLight); +FNativeEntry URtxLight::StaticNativeMap[] = { + MAP_NATIVE(Update,0) + {NULL,NULL} +}; +LINK_NATIVES(URtxLight); diff --git a/RtxDrv/Src/RtxDrvPrivate.h b/RtxDrv/Src/RtxDrvPrivate.h index e97e8875..337fde56 100644 --- a/RtxDrv/Src/RtxDrvPrivate.h +++ b/RtxDrv/Src/RtxDrvPrivate.h @@ -1,2 +1,4 @@ #include "Core.h" +#include "bridge_c.h" +typedef uint64_t FRtxHandle; #include "../Inc/RtxDrvClasses.h" diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 49b707d0..68ea30e0 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -1,14 +1,15 @@ -#include "RtxDrvPrivate.h" #include "RtxRenderDevice.h" +#include "RtxDrvPrivate.h" +#include "Window.h" IMPLEMENT_CLASS(URtxRenderDevice) -class USolidColorMaterial : public UConstantMaterial{ - DECLARE_CLASS(USolidColorMaterial,UConstantMaterial,0,RtxDrv) -public: - virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0,255); } -}; -IMPLEMENT_CLASS(USolidColorMaterial) +void URtxRenderDevice::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + if(Ar.IsGarbageCollecting()) + Ar << Rtx; +} UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) { @@ -16,7 +17,31 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) { if(ParseCommand(&Cmd, "TOGGLEANCHOR")) { - bShowAnchorTriangle = !bShowAnchorTriangle; + Rtx->bShowAnchorTriangle = !Rtx->bShowAnchorTriangle; + return 1; + } + else if(ParseCommand(&Cmd, "PREFERENCES")) + { + GEngine->Client->GetLastCurrent()->EndFullscreen(); + WObjectProperties* P = new WObjectProperties("EditObj", 0, "", NULL, 1); + P->OpenWindow(GLogWindow->hWnd); + UObject* Obj = Rtx; + P->Root.SetObjects(&Obj, 1); + P->Show(1); + } + else if(ParseCommand(&Cmd, "CREATELIGHT")) + { + UObject* Light = Rtx->CreateLight(true); + + if(!ParseCommand(&Cmd, "!")) + { + GEngine->Client->GetLastCurrent()->EndFullscreen(); + WObjectProperties* P = new WObjectProperties("EditObj", 0, "", NULL, 1); + P->OpenWindow(GLogWindow->hWnd); + P->Root.SetObjects(&Light, 1); + P->Show(1); + } + return 1; } } @@ -26,8 +51,8 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) void URtxRenderDevice::StaticConstructor() { - new(GetClass(), "ShowAnchor", RF_Public) UBoolProperty(CPP_PROPERTY(bShowAnchorTriangle), "RtxRenderDevice", CPF_Config); - new(GetClass(), "EnableD3DLights", RF_Public) UBoolProperty(CPP_PROPERTY(bEnableD3DLights), "RtxRenderDevice", CPF_Config); + UseStencil = 0; + CanDoDistortionEffects = 0; } UBOOL URtxRenderDevice::Init() @@ -43,9 +68,6 @@ UBOOL URtxRenderDevice::Init() InitSWRCFix(); } - RenderInterface.RenDev = this; - RenderInterface.Impl = NULL; - ClearMaterialFlags(); UClient* Client = UTexture::__Client; Client->Shadows = 0; @@ -53,29 +75,28 @@ UBOOL URtxRenderDevice::Init() Client->BloomQuality = 0; Client->BlurEnabled = 0; Client->BumpmappingQuality = 0; - // Client->Projectors = 0; GetDefault()->bVisor = 0; GetDefault()->VisorModeDefault = 1; - UseStencil = 0; + + Rtx = new(this) URtxInterface; return Super::Init(); } +void URtxRenderDevice::Exit(UViewport* Viewport) +{ + Rtx->Exit(); + delete Rtx; + Rtx = NULL; + Super::Exit(Viewport); +} + UBOOL URtxRenderDevice::SetRes(UViewport* Viewport, INT NewX, INT NewY, UBOOL Fullscreen, INT ColorBytes, UBOOL bSaveSize) { UBOOL Result = Super::SetRes(Viewport, NewX, NewY, Fullscreen, ColorBytes, bSaveSize); - if(Result && !BridgeInterface.initialized) - { - debugf("Initializing remix bridge API"); - if(bridgeapi_initialize(&BridgeInterface) != BRIDGEAPI_ERROR_CODE_SUCCESS || !BridgeInterface.initialized) - { - appErrorf("Failed to initialize remix bridge API"); - return 0; - } - - BridgeInterface.RegisterDevice(); - } + if(Result) + Rtx->Init(); return Result; } @@ -96,181 +117,69 @@ FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT Viewport->Actor->VisorModeDefault = 1; } - RenderInterface.Impl = Super::Lock(Viewport, HitData, HitSize); - return RenderInterface.Impl ? &RenderInterface : NULL; + FRenderInterface* RI = Super::Lock(Viewport, HitData, HitSize); + + if(!RI) + return NULL; + + D3D = RI; + + return this; } -struct FLightHandle{ - uint64_t Handle; - UBOOL bUsed; -}; -class RTXDRV_API UConstantColorMaterial : public UConstantMaterial{ -public: - DECLARE_CLASS(UConstantColorMaterial,UConstantMaterial,0,RtxDrv) - virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0); } +struct FProjectileLight{ + URtxLight* Light; + UBOOL bUsed; }; -IMPLEMENT_CLASS(UConstantColorMaterial) void URtxRenderDevice::Unlock(FRenderInterface* RI) { - typedef TMap FHandleMap; - static FHandleMap HandleMap; + typedef TMap FProjLightMap; + static FProjLightMap ProjLights; foreach(AllActors, AProjectile, Proj, static_cast(GEngine)->GLevel) { - FLightHandle* HandlePtr = HandleMap.Find(*Proj); - - if(HandlePtr) - { - if(HandlePtr->Handle) - BridgeInterface.DestroyLight(HandlePtr->Handle); - } - else - { - HandlePtr = &HandleMap[*Proj]; - } + FProjectileLight* ProjLight = ProjLights.Find(*Proj); - x86::remixapi_LightInfo l; - l.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO; - l.hash = reinterpret_cast(*Proj); - - FPlane Col = FGetHSV(Proj->LightHue, Proj->LightSaturation, Proj->LightBrightness) * 1000; - - l.radiance.x = Col.X; - l.radiance.y = Col.Y; - l.radiance.z = Col.Z; + if(!ProjLight) + ProjLight = &ProjLights[*Proj]; + FPlane Col = FGetHSV(Proj->LightHue, Proj->LightSaturation, Proj->LightBrightness) * 10000; FVector Loc = Proj->Location; - DECLARE_NAME(GrenadeProj); - if(Proj->IsA(NGrenadeProj)) - { - x86::remixapi_LightInfoSphereEXT s; - s.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT; - s.position.x = Loc.X; - s.position.y = Loc.Y; - s.position.z = Loc.Z; - s.radius = 32.0f; - s.shaping_hasvalue = FALSE; - s.shaping_value.direction.x = 0.0f; - s.shaping_value.direction.y = 0.0f; - s.shaping_value.direction.z = 1.0f; - s.shaping_value.coneAngleDegrees = 80.0f; - s.shaping_value.coneSoftness = 1.0f; - s.shaping_value.focusExponent = 0.0f; - HandlePtr->Handle = BridgeInterface.CreateSphereLight(&l, &s); - } - else - { - x86::remixapi_LightInfoCylinderEXT s; - FVector Dir = Proj->Rotation.Vector().GetNormalized(); - s.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT; - s.position.x = Loc.X; - s.position.y = Loc.Y; - s.position.z = Loc.Z; - s.axis.x = Dir.X; - s.axis.y = Dir.Y; - s.axis.z = Dir.Z; - s.axisLength = 200.0f; - s.radius = 2.5f; - HandlePtr->Handle = BridgeInterface.CreateCylinderLight(&l, &s); - } + if(!ProjLight->Light) + ProjLight->Light = Rtx->CreateLight(); - HandlePtr->bUsed = 1; + URtxLight* Light = ProjLight->Light; + Light->Type = RTXLIGHT_Sphere; + Light->Position = Loc; + Light->Radiance = Col; + Light->Sphere.Radius = 2.5f; + Light->Update(); - if(HandlePtr->Handle) - BridgeInterface.DrawLightInstance(HandlePtr->Handle); + ProjLight->bUsed = 1; } - for(FHandleMap::TIterator It(HandleMap); It; ++It) + for(FProjLightMap::TIterator It(ProjLights); It; ++It) { if(!It->bUsed) - HandleMap.Remove(It.Key()); - else - It->bUsed = 0; - } - - DECLARE_STATIC_UOBJECT(USolidColorMaterial, Material, {}); - DECLARE_STATIC_UOBJECT(UFinalBlend, FinalBlend, - { - FinalBlend->Material = Material; - FinalBlend->FrameBufferBlending = FB_Overwrite; - }); - FinalBlend->ColorWriteEnable = bShowAnchorTriangle; - - // Draw anchor triangle at world center to parent stuff to in remix - if(LockedViewport && LockedViewport->Actor) - { - AActor* ViewActor = LockedViewport->Actor; - FVector CameraLocation = ViewActor->Location; - FRotator CameraRotation = ViewActor->Rotation; - LockedViewport->Actor->PlayerCalcView(ViewActor, CameraLocation, CameraRotation); - - // Initialize the view matrix. - FMatrix WorldToCamera = FTranslationMatrix(-CameraLocation); - - if(!LockedViewport->IsOrtho()) - { - WorldToCamera = WorldToCamera * FInverseRotationMatrix(CameraRotation); - WorldToCamera = WorldToCamera * FMatrix( - FPlane(0, 0, 1, 0), - FPlane(LockedViewport->ScaleX, 0, 0, 0), - FPlane(0, LockedViewport->ScaleY, 0, 0), - FPlane(0, 0, 0, 1)); - } - else if(LockedViewport->Actor->RendMap == REN_OrthXY) - { - WorldToCamera = WorldToCamera * FMatrix( - FPlane(LockedViewport->ScaleX, 0, 0, 0), - FPlane(0, -LockedViewport->ScaleY, 0, 0), - FPlane(0, 0, -1, 0), - FPlane(0, 0, -CameraLocation.Z, 1)); - } - else if(LockedViewport->Actor->RendMap == REN_OrthXZ) - { - WorldToCamera = WorldToCamera * FMatrix( - FPlane(LockedViewport->ScaleX, 0, 0, 0), - FPlane(0, 0, -1, 0), - FPlane(0, LockedViewport->ScaleY, 0, 0), - FPlane(0, 0, -CameraLocation.Y, 1)); - } - else if(LockedViewport->Actor->RendMap == REN_OrthYZ) { - WorldToCamera = WorldToCamera * FMatrix( - FPlane(0, 0, 1, 0), - FPlane(LockedViewport->ScaleX, 0, 0, 0), - FPlane(0, LockedViewport->ScaleY, 0, 0), - FPlane(0, 0, CameraLocation.X, 1)); - } - - // Initialize the projection matrix. - FMatrix CameraToScreen; - if(LockedViewport->IsOrtho()) - { - const FLOAT Zoom = LockedViewport->Actor->OrthoZoom / (LockedViewport->SizeX * 15.0f); - CameraToScreen = FOrthoMatrix(Zoom * LockedViewport->SizeX / 2,Zoom * LockedViewport->SizeY / 2, 0.5f / HALF_WORLD_MAX, HALF_WORLD_MAX); + Rtx->DestroyLight(It.Value().Light); + ProjLights.Remove(It.Key()); } else { - const FLOAT FOV = LockedViewport->Actor->FovAngle * PI / 360.0f; - CameraToScreen = FPerspectiveMatrix(FOV, FOV, 1.0f, (FLOAT)LockedViewport->SizeX / LockedViewport->SizeY, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); + It->bUsed = 0; } - - RenderInterface.PushState(); - RenderInterface.SetTransform(TT_LocalToWorld, FMatrix::Identity); - RenderInterface.SetTransform(TT_WorldToCamera, WorldToCamera); - RenderInterface.SetTransform(TT_CameraToScreen, CameraToScreen); - RenderInterface.SetMaterial(FinalBlend); - RenderInterface.SetIndexBuffer(NULL, 0); - FVertexStream* Stream = &AnchorTriangle; - RenderInterface.SetVertexStreams(VS_FixedFunction, &Stream, 1); - RenderInterface.DrawPrimitive(PT_TriangleList, 0, 1); - RenderInterface.PopState(); } + Rtx->RenderLights(); + + DrawAnchorTriangle(); LockedViewport = NULL; + D3D = NULL; - Super::Unlock(static_cast(RI)->Impl); + Super::Unlock(static_cast(RI)->D3D); } void URtxRenderDevice::Present(UViewport* Viewport) @@ -278,60 +187,171 @@ void URtxRenderDevice::Present(UViewport* Viewport) Super::Present(Viewport); } -FRenderCaps* URtxRenderDevice::GetRenderCaps() +void URtxRenderDevice::ClearMaterialFlags() { - return Super::GetRenderCaps(); - // static FRenderCaps RenderCaps(1, 14, 1); + foreachobj(UMaterial, Material) + reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); +} + +/* + * Draw anchor triangle at world center to parent assets to in remix + */ + +class FSingleTriangleVertexStream : public FVertexStream{ +public: + FSingleTriangleVertexStream(FLOAT Width, FLOAT Height) : HalfWidth(Width / 2), HalfHeight(Height / 2) + { + CacheId = MakeCacheID(CID_RenderVertices); + } + + FLOAT HalfWidth; + FLOAT HalfHeight; + + virtual INT GetStride(){ return sizeof(FVector); } + virtual INT GetSize(){ return sizeof(FVector) * 3; } + + virtual INT GetComponents(FVertexComponent* Components) + { + Components->Type = CT_Float3; + Components->Function = FVF_Position; + return 1; + } + + virtual void GetStreamData(void* Dest) + { + FVector* D = static_cast(Dest); + D[0] = FVector(-HalfWidth, -HalfHeight, 0); + D[1] = FVector(HalfHeight, -HalfHeight, 0); + D[2] = FVector(0, HalfHeight, 0); + } +}; + +class USolidColorMaterial : public UConstantMaterial{ + DECLARE_CLASS(USolidColorMaterial,UConstantMaterial,0,RtxDrv) +public: + virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0,255); } +}; +IMPLEMENT_CLASS(USolidColorMaterial) + +void URtxRenderDevice::DrawAnchorTriangle() +{ + if(!LockedViewport || !LockedViewport->Actor) + return; + + AActor* ViewActor = LockedViewport->Actor; + FVector CameraLocation = ViewActor->Location; + FRotator CameraRotation = ViewActor->Rotation; + LockedViewport->Actor->PlayerCalcView(ViewActor, CameraLocation, CameraRotation); - // return &RenderCaps; + // Initialize the view matrix. + FMatrix WorldToCamera = FTranslationMatrix(-CameraLocation); + + if(!LockedViewport->IsOrtho()) + { + WorldToCamera = WorldToCamera * FInverseRotationMatrix(CameraRotation); + WorldToCamera = WorldToCamera * FMatrix( + FPlane(0, 0, 1, 0), + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, 0, 1)); + } + else if(LockedViewport->Actor->RendMap == REN_OrthXY) + { + WorldToCamera = WorldToCamera * FMatrix( + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, -LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, -1, 0), + FPlane(0, 0, -CameraLocation.Z, 1)); + } + else if(LockedViewport->Actor->RendMap == REN_OrthXZ) + { + WorldToCamera = WorldToCamera * FMatrix( + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, 0, -1, 0), + FPlane(0, LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, -CameraLocation.Y, 1)); + } + else if(LockedViewport->Actor->RendMap == REN_OrthYZ) + { + WorldToCamera = WorldToCamera * FMatrix( + FPlane(0, 0, 1, 0), + FPlane(LockedViewport->ScaleX, 0, 0, 0), + FPlane(0, LockedViewport->ScaleY, 0, 0), + FPlane(0, 0, CameraLocation.X, 1)); + } + + // Initialize the projection matrix. + FMatrix CameraToScreen; + if(LockedViewport->IsOrtho()) + { + const FLOAT Zoom = LockedViewport->Actor->OrthoZoom / (LockedViewport->SizeX * 15.0f); + CameraToScreen = FOrthoMatrix(Zoom * LockedViewport->SizeX / 2,Zoom * LockedViewport->SizeY / 2, 0.5f / HALF_WORLD_MAX, HALF_WORLD_MAX); + } + else + { + const FLOAT FOV = LockedViewport->Actor->FovAngle * PI / 360.0f; + CameraToScreen = FPerspectiveMatrix(FOV, FOV, 1.0f, (FLOAT)LockedViewport->SizeX / LockedViewport->SizeY, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE); + } + + // Material + DECLARE_STATIC_UOBJECT(USolidColorMaterial, Material, {}); + DECLARE_STATIC_UOBJECT(UFinalBlend, FinalBlend, + { + FinalBlend->Material = Material; + FinalBlend->FrameBufferBlending = FB_Overwrite; + }); + FinalBlend->ColorWriteEnable = Rtx->bShowAnchorTriangle; + + PushState(); + SetTransform(TT_LocalToWorld, FMatrix::Identity); + SetTransform(TT_WorldToCamera, WorldToCamera); + SetTransform(TT_CameraToScreen, CameraToScreen); + SetMaterial(FinalBlend); + SetIndexBuffer(NULL, 0); + static FSingleTriangleVertexStream AnchorTriangle(512, 512); + FVertexStream* Stream = &AnchorTriangle; + SetVertexStreams(VS_FixedFunction, &Stream, 1); + DrawPrimitive(PT_TriangleList, 0, 1); + PopState(); } -UBOOL FRtxRenderInterface::SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer) +/* + * FRenderInterface + */ + +UBOOL URtxRenderDevice::SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer) { - debugf("SETRENDERTARGET: %p", RenderTarget); - return Impl->SetRenderTarget(RenderTarget, bOwnDepthBuffer); + return D3D->SetRenderTarget(RenderTarget, bOwnDepthBuffer); } -void FRtxRenderInterface::Clear(UBOOL UseColor, FColor Color, UBOOL UseDepth, FLOAT Depth, UBOOL UseStencil, DWORD Stencil) +void URtxRenderDevice::Clear(UBOOL UseColor, FColor Color, UBOOL UseDepth, FLOAT Depth, UBOOL UseStencil, DWORD Stencil) { - Impl->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); + D3D->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); } -void FRtxRenderInterface::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue){ +void URtxRenderDevice::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue){ UseDynamic = 0; Lightmap = NULL; Modulate2X = 0; - Impl->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); -} - -void FRtxRenderInterface::SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale) -{ - if(RenDev->bEnableD3DLights) - Impl->SetLight(LightIndex, Light, Scale); -} - -void FRtxRenderInterface::SetTransform(ETransformType Type, const FMatrix& Matrix) -{ - Impl->SetTransform(Type, Matrix); + D3D->EnableLighting(UseDynamic, UseStatic, Modulate2X, Lightmap, LightingOnly, LitSphere, IntValue); } -void FRtxRenderInterface::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) +void URtxRenderDevice::SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale) { - Impl->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); + // Impl->SetLight(LightIndex, Light, Scale); } -void FRtxRenderInterface::DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex, INT MaxIndex) +void URtxRenderDevice::SetTransform(ETransformType Type, const FMatrix& Matrix) { - Impl->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); + D3D->SetTransform(Type, Matrix); } -void URtxRenderDevice::ClearMaterialFlags() +void URtxRenderDevice::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) { - foreachobj(UMaterial, Material) - reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); + D3D->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); } -void URtx::execTestFunc(FFrame& Stack, void* Result) +void URtxRenderDevice::DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex, INT MaxIndex) { - + D3D->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); } diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 1d5f95e5..700b5d7a 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -1,112 +1,73 @@ #pragma once #include "../../D3DDrv/Inc/D3DDrv.h" -#include "bridge_c.h" -#ifndef RTXDRV_API -#define RTXDRV_API DLL_IMPORT -#endif +class URtxInterface; -class URtxRenderDevice; - -class FSingleTriangleVertexStream : public FVertexStream{ +class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ + DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) + static const TCHAR* StaticConfigName(){ return "RtxDrv"; } public: - FSingleTriangleVertexStream(FLOAT Width, FLOAT Height) : HalfWidth(Width / 2), HalfHeight(Height / 2) - { - CacheId = MakeCacheID(CID_RenderVertices); - } - - FLOAT HalfWidth; - FLOAT HalfHeight; - - virtual INT GetStride(){ return sizeof(FVector); } - virtual INT GetSize(){ return sizeof(FVector) * 3; } + void StaticConstructor(); - virtual INT GetComponents(FVertexComponent* Components) - { - Components->Type = CT_Float3; - Components->Function = FVF_Position; - return 1; - } + virtual void Serialize(FArchive& Ar); + virtual UBOOL Exec(const TCHAR* Cmd, FOutputDevice& Ar); + virtual UBOOL Init(); + virtual void Exit(UViewport* Viewport); + virtual UBOOL SetRes(UViewport* Viewport, INT NewX, INT NewY, UBOOL Fullscreen, INT ColorBytes = 0, UBOOL bSaveSize = true); + virtual void Flush(UViewport* Viewport); + virtual FRenderInterface* Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize); + virtual void Unlock(FRenderInterface* RI); + virtual void Present(UViewport* Viewport); - virtual void GetStreamData(void* Dest) - { - FVector* D = static_cast(Dest); - D[0] = FVector(-HalfWidth, -HalfHeight, 0); - D[1] = FVector(HalfHeight, -HalfHeight, 0); - D[2] = FVector(0, HalfHeight, 0); - } -}; + URtxInterface* GetRtxInterface(){ return Rtx; } -class FRtxRenderInterface : public FRenderInterface{ -public: - URtxRenderDevice* RenDev; - FRenderInterface* Impl; + // FRenderInterface - virtual void PushState(DWORD Flags = 0){ Impl->PushState(Flags); } - virtual void PopState(DWORD Flags = 0){ Impl->PopState(Flags); } + virtual void PushState(DWORD Flags = 0){ D3D->PushState(Flags); } + virtual void PopState(DWORD Flags = 0){ D3D->PopState(Flags); } virtual UBOOL SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDepthBuffer); - virtual void SetViewport(INT X, INT Y, INT Width, INT Height){ Impl->SetViewport(X, Y, Width, Height); } + virtual void SetViewport(INT X, INT Y, INT Width, INT Height){ D3D->SetViewport(X, Y, Width, Height); } virtual void Clear(UBOOL UseColor = 1, FColor Color = FColor(0, 0, 0), UBOOL UseDepth = 1, FLOAT Depth = 1.0f, UBOOL UseStencil = 1, DWORD Stencil = 0); - virtual void PushHit(const BYTE* Data, INT Count){ Impl->PushHit(Data, Count); } - virtual void PopHit(INT Count, UBOOL Force){ Impl->PopHit(Count, Force); } - virtual void SetCullMode(ECullMode CullMode){ Impl->SetCullMode(CullMode); } + virtual void PushHit(const BYTE* Data, INT Count){ D3D->PushHit(Data, Count); } + virtual void PopHit(INT Count, UBOOL Force){ D3D->PopHit(Count, Force); } + virtual void SetCullMode(ECullMode CullMode){ D3D->SetCullMode(CullMode); } virtual void SetAmbientLight(FColor Color){} virtual void EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue); virtual void SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f); virtual void SetShaderLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale = 1.0f){} - virtual void SetNPatchTesselation(FLOAT Tesselation){ Impl->SetNPatchTesselation(Tesselation); } - virtual void SetDistanceFog(UBOOL Enable, FLOAT FogStart, FLOAT FogEnd, FColor Color){ Impl->SetDistanceFog(0, 0.0f, 0.0f, FColor()); } - virtual UBOOL EnableFog(UBOOL Enable){ return Impl->EnableFog(0); } - virtual UBOOL IsFogEnabled(){ return Impl->IsFogEnabled(); } - virtual void SetGlobalColor(FColor Color){ Impl->SetGlobalColor(Color); } + virtual void SetNPatchTesselation(FLOAT Tesselation){ D3D->SetNPatchTesselation(Tesselation); } + virtual void SetDistanceFog(UBOOL Enable, FLOAT FogStart, FLOAT FogEnd, FColor Color){ D3D->SetDistanceFog(0, 0.0f, 0.0f, FColor()); } + virtual UBOOL EnableFog(UBOOL Enable){ return D3D->EnableFog(0); } + virtual UBOOL IsFogEnabled(){ return D3D->IsFogEnabled(); } + virtual void SetGlobalColor(FColor Color){ D3D->SetGlobalColor(Color); } virtual void SetTransform(ETransformType Type, const FMatrix& Matrix); - virtual FMatrix GetTransform(ETransformType Type) const { return Impl->GetTransform(Type); } + virtual FMatrix GetTransform(ETransformType Type) const { return D3D->GetTransform(Type); } virtual void SetMaterial(UMaterial* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL, INT* NumPasses = NULL); - virtual UBOOL SetHardwareShaderMaterial(UHardwareShader* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL){ return Impl->SetHardwareShaderMaterial(Material, ErrorString, ErrorMaterial); } - virtual UBOOL ShowAlpha(UMaterial* Material){ return Impl->ShowAlpha(Material); } + virtual UBOOL SetHardwareShaderMaterial(UHardwareShader* Material, FString* ErrorString = NULL, UMaterial** ErrorMaterial = NULL){ return D3D->SetHardwareShaderMaterial(Material, ErrorString, ErrorMaterial); } + virtual UBOOL ShowAlpha(UMaterial* Material){ return D3D->ShowAlpha(Material); } virtual UBOOL IsShadowInterface(){ return 0; } virtual void SetAntiAliasing(INT Level){} - virtual void CopyBackBufferToTarget(FAuxRenderTarget* Target){ Impl->CopyBackBufferToTarget(Target); } - virtual void SetLODDiffuseFade(FLOAT Distance){ Impl->SetLODDiffuseFade(Distance); } - virtual void SetLODSpecularFade(FLOAT Distance){ Impl->SetLODSpecularFade(Distance); } + virtual void CopyBackBufferToTarget(FAuxRenderTarget* Target){ D3D->CopyBackBufferToTarget(Target); } + virtual void SetLODDiffuseFade(FLOAT Distance){ D3D->SetLODDiffuseFade(Distance); } + virtual void SetLODSpecularFade(FLOAT Distance){ D3D->SetLODSpecularFade(Distance); } virtual void SetStencilOp(ECompareFunction Test, DWORD Ref, DWORD Mask, EStencilOp FailOp, EStencilOp ZFailOp, EStencilOp PassOp, DWORD WriteMask){} virtual void EnableStencil(UBOOL Enable){} - virtual void EnableDepth(UBOOL Enable){ Impl->EnableDepth(Enable); } - virtual void SetPrecacheMode(EPrecacheMode PrecacheMode){ Impl->SetPrecacheMode(PrecacheMode); } - virtual void SetZBias(INT ZBias){ Impl->SetZBias(ZBias); } - virtual INT SetVertexStreams(EVertexShader Shader, FVertexStream** Streams, INT NumStreams){ return Impl->SetVertexStreams(Shader, Streams, NumStreams); } - virtual INT SetDynamicStream(EVertexShader Shader, FVertexStream* Stream){ return Impl->SetDynamicStream(Shader, Stream); } - virtual INT SetIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetIndexBuffer(IndexBuffer, BaseIndex); } - virtual INT SetDynamicIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return Impl->SetDynamicIndexBuffer(IndexBuffer, BaseIndex); } + virtual void EnableDepth(UBOOL Enable){ D3D->EnableDepth(Enable); } + virtual void SetPrecacheMode(EPrecacheMode){ D3D->SetPrecacheMode(PRECACHE_All); } + virtual void SetZBias(INT ZBias){ D3D->SetZBias(ZBias); } + virtual INT SetVertexStreams(EVertexShader Shader, FVertexStream** Streams, INT NumStreams){ return D3D->SetVertexStreams(Shader, Streams, NumStreams); } + virtual INT SetDynamicStream(EVertexShader Shader, FVertexStream* Stream){ return D3D->SetDynamicStream(Shader, Stream); } + virtual INT SetIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return D3D->SetIndexBuffer(IndexBuffer, BaseIndex); } + virtual INT SetDynamicIndexBuffer(FIndexBuffer* IndexBuffer, INT BaseIndex){ return D3D->SetDynamicIndexBuffer(IndexBuffer, BaseIndex); } virtual void DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex = INDEX_NONE, INT MaxIndex = INDEX_NONE); - virtual void SetFillMode(EFillMode FillMode){ Impl->SetFillMode(FillMode); } -}; - -class RTXDRV_API URtxRenderDevice : public UD3DRenderDevice{ - DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) - static const TCHAR* StaticConfigName(){ return "RtxDrv"; } -public: - URtxRenderDevice() : AnchorTriangle(512, 512){} - void StaticConstructor(); - - UBOOL bShowAnchorTriangle; - UBOOL bEnableD3DLights; - - virtual UBOOL Exec(const TCHAR* Cmd, FOutputDevice& Ar); - virtual UBOOL Init(); - virtual UBOOL SetRes(UViewport* Viewport, INT NewX, INT NewY, UBOOL Fullscreen, INT ColorBytes = 0, UBOOL bSaveSize = true); - virtual void Flush(UViewport* Viewport); - virtual FRenderInterface* Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize); - virtual void Unlock(FRenderInterface* RI); - virtual void Present(UViewport* Viewport); - virtual FRenderCaps* GetRenderCaps(); + virtual void SetFillMode(EFillMode FillMode){ D3D->SetFillMode(FillMode); } private: - UViewport* LockedViewport; - bridgeapi_Interface BridgeInterface; - FSingleTriangleVertexStream AnchorTriangle; - FRtxRenderInterface RenderInterface; + UViewport* LockedViewport; + FRenderInterface* D3D; + URtxInterface* Rtx; void ClearMaterialFlags(); + void DrawAnchorTriangle(); }; From b9e4bd02df3d9c9311e7d8aa520f76d92c0e6e5f Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sun, 11 Aug 2024 20:26:22 +0200 Subject: [PATCH 13/48] Clean up TArray --- Core/Inc/UnTemplate.h | 511 ++++++++++++++++++------------------------ RtxDrv/Src/Rtx.cpp | 3 +- 2 files changed, 223 insertions(+), 291 deletions(-) diff --git a/Core/Inc/UnTemplate.h b/Core/Inc/UnTemplate.h index b3aba5af..562ac540 100644 --- a/Core/Inc/UnTemplate.h +++ b/Core/Inc/UnTemplate.h @@ -149,17 +149,8 @@ class TArray : public FArray{ TArray() : FArray(){} //TArray(T* Src, INT Count) : FArray(Src, Count){} // Should not be used due to a memory leak in Core.dll TArray(ENoInit) : FArray(E_NoInit){} - - TArray(INT Size, bool NoShrink = false) : FArray(NoShrink) - { - Set(Size); - } - - TArray(const TArray& other, bool NoShrink = false) - { - bNoShrink = NoShrink; - *this = other; - } + TArray(INT Size, bool NoShrink = false) : FArray(NoShrink){ Set(Size); } + TArray(const TArray& other, bool NoShrink = false){ bNoShrink = NoShrink; *this = other; } ~TArray() { @@ -173,135 +164,111 @@ class TArray : public FArray{ ArrayNum = 0; } - TArray& operator=(const TArray& Other) - { - if(this != &Other) - { - if(Other.bIsReference || Other.bIsTemporary) - { - Transfer(const_cast&>(Other)); - } - else - { - Empty(Other.ArrayNum); - - // It is assumed that a type is not trivially copyable if it needs a destructor which should be true in pretty much any case - if(TTypeInfo::NeedsDestructor()) - { - for(INT i = 0; i < Other.ArrayNum; ++i) - new(*this)T(Other[i]); - } - else - { - appMemcpy(Data, Other.Data, Other.ArrayNum * sizeof(T)); - ArrayNum = Other.ArrayNum; - } - } - } + T* GetData(){ return static_cast(Data); } + const T* GetData() const{ return static_cast(Data); } + INT Num() const{ return ArrayNum; } + bool IsAllocated() const{ return Data != NULL && !bIsReference; } + INT GetMaxSize() const{ return Capacity(); } - return *this; - } + /* + * Create/Copy + */ - TArray operator+(const TArray& Other) + TArray& operator=(const TArray& Other) { - TArray Result(*this); - - Result.Reserve(Result.Num() + Other.Num()); + if(this == &Other) + return *this; - if(TTypeInfo::NeedsDestructor()) + if(Other.bIsReference || Other.bIsTemporary) { - for(INT i = 0; i < Other.ArrayNum; ++i) - new(Result)T(Other[i]); + Transfer(const_cast&>(Other)); } else { - appMemcpy(static_cast(Result.Data) + Result.Num(), Other.Data, Other.ArrayNum * sizeof(T)); - Result.ArrayNum += Other.ArrayNum; + Empty(Other.ArrayNum); + *this += Other; } - Result.bIsTemporary |= 1; + return *this; + } + TArray operator+(const TArray& Other) + { + TArray Result(*this); + Result += Other; + Result.bIsTemporary = 1; return Result; } TArray& operator+=(const TArray& Other) { - Reserve(Num() + Other.Num()); - + // It is assumed that a type is not trivially copyable if it needs a destructor which should be true in pretty much any case if(TTypeInfo::NeedsDestructor()) { + const INT Idx = AddZeroed(Other.Num()); for(INT i = 0; i < Other.ArrayNum; ++i) - new(*this)T(Other[i]); + new(GetData() + Idx + i) T(Other[i]); } else { - appMemcpy(GetData() + Num(), Other.Data, Other.ArrayNum * sizeof(T)); + const INT RequiredCapacity = Num() + Other.Num(); + if(Capacity() < RequiredCapacity) + Reserve(RequiredCapacity); + + appMemcpy(GetData() + Num(), Other.GetData(), Other.Num() * sizeof(T)); ArrayNum += Other.ArrayNum; } return *this; } - T& operator[](INT Index) - { - checkSlow(IsValidIndex(Index)); - return GetData()[Index]; - } - - const T& operator[](INT Index) const{ - checkSlow(IsValidIndex(Index)); - return GetData()[Index]; - } - void Transfer(TArray& Src) { Empty(); - Data = Src.Data; ArrayNum = Src.ArrayNum; bIsReference = Src.bIsReference; bNoShrink = Src.bNoShrink; - Src.Unreference(); } - void Set(T* Src, INT Count) + TArray Segment(INT Index, INT Count) { - Data = Src; - ArrayNum = Count; + TArray Result; + Result.Data = &At(Index); + Result.ArrayNum = Count; + Result.Unreference(); + return Result; } - void Set(INT NewSize, INT Slack) - { - INT OldNum = Num(); + /* + * Access items + */ - if(NewSize >= Num()) - { - Realloc(NewSize, Slack); + bool IsValidIndex(INT Index) const{ return Index >= 0 && Index < Num(); } - if(Num() > OldNum) - appMemzero(static_cast(Data) + OldNum, (Num() - OldNum) * sizeof(T)); - } - else - { - Remove(NewSize, Num() - NewSize); - } + T& At(INT Index) + { + checkSlow(IsValidIndex(Index)); + return GetData()[Index]; } - void Set(INT NewSize){ Set(NewSize, NewSize); } - T* GetData(){ return static_cast(Data); } - const T* GetData() const{ return static_cast(Data); } - bool IsValidIndex(INT Index) const{ return Index >= 0 && Index < Num(); } - INT Num() const{ return ArrayNum; } - INT Size() const{ return Num(); } - bool IsAllocated() const{ return Data != NULL && !bIsReference; } - T& Last(INT c = 0){ return (*this)[Num() - c - 1]; } - const T& Last(INT c = 0) const{ return (*this)[Num() - c - 1]; } + const T& At(INT Index) const + { + checkSlow(IsValidIndex(Index)); + return GetData()[Index]; + } + + T& operator[](INT Index){ return At(Index); } + const T& operator[](INT Index) const{ return At(Index); } + + T& Last(INT c = 0){ return At(Num() - c - 1); } + const T& Last(INT c = 0) const{ return At(Num() - c - 1); } bool FindItem(const T& Item, INT& Index) const{ for(Index = 0; Index < Num(); ++Index) { - if((*this)[Index] == Item) + if(GetData()[Index] == Item) return true; } @@ -317,133 +284,130 @@ class TArray : public FArray{ return INDEX_NONE; } - void SetNoShrink(bool NoShrink) + /* + * Grow/Shrink/Clear + */ + + void Set(T* Src, INT Count) { - if(NoShrink) - bNoShrink |= 1; - else - bNoShrink = 0; + Data = Src; + ArrayNum = Count; } - void CountBytes(FArchive& Ar){ Ar.CountBytes(Data, Num() * sizeof(T)); } - INT GetMaxSize() const{ return Capacity(); } - - void Serialize(FArchive& Ar) + void Set(INT NewSize, INT Slack) { - guard(MyTArray::Serialize); - CountBytes(Ar); - - INT TempNum = Num(); - - if(sizeof(T) == 1) - { - // Serialize simple bytes which require no construction or destruction. - if(Ar.IsLoading()) - { - Ar << AR_INDEX(TempNum); - Realloc(TempNum, 0); - } - else - { - Ar << AR_INDEX(TempNum); - } - - Ar.Serialize(&(*this)[0], Num()); - } - else if(Ar.IsLoading()) + if(NewSize > Num()) { - // Load array. - - Ar << AR_INDEX(TempNum); - - Empty(TempNum); - - for(INT i = 0; i < TempNum; ++i) - Ar << *new(*this)T; + Reserve(Max(NewSize, Slack)); + AddZeroed(NewSize - Num()); } else { - // Save array. - Ar << AR_INDEX(TempNum); - - for(INT i = 0; i < Num(); ++i) - Ar << (*this)[i]; + Deinit(NewSize, Num() - NewSize); + Realloc(NewSize, Slack); } + } - unguard; + void Set(INT NewSize){ Set(NewSize, NewSize); } + void SetNoShrink(bool NoShrink){ bNoShrink = NoShrink; } + void Shrink(){ Realloc(Num(), Num()); } + + void Empty(INT Slack = 0) + { + Deinit(0, ArrayNum); + Realloc(0, Slack); } void Reserve(INT Size) { - INT CurrentSize = IsAllocated() ? 0 : Capacity(); - - Realloc(Num(), CurrentSize < Size ? Size : CurrentSize); + if(Capacity() < Size) + Realloc(Num(), Size); } - void Insert(INT Index, INT Count = 1, bool bInit = true) + /* + * Add + */ + + INT Add(INT Count, bool bInit = true) { + const INT FirstIdx = Num(); Realloc(Num() + Count, 0); - appMemmove( - static_cast(Data) + (Index + Count) * sizeof(T), - static_cast(Data) + Index * sizeof(T), - (Num() - Index - Count) * sizeof(T) - ); - if(bInit) - Init(Index, Count); + Init(FirstIdx, Count); + + return FirstIdx; } - INT Add(INT Count, bool bInit = true) + INT AddZeroed(INT Count = 1) { + const INT FirstIdx = Num(); Realloc(Num() + Count, 0); - - if(bInit) - Init(Num() - Count, Count); - - return Num() - Count; + appMemzero(GetData() + FirstIdx, Count * sizeof(T)); + return FirstIdx; } - void InsertZeroed(INT Index, INT Count) + INT AddItem(const T& Item) { - Insert(Index, Count); - appMemzero(static_cast(Data) + Index * sizeof(T), Count * sizeof(T)); + Add(1, false); + new(&Last()) T(Item); + return Num() - 1; } - INT AddZeroed(INT Count = 1) + INT AddUniqueItem(const T& Item) { - INT Index = Add(Count); + const INT Index = FindItemIndex(Item); - appMemzero(static_cast(Data) + Index * sizeof(T), Count * sizeof(T)); + if(Index != INDEX_NONE) + return Index; - return Index; + return AddItem(Item); } - void Shrink() + /* + * Insert + */ + + void Insert(INT Index, INT Count = 1, bool bInit = true) { - Realloc(Num(), Num()); + const INT MoveCount = Num() - Index; + Realloc(Num() + Count, 0); + appMemmove( + GetData() + Index + Count, + GetData() + Index, + MoveCount * sizeof(T) + ); + + if(bInit) + Init(Index, Count); } - void Empty(INT Slack = 0) + void InsertZeroed(INT Index, INT Count) { - Deinit(0, ArrayNum); - Realloc(0, Slack); + Insert(Index, Count, false); + appMemzero(GetData() + Index, Count * sizeof(T)); } - void Remove(INT Index, INT Count = 1) + void InsertItem(INT Index, const T& Item) { - Deinit(Index, Count); + Insert(Index, 1, false); + new(GetData() + Index) T(Item); + } - if(Count) - { - appMemmove( - static_cast(Data) + Index * sizeof(T), - static_cast(Data) + (Index + Count) * sizeof(T), - (Num() - Index - Count) * sizeof(T) - ); + /* + * Remove + */ - Realloc(Num() - Count, 0); - } + void Remove(INT Index, INT Count = 1) + { + const INT MoveCount = Num() - Index - Count; + Deinit(Index, Count); + appMemmove( + GetData() + Index, + GetData() + Index + Count, + MoveCount * sizeof(T) + ); + Realloc(Num() - Count, 0); } INT RemoveItem(const T& Item) @@ -464,30 +428,56 @@ class TArray : public FArray{ return GetData()[ArrayNum]; } - INT AddItem(const T& Item) - { - new(*this) T(Item); + /* + * Serialize + */ - return Num() - 1; - } + void CountBytes(FArchive& Ar){ Ar.CountBytes(Data, Num() * sizeof(T)); } - INT AddUniqueItem(const T& Item) + void Serialize(FArchive& Ar) { - INT Index = FindItemIndex(Item); + guard(MyTArray::Serialize); + CountBytes(Ar); - return Index != INDEX_NONE ? Index : AddItem(Item); - } + INT TempNum = Num(); - TArray Segment(INT Index, INT Count) - { - TArray Result; + if(sizeof(T) == 1) + { + // Serialize simple bytes which require no construction or destruction. + if(Ar.IsLoading()) + { + Ar << AR_INDEX(TempNum); + Realloc(TempNum, 0); + } + else + { + Ar << AR_INDEX(TempNum); + } - Result.Data = &(*this)[Index]; - Result.ArrayNum = Count; + Ar.Serialize(GetData(), Num()); + } + else if(Ar.IsLoading()) + { + // Load array. - Result.Unreference(); + Ar << AR_INDEX(TempNum); - return Result; + Empty(TempNum); + AddZeroed(TempNum); + + for(INT i = 0; i < TempNum; ++i) + Ar << GetData()[i]; + } + else + { + // Save array. + Ar << AR_INDEX(TempNum); + + for(INT i = 0; i < Num(); ++i) + Ar << GetData()[i]; + } + + unguard; } // Iterator @@ -534,7 +524,7 @@ class TArray : public FArray{ if(TTypeInfo::NeedsDestructor()) { for(INT i = Index; i < Index + Count; ++i) - (&(*this)[i])->~T(); + (&(GetData()[i]))->~T(); } } @@ -549,7 +539,7 @@ class TArray : public FArray{ if(!bNoShrink && ArrayNum >= 0 && Align(NewSize * sizeof(T), 32) < Align(Num() * sizeof(T), 32)) Data = appRealloc(Data, NewSize * sizeof(T), Max(NewSize, Slack) * sizeof(T)); } - else + else if(Capacity() < Max(NewSize, Slack)) { Data = appRealloc(Data, NewSize * sizeof(T), Slack * sizeof(T)); } @@ -586,37 +576,35 @@ class TArray : public FArray{ } }; -template -class TArrayNoInit : public TArray{ -public: - TArrayNoInit() : TArray(E_NoInit){} - - TArrayNoInit& operator=(const TArrayNoInit& Other) - { - TArray::operator=(Other); - return *this; - } -}; - // // Array operator news. // template void* operator new(size_t Size, TArray& Array) { - INT Index = Array.Add(1); - + const INT Index = Array.Add(1, false); return &Array[Index]; } template void* operator new(size_t Size, TArray& Array, INT Index) { - Array.Insert(Index); - + Array.Insert(Index, 1, false); return &Array[Index]; } +template +class TArrayNoInit : public TArray{ +public: + TArrayNoInit() : TArray(E_NoInit){} + + TArrayNoInit& operator=(const TArrayNoInit& Other) + { + TArray::operator=(Other); + return *this; + } +}; + // // Array exchanger. // @@ -636,17 +624,9 @@ template class TTransArray : public TArray{ public: // Constructors. - TTransArray(UObject* InOwner, INT InNum = 0) : TArray(InNum), - Owner(InOwner){} - - TTransArray(UObject* InOwner, const TArray& Other) : TArray(Other), - Owner(InOwner){} - - TTransArray& operator=(const TTransArray& Other) - { - operator=((const TArray&)Other); - return *this; - } + TTransArray(UObject* InOwner, INT InNum = 0) : TArray(InNum), Owner(InOwner){} + TTransArray(UObject* InOwner, const TArray& Other) : TArray(Other), Owner(InOwner){} + TTransArray& operator=(const TTransArray& Other){ operator=((const TArray&)Other); return *this; } // Add, Insert, Remove, Empty interface. @@ -685,52 +665,12 @@ class TTransArray : public TArray{ // Functions dependent on Add, Remove. TTransArray& operator=(const TArray& Other) { - if(this != &Other) - { - Empty(Other.Num()); - - for(INT i = 0; i::operator=(other); return *this; } - INT AddItem(const T& Item) - { - new(*this) T(Item); - return Num() - 1; - } - - INT AddZeroed(INT n = 1) - { - INT Index = Add(n); - appMemzero(&(*this)[Index], n*sizeof(T)); - return Index; - } - - INT AddUniqueItem(const T& Item) - { - for(INT Index = 0; Index{ Ar << (TArray&)A; return Ar; } -protected: - static void SerializeItem(FArchive& Ar, void* TPtr) - { - Ar << *(T*)TPtr; - } - - static void DestructItem(void* TPtr) - { - ((T*)TPtr)->~T(); - } +protected: UObject* Owner; -private: + static void SerializeItem(FArchive& Ar, void* TPtr){ Ar << *(T*)TPtr; } + static void DestructItem(void* TPtr){ ((T*)TPtr)->~T(); } +private: // Disallow the copy constructor. TTransArray(const TArray& Other){} }; @@ -802,10 +735,7 @@ class FLazyLoader{ template class TLazyArray : public TArray, public FLazyLoader{ public: - TLazyArray(INT InNum = 0) - : TArray(InNum) - , FLazyLoader() - {} + TLazyArray(INT InNum = 0) : TArray(InNum), FLazyLoader(){} ~TLazyArray() { if(SavedAr) @@ -1224,30 +1154,33 @@ class TMapBase{ TI& Add(typename TTypeInfo::ConstInitType InKey, typename TTypeInfo::ConstInitType InValue) { - TPair& Pair = *new(Pairs)TPair(InKey, InValue); - INT iHash = (GetTypeHash(Pair.Key) & (HashCount-1)); + TPair& Pair = *(new(Pairs) TPair(InKey, InValue)); + const INT iHash = (GetTypeHash(Pair.Key) & (HashCount - 1)); + Pair.HashNext = Hash[iHash]; + Hash[iHash] = Pairs.Num() - 1; - Pair.HashNext = Hash[iHash]; - Hash[iHash] = Pairs.Num()-1; if(HashCount * 2 + 8 < Pairs.Num()) { HashCount *= 2; Rehash(); } + return Pair.Value; } public: - TMapBase() : Hash(NULL), - HashCount(8) - { + TMapBase() + : Hash(NULL), + HashCount(8) + { Rehash(); } - TMapBase(const TMapBase& Other) : Pairs(Other.Pairs), - HashCount(Other.HashCount), - Hash(NULL) - { + TMapBase(const TMapBase& Other) + : Pairs(Other.Pairs), + HashCount(Other.HashCount), + Hash(NULL) + { if(HashCount < 8) // Need to check this in case the other map was zero initialized without the constructor being called HashCount = 8; @@ -1438,7 +1371,7 @@ class TMultiMap : public TMapBase{ for(INT i = Hash[(GetTypeHash(Key) & (HashCount - 1))]; i != INDEX_NONE; i = Pairs[i].HashNext) { if(Pairs[i].Key == Key) - new(Values, 0) TI(Pairs[i].Value); + Values.InsertItem(0, Pairs[i].Value); } } diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 557f837c..6499954f 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -46,8 +46,7 @@ void URtxInterface::DestroyLight(URtxLight* Light) void URtxInterface::DestroyAllLights() { - INT Index = DestroyedLights.Add(Lights.Num(), false); - appMemcpy(&DestroyedLights[Index], &Lights[0], Lights.Num() * sizeof(URtxLight*)); + DestroyedLights += Lights; Lights.Empty(); } From 3512d0be66f73530867635fc0b282ae655a12bde Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sun, 11 Aug 2024 21:20:24 +0200 Subject: [PATCH 14/48] Add option to disable all lights --- Core/Inc/UnMath.h | 5 ++--- RtxDrv/Classes/RtxInterface.uc | 8 ++++++++ RtxDrv/Inc/RtxDrvClasses.h | 1 + RtxDrv/Src/Rtx.cpp | 7 +++---- RtxDrv/Src/RtxRenderDevice.cpp | 8 +++++--- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Core/Inc/UnMath.h b/Core/Inc/UnMath.h index ee673ee0..c842c8f9 100644 --- a/Core/Inc/UnMath.h +++ b/Core/Inc/UnMath.h @@ -322,14 +322,13 @@ class FVector{ } else return 0; } - FVector GetNormalized() + FVector GetNormalized() const { FLOAT SquareSum = X*X+Y*Y+Z*Z; if(SquareSum >= SMALL_NUMBER) { FLOAT Scale = 1.0f/appSqrt(SquareSum); - X *= Scale; Y *= Scale; Z *= Scale; - return *this; + return FVector(X * Scale, Y * Scale, Z * Scale); } return FVector(0,0,0); diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc index 12de7bfc..5c7752e5 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/RtxInterface.uc @@ -7,7 +7,10 @@ struct noexport RtxHandle{ }; var(General) config bool bShowAnchorTriangle; + +var(Lighting) bool bEnableLights; var(Lighting) editinline array Lights; + var array DestroyedLights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights native final function RtxLight CreateLight(); @@ -27,3 +30,8 @@ cpptext static bridgeapi_Interface BridgeInterface; } + +defaultproperties +{ + bEnableLights=True +} diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index ab9988ea..b95f5da3 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -21,6 +21,7 @@ class RTXDRV_API URtxInterface : public UObject { public: BITFIELD bShowAnchorTriangle:1 GCC_PACK(4); + BITFIELD bEnableLights:1; TArrayNoInit Lights GCC_PACK(4); TArrayNoInit DestroyedLights; void execCreateLight(FFrame& Stack, void* Result); diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 6499954f..a5ecdae0 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -52,6 +52,9 @@ void URtxInterface::DestroyAllLights() void URtxInterface::RenderLights() { + if(!bEnableLights) + return; + for(INT i = 0; i < Lights.Num(); ++i) { URtxLight* Light = Lights[i]; @@ -60,10 +63,6 @@ void URtxInterface::RenderLights() { Light = ConstructObject(URtxLight::StaticClass(), this); Lights[i] = Light; - - TObjectIterator It; - if(It && It->Actor) - Lights[i]->Position = It->Actor->Location; } if(Light->bEnabled) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 68ea30e0..ba42b967 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -31,14 +31,16 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) } else if(ParseCommand(&Cmd, "CREATELIGHT")) { - UObject* Light = Rtx->CreateLight(true); + URtxLight* Light = Rtx->CreateLight(true); + Light->Position = GEngine->Client->Viewports[0]->Actor->Location; if(!ParseCommand(&Cmd, "!")) { GEngine->Client->GetLastCurrent()->EndFullscreen(); WObjectProperties* P = new WObjectProperties("EditObj", 0, "", NULL, 1); P->OpenWindow(GLogWindow->hWnd); - P->Root.SetObjects(&Light, 1); + UObject* Obj = Light; + P->Root.SetObjects(&Obj, 1); P->Show(1); } @@ -69,7 +71,7 @@ UBOOL URtxRenderDevice::Init() } ClearMaterialFlags(); - UClient* Client = UTexture::__Client; + UClient* Client = GEngine->Client; Client->Shadows = 0; Client->FrameFXDisabled = 1; Client->BloomQuality = 0; From 63695fb0bc559e6da69c913c5e1a5a4fcf9dbe61 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 12 Aug 2024 00:42:26 +0200 Subject: [PATCH 15/48] Separate color and radiance for rtx lights --- RtxDrv/Classes/RtxLight.uc | 6 ++++-- RtxDrv/Inc/RtxDrvClasses.h | 3 ++- RtxDrv/Src/Rtx.cpp | 2 +- RtxDrv/Src/RtxDrvPrivate.h | 2 +- RtxDrv/Src/RtxRenderDevice.cpp | 8 +++----- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/RtxDrv/Classes/RtxLight.uc b/RtxDrv/Classes/RtxLight.uc index 4ee48a74..c06263d9 100644 --- a/RtxDrv/Classes/RtxLight.uc +++ b/RtxDrv/Classes/RtxLight.uc @@ -13,7 +13,8 @@ var(Common) enum ERtxLightType{ var(Common) bool bEnabled; var(Common) bool bUseShaping; var(Common) vector Position; -var(Common) vector Radiance; +var(Common) color Color; +var(Common) float Radiance; // Used by sphere, rect and disc if bUseShaping var(Common) struct RtxLightShaping{ @@ -66,6 +67,7 @@ cpptext defaultproperties { bEnabled=True - Radiance=(X=1000,Y=1000,Z=1000) + Color=(R=255,G=255,B=255,A=255) + Radiance=10000 Sphere=(Radius=2.5) } diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index b95f5da3..b5a66ca3 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -102,7 +102,8 @@ class RTXDRV_API URtxLight : public UObject BITFIELD bEnabled:1 GCC_PACK(4); BITFIELD bUseShaping:1; FVector Position GCC_PACK(4); - FVector Radiance; + FColor Color; + FLOAT Radiance; FRtxLightShaping Shaping; FRtxSphereLight Sphere; FRtxRectLight Rect; diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index a5ecdae0..88d13f43 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -152,7 +152,7 @@ void URtxLight::Update() x86::remixapi_LightInfo LightInfo; LightInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO; LightInfo.hash = reinterpret_cast(this); - InitFloat3D(LightInfo.radiance, Radiance); + InitFloat3D(LightInfo.radiance, Color.Plane() * Radiance); switch(Type) { diff --git a/RtxDrv/Src/RtxDrvPrivate.h b/RtxDrv/Src/RtxDrvPrivate.h index 337fde56..8b2e49a8 100644 --- a/RtxDrv/Src/RtxDrvPrivate.h +++ b/RtxDrv/Src/RtxDrvPrivate.h @@ -1,4 +1,4 @@ -#include "Core.h" +#include "Engine.h" #include "bridge_c.h" typedef uint64_t FRtxHandle; #include "../Inc/RtxDrvClasses.h" diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index ba42b967..7f23cb0e 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -146,16 +146,14 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) if(!ProjLight) ProjLight = &ProjLights[*Proj]; - FPlane Col = FGetHSV(Proj->LightHue, Proj->LightSaturation, Proj->LightBrightness) * 10000; - FVector Loc = Proj->Location; - if(!ProjLight->Light) ProjLight->Light = Rtx->CreateLight(); URtxLight* Light = ProjLight->Light; Light->Type = RTXLIGHT_Sphere; - Light->Position = Loc; - Light->Radiance = Col; + Light->Position = Proj->Location; + Light->Radiance = 10000.0f; + Light->Color = FGetHSV(Proj->LightHue, Proj->LightSaturation, Proj->LightBrightness); Light->Sphere.Radius = 2.5f; Light->Update(); From 95119d0ea8b532423bc1aeabd0a1ab0a3adf0c71 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 12 Aug 2024 01:18:43 +0200 Subject: [PATCH 16/48] Avoid iterating all lights for each DestroyLight call --- RtxDrv/Classes/RtxInterface.uc | 8 ++++---- RtxDrv/Classes/RtxLight.uc | 1 + RtxDrv/Inc/RtxDrvClasses.h | 3 ++- RtxDrv/Src/Rtx.cpp | 24 ++++++++++++++++++++---- RtxDrv/Src/RtxRenderDevice.cpp | 1 + 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc index 5c7752e5..ca2a6cfe 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/RtxInterface.uc @@ -23,10 +23,10 @@ cpptext { void Init(); void Exit(); - URtxLight* CreateLight(bool ForceDefaultConstructed = false); - void DestroyLight(URtxLight* Light); - void DestroyAllLights(); - void RenderLights(); + URtxLight* CreateLight(bool ForceDefaultConstructed = false); + void DestroyLight(URtxLight* Light); + void DestroyAllLights(); + void RenderLights(); static bridgeapi_Interface BridgeInterface; } diff --git a/RtxDrv/Classes/RtxLight.uc b/RtxDrv/Classes/RtxLight.uc index c06263d9..70486f06 100644 --- a/RtxDrv/Classes/RtxLight.uc +++ b/RtxDrv/Classes/RtxLight.uc @@ -10,6 +10,7 @@ var(Common) enum ERtxLightType{ RTXLIGHT_Distant } Type; +var bool bShouldBeDestroyed; var(Common) bool bEnabled; var(Common) bool bUseShaping; var(Common) vector Position; diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index b5a66ca3..354ef3c5 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -99,7 +99,8 @@ class RTXDRV_API URtxLight : public UObject public: FRtxHandle Handle; BYTE Type; - BITFIELD bEnabled:1 GCC_PACK(4); + BITFIELD bShouldBeDestroyed:1 GCC_PACK(4); + BITFIELD bEnabled:1; BITFIELD bUseShaping:1; FVector Position GCC_PACK(4); FColor Color; diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 88d13f43..5db3559c 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -14,6 +14,9 @@ void URtxInterface::Init() BridgeInterface.RegisterDevice(); } + + Lights.SetNoShrink(true); + DestroyedLights.SetNoShrink(true); } void URtxInterface::Exit() @@ -30,6 +33,7 @@ URtxLight* URtxInterface::CreateLight(bool ForceDefaultConstructed) else Light = ConstructObject(URtxLight::StaticClass(), this); + Light->bShouldBeDestroyed = 0; Light->bEnabled = 1; Lights.AddItem(Light); return Light; @@ -38,10 +42,7 @@ URtxLight* URtxInterface::CreateLight(bool ForceDefaultConstructed) void URtxInterface::DestroyLight(URtxLight* Light) { if(Light) - { - Lights.RemoveItem(Light); - DestroyedLights.AddItem(Light); - } + Light->bShouldBeDestroyed = 1; } void URtxInterface::DestroyAllLights() @@ -65,6 +66,21 @@ void URtxInterface::RenderLights() Lights[i] = Light; } + if(Light->bShouldBeDestroyed) + { + URtxLight* Last = Lights.Pop(); + + if(i == Lights.Num()) + { + DestroyedLights.AddItem(Last); + break; + } + + DestroyedLights.AddItem(Light); + Lights[i] = Last; + Light = Last; + } + if(Light->bEnabled) { if(!Light->Handle) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 7f23cb0e..90400786 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -28,6 +28,7 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) UObject* Obj = Rtx; P->Root.SetObjects(&Obj, 1); P->Show(1); + return 1; } else if(ParseCommand(&Cmd, "CREATELIGHT")) { From 4b6d5b784258768411bec92b5ad1988bd90bf6ba Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sun, 18 Aug 2024 19:14:59 +0200 Subject: [PATCH 17/48] Draw a unique anchor triangle per level --- RtxDrv/Classes/RtxInterface.uc | 4 +++ RtxDrv/Inc/RtxDrvClasses.h | 10 +++--- RtxDrv/Src/RtxRenderDevice.cpp | 59 +++++++++++++++------------------- RtxDrv/Src/RtxRenderDevice.h | 44 +++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 40 deletions(-) diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc index ca2a6cfe..a79728fe 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/RtxInterface.uc @@ -6,6 +6,8 @@ struct noexport RtxHandle{ var const int hi; }; +var(General) config float AnchorTriangleSize; +var(General) config color AnchorTriangleColor; var(General) config bool bShowAnchorTriangle; var(Lighting) bool bEnableLights; @@ -33,5 +35,7 @@ cpptext defaultproperties { + AnchorTriangleSize=512 + AnchorTriangleColor=(R=255,G=255,B=0,A=255) bEnableLights=True } diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 354ef3c5..588f5105 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -20,6 +20,8 @@ class RTXDRV_API URtxInterface : public UObject { public: + FLOAT AnchorTriangleSize; + FColor AnchorTriangleColor; BITFIELD bShowAnchorTriangle:1 GCC_PACK(4); BITFIELD bEnableLights:1; TArrayNoInit Lights GCC_PACK(4); @@ -31,10 +33,10 @@ class RTXDRV_API URtxInterface : public UObject DECLARE_CLASS(URtxInterface,UObject,0|CLASS_Transient|CLASS_Config,RtxDrv) void Init(); void Exit(); - URtxLight* CreateLight(bool ForceDefaultConstructed = false); - void DestroyLight(URtxLight* Light); - void DestroyAllLights(); - void RenderLights(); + URtxLight* CreateLight(bool ForceDefaultConstructed = false); + void DestroyLight(URtxLight* Light); + void DestroyAllLights(); + void RenderLights(); static bridgeapi_Interface BridgeInterface; DECLARE_NATIVES(URtxInterface) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 90400786..214a911f 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -1,9 +1,21 @@ #include "RtxRenderDevice.h" #include "RtxDrvPrivate.h" #include "Window.h" +#include "Editor.h" IMPLEMENT_CLASS(URtxRenderDevice) +static ULevel* GetLevel() +{ + if(GEngine->IsA()) + return static_cast(GEngine)->GLevel; + + if(GEngine->IsA()) + return static_cast(GEngine)->Level; + + return NULL; +} + void URtxRenderDevice::Serialize(FArchive& Ar) { Super::Serialize(Ar); @@ -112,6 +124,15 @@ void URtxRenderDevice::Flush(UViewport* Viewport) FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) { + ULevel* Level = GetLevel(); + + if(Level != CurrentLevel) + { + CurrentLevel = Level; + AnchorTriangleStream.Update(CurrentLevel ? (FLOAT)appStrihash(CurrentLevel->GetPathName()) : 0.0f); + Rtx->DestroyAllLights(); + } + LockedViewport = Viewport; if(Viewport->Actor) @@ -198,39 +219,11 @@ void URtxRenderDevice::ClearMaterialFlags() * Draw anchor triangle at world center to parent assets to in remix */ -class FSingleTriangleVertexStream : public FVertexStream{ -public: - FSingleTriangleVertexStream(FLOAT Width, FLOAT Height) : HalfWidth(Width / 2), HalfHeight(Height / 2) - { - CacheId = MakeCacheID(CID_RenderVertices); - } - - FLOAT HalfWidth; - FLOAT HalfHeight; - - virtual INT GetStride(){ return sizeof(FVector); } - virtual INT GetSize(){ return sizeof(FVector) * 3; } - - virtual INT GetComponents(FVertexComponent* Components) - { - Components->Type = CT_Float3; - Components->Function = FVF_Position; - return 1; - } - - virtual void GetStreamData(void* Dest) - { - FVector* D = static_cast(Dest); - D[0] = FVector(-HalfWidth, -HalfHeight, 0); - D[1] = FVector(HalfHeight, -HalfHeight, 0); - D[2] = FVector(0, HalfHeight, 0); - } -}; - class USolidColorMaterial : public UConstantMaterial{ DECLARE_CLASS(USolidColorMaterial,UConstantMaterial,0,RtxDrv) public: - virtual FColor GetColor(FLOAT TimeSeconds){ return FColor(255,255,0,255); } + FColor Color; + virtual FColor GetColor(FLOAT TimeSeconds){ return Color; } }; IMPLEMENT_CLASS(USolidColorMaterial) @@ -301,16 +294,16 @@ void URtxRenderDevice::DrawAnchorTriangle() FinalBlend->Material = Material; FinalBlend->FrameBufferBlending = FB_Overwrite; }); + Material->Color = Rtx->AnchorTriangleColor; FinalBlend->ColorWriteEnable = Rtx->bShowAnchorTriangle; PushState(); - SetTransform(TT_LocalToWorld, FMatrix::Identity); + SetTransform(TT_LocalToWorld, FScaleMatrix(FVector(Rtx->AnchorTriangleSize, Rtx->AnchorTriangleSize, 0.0f))); SetTransform(TT_WorldToCamera, WorldToCamera); SetTransform(TT_CameraToScreen, CameraToScreen); SetMaterial(FinalBlend); SetIndexBuffer(NULL, 0); - static FSingleTriangleVertexStream AnchorTriangle(512, 512); - FVertexStream* Stream = &AnchorTriangle; + FVertexStream* Stream = &AnchorTriangleStream; SetVertexStreams(VS_FixedFunction, &Stream, 1); DrawPrimitive(PT_TriangleList, 0, 1); PopState(); diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 700b5d7a..bb9b5a2c 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -4,6 +4,42 @@ class URtxInterface; +class FAnchorTriangleVertexStream : public FVertexStream{ +public: + FAnchorTriangleVertexStream() + { + CacheId = MakeCacheID(CID_RenderVertices); + Update(0.0f); + } + + void Update(FLOAT InZOffset) + { + ZOffset = InZOffset; + ++Revision; + } + + virtual INT GetStride(){ return sizeof(FVector); } + virtual INT GetSize(){ return sizeof(FVector) * 3; } + + virtual INT GetComponents(FVertexComponent* Components) + { + Components->Type = CT_Float3; + Components->Function = FVF_Position; + return 1; + } + + virtual void GetStreamData(void* Dest) + { + FVector* D = static_cast(Dest); + D[0] = FVector(-1.0f, -1.0f, ZOffset); + D[1] = FVector(1.0f, -1.0f, ZOffset); + D[2] = FVector(0, 1.0f, ZOffset); + } + +private: + FLOAT ZOffset; +}; + class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) static const TCHAR* StaticConfigName(){ return "RtxDrv"; } @@ -64,9 +100,11 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ virtual void SetFillMode(EFillMode FillMode){ D3D->SetFillMode(FillMode); } private: - UViewport* LockedViewport; - FRenderInterface* D3D; - URtxInterface* Rtx; + UViewport* LockedViewport; + ULevel* CurrentLevel; + FAnchorTriangleVertexStream AnchorTriangleStream; + FRenderInterface* D3D; + URtxInterface* Rtx; void ClearMaterialFlags(); void DrawAnchorTriangle(); From c633ed644d6d04c1b1a1d2e6c5f470bfdd46ba38 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 19 Aug 2024 00:20:14 +0200 Subject: [PATCH 18/48] Don't reset d3d render interface in Unlock because it might still be used if Lock returns NULL when playing movies --- RtxDrv/Src/RtxRenderDevice.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 214a911f..c2c75bb7 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -124,6 +124,11 @@ void URtxRenderDevice::Flush(UViewport* Viewport) FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) { + D3D = Super::Lock(Viewport, HitData, HitSize); + + if(!D3D) + return NULL; + ULevel* Level = GetLevel(); if(Level != CurrentLevel) @@ -141,13 +146,6 @@ FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT Viewport->Actor->VisorModeDefault = 1; } - FRenderInterface* RI = Super::Lock(Viewport, HitData, HitSize); - - if(!RI) - return NULL; - - D3D = RI; - return this; } @@ -199,7 +197,6 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) DrawAnchorTriangle(); LockedViewport = NULL; - D3D = NULL; Super::Unlock(static_cast(RI)->D3D); } From 426192bb8d28a9f485431abad11e3f22f08250d6 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 19 Aug 2024 00:20:51 +0200 Subject: [PATCH 19/48] Fix crash when light is added via UI at the end of a non-empty list --- RtxDrv/Src/Rtx.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 5db3559c..9d2d6b8c 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -60,13 +60,7 @@ void URtxInterface::RenderLights() { URtxLight* Light = Lights[i]; - if(!Light) // NULL entry can happen if a light was added via the property window UI. In that case just create it - { - Light = ConstructObject(URtxLight::StaticClass(), this); - Lights[i] = Light; - } - - if(Light->bShouldBeDestroyed) + if(Light && Light->bShouldBeDestroyed) { URtxLight* Last = Lights.Pop(); @@ -81,6 +75,12 @@ void URtxInterface::RenderLights() Light = Last; } + if(!Light) // NULL entry can happen if a light was added via the property window UI. In that case just create it + { + Light = ConstructObject(URtxLight::StaticClass(), this); + Lights[i] = Light; + } + if(Light->bEnabled) { if(!Light->Handle) From c680208fb01fe4930e8cd696c54c5321a1f0f65f Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 20 Aug 2024 22:31:17 +0200 Subject: [PATCH 20/48] Move bridge interface out of URtxInterface --- RtxDrv/Classes/RtxInterface.uc | 2 -- RtxDrv/Classes/RtxLight.uc | 1 + RtxDrv/Inc/RtxDrvClasses.h | 3 +- RtxDrv/Src/Rtx.cpp | 58 ++++++++++++++++------------------ 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc index a79728fe..80d91bd9 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/RtxInterface.uc @@ -29,8 +29,6 @@ cpptext void DestroyLight(URtxLight* Light); void DestroyAllLights(); void RenderLights(); - - static bridgeapi_Interface BridgeInterface; } defaultproperties diff --git a/RtxDrv/Classes/RtxLight.uc b/RtxDrv/Classes/RtxLight.uc index 70486f06..3f23e938 100644 --- a/RtxDrv/Classes/RtxLight.uc +++ b/RtxDrv/Classes/RtxLight.uc @@ -63,6 +63,7 @@ cpptext virtual void Destroy(); virtual void PostEditChange(){ Super::PostEditChange(); Update(); } void Update(); + void DestroyHandle(); } defaultproperties diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 588f5105..50f35b15 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -37,8 +37,6 @@ class RTXDRV_API URtxInterface : public UObject void DestroyLight(URtxLight* Light); void DestroyAllLights(); void RenderLights(); - - static bridgeapi_Interface BridgeInterface; DECLARE_NATIVES(URtxInterface) }; @@ -118,6 +116,7 @@ class RTXDRV_API URtxLight : public UObject virtual void Destroy(); virtual void PostEditChange(){ Super::PostEditChange(); Update(); } void Update(); + void DestroyHandle(); DECLARE_NATIVES(URtxLight) }; diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 9d2d6b8c..686f8dc6 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -1,18 +1,18 @@ #include "RtxDrvPrivate.h" #include "RtxRenderDevice.h" -bridgeapi_Interface URtxInterface::BridgeInterface; +static bridgeapi_Interface GBridgeInterface; void URtxInterface::Init() { - if(!BridgeInterface.initialized) + if(!GBridgeInterface.initialized) { debugf("Initializing remix bridge API"); - if(bridgeapi_initialize(&BridgeInterface) != BRIDGEAPI_ERROR_CODE_SUCCESS || !BridgeInterface.initialized) + if(bridgeapi_initialize(&GBridgeInterface) != BRIDGEAPI_ERROR_CODE_SUCCESS || !GBridgeInterface.initialized) appErrorf("Failed to initialize remix bridge API"); - BridgeInterface.RegisterDevice(); + GBridgeInterface.RegisterDevice(); } Lights.SetNoShrink(true); @@ -21,7 +21,7 @@ void URtxInterface::Init() void URtxInterface::Exit() { - BridgeInterface.initialized = false; + GBridgeInterface.initialized = false; } URtxLight* URtxInterface::CreateLight(bool ForceDefaultConstructed) @@ -62,15 +62,13 @@ void URtxInterface::RenderLights() if(Light && Light->bShouldBeDestroyed) { + Light->DestroyHandle(); URtxLight* Last = Lights.Pop(); + DestroyedLights.AddItem(Light); - if(i == Lights.Num()) - { - DestroyedLights.AddItem(Last); + if(Light == Last) break; - } - DestroyedLights.AddItem(Light); Lights[i] = Last; Light = Last; } @@ -87,7 +85,7 @@ void URtxInterface::RenderLights() Light->Update(); if(Light->Handle) - BridgeInterface.DrawLightInstance(Light->Handle); + GBridgeInterface.DrawLightInstance(Light->Handle); } } } @@ -130,14 +128,7 @@ void URtxLight::execUpdate(FFrame& Stack, void* Result) void URtxLight::Destroy() { - if(Handle) - { - if(URtxInterface::BridgeInterface.initialized) - URtxInterface::BridgeInterface.DestroyLight(Handle); - - Handle = 0; - } - + DestroyHandle(); Super::Destroy(); } @@ -157,13 +148,7 @@ static void InitShaping(x86::remixapi_LightInfoLightShaping& Dest, const FRtxLig void URtxLight::Update() { - const bridgeapi_Interface& Bridge = URtxInterface::BridgeInterface; - - if(Handle) - { - Bridge.DestroyLight(Handle); - Handle = 0; - } + DestroyHandle(); x86::remixapi_LightInfo LightInfo; LightInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO; @@ -183,7 +168,7 @@ void URtxLight::Update() if(SphereInfo.shaping_hasvalue) InitShaping(SphereInfo.shaping_value, Shaping); - Handle = Bridge.CreateSphereLight(&LightInfo, &SphereInfo); + Handle = GBridgeInterface.CreateSphereLight(&LightInfo, &SphereInfo); break; } case RTXLIGHT_Rect: @@ -200,7 +185,7 @@ void URtxLight::Update() if(RectInfo.shaping_hasvalue) InitShaping(RectInfo.shaping_value, Shaping); - Handle = Bridge.CreateRectLight(&LightInfo, &RectInfo); + Handle = GBridgeInterface.CreateRectLight(&LightInfo, &RectInfo); break; } case RTXLIGHT_Disk: @@ -217,7 +202,7 @@ void URtxLight::Update() if(DiskInfo.shaping_hasvalue) InitShaping(DiskInfo.shaping_value, Shaping); - Handle = Bridge.CreateDiskLight(&LightInfo, &DiskInfo); + Handle = GBridgeInterface.CreateDiskLight(&LightInfo, &DiskInfo); break; } case RTXLIGHT_Cylinder: @@ -228,7 +213,7 @@ void URtxLight::Update() InitFloat3D(CylinderInfo.axis, Cylinder.Axis.GetNormalized()); CylinderInfo.radius = Cylinder.Radius; CylinderInfo.axisLength = Cylinder.Length; - Handle = Bridge.CreateCylinderLight(&LightInfo, &CylinderInfo); + Handle = GBridgeInterface.CreateCylinderLight(&LightInfo, &CylinderInfo); break; } case RTXLIGHT_Distant: @@ -237,8 +222,19 @@ void URtxLight::Update() DistantInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT; InitFloat3D(DistantInfo.direction, Distant.Direction.GetNormalized()); DistantInfo.angularDiameterDegrees = Distant.AngularDiameterDegrees; - Handle = Bridge.CreateDistantLight(&LightInfo, &DistantInfo); + Handle = GBridgeInterface.CreateDistantLight(&LightInfo, &DistantInfo); break; } } } + +void URtxLight::DestroyHandle() +{ + if(Handle) + { + if(GBridgeInterface.initialized) + GBridgeInterface.DestroyLight(Handle); + + Handle = 0; + } +} From 3a44e98c5ad73bc7fcf1bd2758960c19369d19ad Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sat, 24 Aug 2024 13:23:31 +0200 Subject: [PATCH 21/48] Make anchor triangle color or visibility changes possible without a level restart --- RtxDrv/Src/RtxRenderDevice.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index c2c75bb7..dc810902 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -291,8 +291,23 @@ void URtxRenderDevice::DrawAnchorTriangle() FinalBlend->Material = Material; FinalBlend->FrameBufferBlending = FB_Overwrite; }); - Material->Color = Rtx->AnchorTriangleColor; - FinalBlend->ColorWriteEnable = Rtx->bShowAnchorTriangle; + + bool Reset = false; + + if(Material->Color != Rtx->AnchorTriangleColor) + { + Material->Color = Rtx->AnchorTriangleColor; + Reset = true; + } + + if(FinalBlend->ColorWriteEnable != Rtx->bShowAnchorTriangle) + { + FinalBlend->ColorWriteEnable = Rtx->bShowAnchorTriangle; + Reset = true; + } + + if(Reset) + FinalBlend->ResetCachedStates(); PushState(); SetTransform(TT_LocalToWorld, FScaleMatrix(FVector(Rtx->AnchorTriangleSize, Rtx->AnchorTriangleSize, 0.0f))); From 0a3af2d93d4108eb7932e11c3fe8d116638c96be Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sun, 8 Sep 2024 18:14:28 +0200 Subject: [PATCH 22/48] Draw anchor triangle after first depth clear so it shows up in scene captures --- RtxDrv/Src/RtxRenderDevice.cpp | 16 ++++++++++++++-- RtxDrv/Src/RtxRenderDevice.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index dc810902..f2bc6682 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -59,6 +59,11 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) return 1; } + else if(ParseCommand(&Cmd, "SAVECONFIG")) + { + Rtx->SaveConfig(); + return 1; + } } return Super::Exec(Cmd, Ar); @@ -124,6 +129,8 @@ void URtxRenderDevice::Flush(UViewport* Viewport) FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) { + DepthCleared = 0; + D3D = Super::Lock(Viewport, HitData, HitSize); if(!D3D) @@ -194,8 +201,6 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) } Rtx->RenderLights(); - - DrawAnchorTriangle(); LockedViewport = NULL; Super::Unlock(static_cast(RI)->D3D); @@ -290,6 +295,7 @@ void URtxRenderDevice::DrawAnchorTriangle() { FinalBlend->Material = Material; FinalBlend->FrameBufferBlending = FB_Overwrite; + FinalBlend->ZWrite = 1; }); bool Reset = false; @@ -333,6 +339,12 @@ UBOOL URtxRenderDevice::SetRenderTarget(FRenderTarget* RenderTarget, bool bOwnDe void URtxRenderDevice::Clear(UBOOL UseColor, FColor Color, UBOOL UseDepth, FLOAT Depth, UBOOL UseStencil, DWORD Stencil) { D3D->Clear(UseColor, Color, UseDepth, Depth, UseStencil, Stencil); + + if(UseDepth && !DepthCleared) + { + DepthCleared = 1; + DrawAnchorTriangle(); + } } void URtxRenderDevice::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue){ diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index bb9b5a2c..bd13b049 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -105,6 +105,7 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ FAnchorTriangleVertexStream AnchorTriangleStream; FRenderInterface* D3D; URtxInterface* Rtx; + UBOOL DepthCleared; void ClearMaterialFlags(); void DrawAnchorTriangle(); From 2d72b7f1059b7a4d3fcce2ddda44be029fcbf729 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 9 Sep 2024 09:48:05 +0200 Subject: [PATCH 23/48] Draw anchor triangle without scaling matrix to avoid issues in remix --- RtxDrv/Classes/RtxInterface.uc | 5 ++--- RtxDrv/Inc/RtxDrvClasses.h | 3 +-- RtxDrv/Src/RtxRenderDevice.cpp | 38 +++++++++++++--------------------- RtxDrv/Src/RtxRenderDevice.h | 7 ++++--- 4 files changed, 21 insertions(+), 32 deletions(-) diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc index 80d91bd9..d8986a40 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/RtxInterface.uc @@ -6,9 +6,8 @@ struct noexport RtxHandle{ var const int hi; }; -var(General) config float AnchorTriangleSize; var(General) config color AnchorTriangleColor; -var(General) config bool bShowAnchorTriangle; +var(General) config bool bDrawAnchorTriangle; var(Lighting) bool bEnableLights; var(Lighting) editinline array Lights; @@ -33,7 +32,7 @@ cpptext defaultproperties { - AnchorTriangleSize=512 AnchorTriangleColor=(R=255,G=255,B=0,A=255) + bDrawAnchorTriangle=True bEnableLights=True } diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 50f35b15..9c42131b 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -20,9 +20,8 @@ class RTXDRV_API URtxInterface : public UObject { public: - FLOAT AnchorTriangleSize; FColor AnchorTriangleColor; - BITFIELD bShowAnchorTriangle:1 GCC_PACK(4); + BITFIELD bDrawAnchorTriangle:1 GCC_PACK(4); BITFIELD bEnableLights:1; TArrayNoInit Lights GCC_PACK(4); TArrayNoInit DestroyedLights; diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index f2bc6682..397080c0 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -29,7 +29,7 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) { if(ParseCommand(&Cmd, "TOGGLEANCHOR")) { - Rtx->bShowAnchorTriangle = !Rtx->bShowAnchorTriangle; + Rtx->bDrawAnchorTriangle = !Rtx->bDrawAnchorTriangle; return 1; } else if(ParseCommand(&Cmd, "PREFERENCES")) @@ -89,13 +89,13 @@ UBOOL URtxRenderDevice::Init() } ClearMaterialFlags(); - UClient* Client = GEngine->Client; - Client->Shadows = 0; - Client->FrameFXDisabled = 1; - Client->BloomQuality = 0; - Client->BlurEnabled = 0; - Client->BumpmappingQuality = 0; - GetDefault()->bVisor = 0; + UClient* Client = GEngine->Client; + Client->Shadows = 0; + Client->FrameFXDisabled = 1; + Client->BloomQuality = 0; + Client->BlurEnabled = 0; + Client->BumpmappingQuality = 0; + GetDefault()->bVisor = 0; GetDefault()->VisorModeDefault = 1; Rtx = new(this) URtxInterface; @@ -141,7 +141,7 @@ FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT if(Level != CurrentLevel) { CurrentLevel = Level; - AnchorTriangleStream.Update(CurrentLevel ? (FLOAT)appStrihash(CurrentLevel->GetPathName()) : 0.0f); + AnchorTriangleStream.Update(CurrentLevel ? (appStrihash(CurrentLevel->GetPathName()) / (FLOAT)MAXDWORD) : 0.0f); Rtx->DestroyAllLights(); } @@ -231,7 +231,7 @@ IMPLEMENT_CLASS(USolidColorMaterial) void URtxRenderDevice::DrawAnchorTriangle() { - if(!LockedViewport || !LockedViewport->Actor) + if(!Rtx->bDrawAnchorTriangle || !LockedViewport || !LockedViewport->Actor) return; AActor* ViewActor = LockedViewport->Actor; @@ -298,25 +298,14 @@ void URtxRenderDevice::DrawAnchorTriangle() FinalBlend->ZWrite = 1; }); - bool Reset = false; - if(Material->Color != Rtx->AnchorTriangleColor) { Material->Color = Rtx->AnchorTriangleColor; - Reset = true; - } - - if(FinalBlend->ColorWriteEnable != Rtx->bShowAnchorTriangle) - { - FinalBlend->ColorWriteEnable = Rtx->bShowAnchorTriangle; - Reset = true; - } - - if(Reset) FinalBlend->ResetCachedStates(); + } PushState(); - SetTransform(TT_LocalToWorld, FScaleMatrix(FVector(Rtx->AnchorTriangleSize, Rtx->AnchorTriangleSize, 0.0f))); + SetTransform(TT_LocalToWorld, FMatrix::Identity); SetTransform(TT_WorldToCamera, WorldToCamera); SetTransform(TT_CameraToScreen, CameraToScreen); SetMaterial(FinalBlend); @@ -347,7 +336,8 @@ void URtxRenderDevice::Clear(UBOOL UseColor, FColor Color, UBOOL UseDepth, FLOAT } } -void URtxRenderDevice::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue){ +void URtxRenderDevice::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue) +{ UseDynamic = 0; Lightmap = NULL; Modulate2X = 0; diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index bd13b049..ff6609fc 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -31,9 +31,10 @@ class FAnchorTriangleVertexStream : public FVertexStream{ virtual void GetStreamData(void* Dest) { FVector* D = static_cast(Dest); - D[0] = FVector(-1.0f, -1.0f, ZOffset); - D[1] = FVector(1.0f, -1.0f, ZOffset); - D[2] = FVector(0, 1.0f, ZOffset); + const FLOAT Size = 512.0f; + D[0] = FVector(-Size, -Size, ZOffset); + D[1] = FVector( Size, -Size, ZOffset); + D[2] = FVector( 0.0f, Size, ZOffset); } private: From 1594b82c17538bb601eb22f9146291782afd5cb3 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Thu, 19 Sep 2024 19:55:40 +0200 Subject: [PATCH 24/48] Update remix api --- RtxDrv/Classes/RtxInterface.uc | 6 - RtxDrv/Classes/RtxLight.uc | 6 +- RtxDrv/Inc/RtxDrvClasses.h | 3 +- RtxDrv/RtxDrv.vcproj | 3 + RtxDrv/Src/Rtx.cpp | 61 +-- RtxDrv/Src/RtxDrvPrivate.h | 3 +- RtxDrv/Src/RtxRenderDevice.cpp | 11 +- RtxDrv/Src/bridge_c.h | 409 ------------------ RtxDrv/Src/remix_c.h | 756 +++++++++++++++++++++++++++++++++ 9 files changed, 806 insertions(+), 452 deletions(-) delete mode 100644 RtxDrv/Src/bridge_c.h create mode 100644 RtxDrv/Src/remix_c.h diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc index d8986a40..3e9a2893 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/RtxInterface.uc @@ -1,11 +1,5 @@ class RtxInterface extends Object within RtxRenderDevice native transient config(RtxDrv) hidecategories(Object, None); -// uint64_t -struct noexport RtxHandle{ - var const int lo; - var const int hi; -}; - var(General) config color AnchorTriangleColor; var(General) config bool bDrawAnchorTriangle; diff --git a/RtxDrv/Classes/RtxLight.uc b/RtxDrv/Classes/RtxLight.uc index 3f23e938..85e431e9 100644 --- a/RtxDrv/Classes/RtxLight.uc +++ b/RtxDrv/Classes/RtxLight.uc @@ -1,7 +1,5 @@ class RtxLight extends Object within RtxInterface native transient hidecategories(Object, None); -var editconst RtxInterface.RtxHandle Handle; - var(Common) enum ERtxLightType{ RTXLIGHT_Sphere, RTXLIGHT_Rect, @@ -56,10 +54,14 @@ var(DistantLight) struct RtxDistantLight{ var() float AngularDiameterDegrees; } Distant; +var const editconst noexport int Handle; + native final function Update(); // Must be called whenever a property value has changed cpptext { + remixapi_LightHandle_T* Handle; + virtual void Destroy(); virtual void PostEditChange(){ Super::PostEditChange(); Update(); } void Update(); diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 9c42131b..28cf3b7a 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -96,7 +96,6 @@ struct RTXDRV_API FRtxDistantLight class RTXDRV_API URtxLight : public UObject { public: - FRtxHandle Handle; BYTE Type; BITFIELD bShouldBeDestroyed:1 GCC_PACK(4); BITFIELD bEnabled:1; @@ -112,6 +111,8 @@ class RTXDRV_API URtxLight : public UObject FRtxDistantLight Distant; void execUpdate(FFrame& Stack, void* Result); DECLARE_CLASS(URtxLight,UObject,0|CLASS_Transient,RtxDrv) + remixapi_LightHandle_T* Handle; + virtual void Destroy(); virtual void PostEditChange(){ Super::PostEditChange(); Update(); } void Update(); diff --git a/RtxDrv/RtxDrv.vcproj b/RtxDrv/RtxDrv.vcproj index b1fd874c..da9041ba 100644 --- a/RtxDrv/RtxDrv.vcproj +++ b/RtxDrv/RtxDrv.vcproj @@ -106,6 +106,9 @@ + + diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 686f8dc6..f5a800bd 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -1,18 +1,22 @@ #include "RtxDrvPrivate.h" #include "RtxRenderDevice.h" -static bridgeapi_Interface GBridgeInterface; +static remixapi_Interface GRemixInterface; void URtxInterface::Init() { - if(!GBridgeInterface.initialized) + if(!GRemixInterface.Startup) { debugf("Initializing remix bridge API"); - if(bridgeapi_initialize(&GBridgeInterface) != BRIDGEAPI_ERROR_CODE_SUCCESS || !GBridgeInterface.initialized) - appErrorf("Failed to initialize remix bridge API"); + wchar_t DllPathBuffer[MAX_PATH]; + FString DllPath = FStringTemp(appBaseDir()) * "d3d9.dll"; + HMODULE DllHandle; + MultiByteToWideChar(CP_ACP, 0, *DllPath, -1, DllPathBuffer, ARRAY_COUNT(DllPathBuffer)); - GBridgeInterface.RegisterDevice(); + remixapi_ErrorCode Error = remixapi_lib_loadRemixDllAndInitialize(DllPathBuffer, &GRemixInterface, &DllHandle) ; + if(Error != REMIXAPI_ERROR_CODE_SUCCESS) + appErrorf("Failed to initialize remix API: %i", Error); } Lights.SetNoShrink(true); @@ -21,7 +25,7 @@ void URtxInterface::Init() void URtxInterface::Exit() { - GBridgeInterface.initialized = false; + appMemzero(&GRemixInterface, sizeof(GRemixInterface)); } URtxLight* URtxInterface::CreateLight(bool ForceDefaultConstructed) @@ -85,7 +89,7 @@ void URtxInterface::RenderLights() Light->Update(); if(Light->Handle) - GBridgeInterface.DrawLightInstance(Light->Handle); + GRemixInterface.DrawLightInstance(Light->Handle); } } } @@ -132,14 +136,14 @@ void URtxLight::Destroy() Super::Destroy(); } -static void InitFloat3D(x86::remixapi_Float3D& Dest, const FVector& Src) +static void InitFloat3D(remixapi_Float3D& Dest, const FVector& Src) { Dest.x = Src.X; Dest.y = Src.Y; Dest.z = Src.Z; } -static void InitShaping(x86::remixapi_LightInfoLightShaping& Dest, const FRtxLightShaping& Src) +static void InitShaping(remixapi_LightInfoLightShaping& Dest, const FRtxLightShaping& Src) { Dest.coneAngleDegrees = Src.ConeAngleDegrees; Dest.coneSoftness = Src.ConeSoftness; @@ -150,8 +154,7 @@ void URtxLight::Update() { DestroyHandle(); - x86::remixapi_LightInfo LightInfo; - LightInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO; + remixapi_LightInfo LightInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO}; LightInfo.hash = reinterpret_cast(this); InitFloat3D(LightInfo.radiance, Color.Plane() * Radiance); @@ -159,8 +162,7 @@ void URtxLight::Update() { case RTXLIGHT_Sphere: { - x86::remixapi_LightInfoSphereEXT SphereInfo; - SphereInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT; + remixapi_LightInfoSphereEXT SphereInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT}; InitFloat3D(SphereInfo.position, Position); SphereInfo.radius = Sphere.Radius; SphereInfo.shaping_hasvalue = bUseShaping; @@ -168,13 +170,13 @@ void URtxLight::Update() if(SphereInfo.shaping_hasvalue) InitShaping(SphereInfo.shaping_value, Shaping); - Handle = GBridgeInterface.CreateSphereLight(&LightInfo, &SphereInfo); + LightInfo.pNext = &SphereInfo; + GRemixInterface.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Rect: { - x86::remixapi_LightInfoRectEXT RectInfo; - RectInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT; + remixapi_LightInfoRectEXT RectInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT}; InitFloat3D(RectInfo.position, Position); InitFloat3D(RectInfo.xAxis, Rect.XAxis.GetNormalized()); RectInfo.xSize = Rect.XSize; @@ -185,13 +187,13 @@ void URtxLight::Update() if(RectInfo.shaping_hasvalue) InitShaping(RectInfo.shaping_value, Shaping); - Handle = GBridgeInterface.CreateRectLight(&LightInfo, &RectInfo); + LightInfo.pNext = &RectInfo; + GRemixInterface.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Disk: { - x86::remixapi_LightInfoDiskEXT DiskInfo; - DiskInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT; + remixapi_LightInfoDiskEXT DiskInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT}; InitFloat3D(DiskInfo.position, Position); InitFloat3D(DiskInfo.xAxis, Disk.XAxis.GetNormalized()); DiskInfo.xRadius = Disk.XRadius; @@ -202,27 +204,28 @@ void URtxLight::Update() if(DiskInfo.shaping_hasvalue) InitShaping(DiskInfo.shaping_value, Shaping); - Handle = GBridgeInterface.CreateDiskLight(&LightInfo, &DiskInfo); + LightInfo.pNext = &DiskInfo; + GRemixInterface.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Cylinder: { - x86::remixapi_LightInfoCylinderEXT CylinderInfo; - CylinderInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT; + remixapi_LightInfoCylinderEXT CylinderInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT}; InitFloat3D(CylinderInfo.position, Position); InitFloat3D(CylinderInfo.axis, Cylinder.Axis.GetNormalized()); CylinderInfo.radius = Cylinder.Radius; CylinderInfo.axisLength = Cylinder.Length; - Handle = GBridgeInterface.CreateCylinderLight(&LightInfo, &CylinderInfo); + LightInfo.pNext = &CylinderInfo; + GRemixInterface.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Distant: { - x86::remixapi_LightInfoDistantEXT DistantInfo; - DistantInfo.sType = REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT; + remixapi_LightInfoDistantEXT DistantInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT}; InitFloat3D(DistantInfo.direction, Distant.Direction.GetNormalized()); DistantInfo.angularDiameterDegrees = Distant.AngularDiameterDegrees; - Handle = GBridgeInterface.CreateDistantLight(&LightInfo, &DistantInfo); + LightInfo.pNext = &DistantInfo; + GRemixInterface.CreateLight(&LightInfo, &Handle); break; } } @@ -232,9 +235,9 @@ void URtxLight::DestroyHandle() { if(Handle) { - if(GBridgeInterface.initialized) - GBridgeInterface.DestroyLight(Handle); + if(GRemixInterface.DestroyLight) + GRemixInterface.DestroyLight(Handle); - Handle = 0; + Handle = NULL; } } diff --git a/RtxDrv/Src/RtxDrvPrivate.h b/RtxDrv/Src/RtxDrvPrivate.h index 8b2e49a8..233d3214 100644 --- a/RtxDrv/Src/RtxDrvPrivate.h +++ b/RtxDrv/Src/RtxDrvPrivate.h @@ -1,4 +1,3 @@ #include "Engine.h" -#include "bridge_c.h" -typedef uint64_t FRtxHandle; +#include "remix_c.h" #include "../Inc/RtxDrvClasses.h" diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 397080c0..f1fae68e 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -44,8 +44,13 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) } else if(ParseCommand(&Cmd, "CREATELIGHT")) { - URtxLight* Light = Rtx->CreateLight(true); - Light->Position = GEngine->Client->Viewports[0]->Actor->Location; + APlayerController* PC = GEngine->Client->Viewports[0]->Actor; + URtxLight* Light = Rtx->CreateLight(true); + + if(PC->Pawn) + Light->Position = PC->Pawn->Location; + else + Light->Position = PC->Location; if(!ParseCommand(&Cmd, "!")) { @@ -346,7 +351,7 @@ void URtxRenderDevice::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL M void URtxRenderDevice::SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale) { - // Impl->SetLight(LightIndex, Light, Scale); + // D3D->SetLight(LightIndex, Light, Scale); } void URtxRenderDevice::SetTransform(ETransformType Type, const FMatrix& Matrix) diff --git a/RtxDrv/Src/bridge_c.h b/RtxDrv/Src/bridge_c.h deleted file mode 100644 index aec283a9..00000000 --- a/RtxDrv/Src/bridge_c.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -// Bridge API header for both the x86 bridge client and the x86 game - -#ifndef BRIDGE_C_H_ -#define BRIDGE_C_H_ - -#include "UnVcWin32.h" - -typedef BYTE uint8_t; -typedef INT int32_t; -typedef DWORD uint32_t; -typedef QWORD uint64_t; -#define nullptr NULL - -#define BRIDGEAPI_CALL __stdcall -#define BRIDGEAPI_PTR BRIDGEAPI_CALL - -#ifdef BRIDGE_API_IMPORT - #define BRIDGE_API __declspec(dllimport) -#else - #define BRIDGE_API __declspec(dllexport) -#endif - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - - typedef enum bridgeapi_ErrorCode { - BRIDGEAPI_ERROR_CODE_SUCCESS = 0, - BRIDGEAPI_ERROR_CODE_GENERAL_FAILURE = 1, - // WinAPI's GetModuleHandle has failed - BRIDGEAPI_ERROR_CODE_GET_MODULE_HANDLE_FAILURE = 2, - BRIDGEAPI_ERROR_CODE_INVALID_ARGUMENTS = 3, - // Couldn't find 'remixInitialize' function in the .dll - BRIDGEAPI_ERROR_CODE_GET_PROC_ADDRESS_FAILURE = 4, - // CreateD3D9 / RegisterD3D9Device can be called only once - BRIDGEAPI_ERROR_CODE_ALREADY_EXISTS = 5, - // RegisterD3D9Device requires the device that was created with IDirect3DDevice9Ex, returned by CreateD3D9 - BRIDGEAPI_ERROR_CODE_REGISTERING_NON_REMIX_D3D9_DEVICE = 6, - // RegisterD3D9Device was not called - BRIDGEAPI_ERROR_CODE_REMIX_DEVICE_WAS_NOT_REGISTERED = 7, - BRIDGEAPI_ERROR_CODE_INCOMPATIBLE_VERSION = 8, - // WinAPI's SetDllDirectory has failed - //BRIDGEAPI_ERROR_CODE_SET_DLL_DIRECTORY_FAILURE = 9, - // WinAPI's GetFullPathName has failed - //BRIDGEAPI_ERROR_CODE_GET_FULL_PATH_NAME_FAILURE = 10, - BRIDGEAPI_ERROR_CODE_NOT_INITIALIZED = 11, - } BRIDGEAPI_ErrorCode; - - // ------------------------------------------ - // <- remix api types from the remix_c header - - typedef enum remixapi_StructType { - REMIXAPI_STRUCT_TYPE_NONE = 0, - REMIXAPI_STRUCT_TYPE_INITIALIZE_LIBRARY_INFO = 1, - REMIXAPI_STRUCT_TYPE_MATERIAL_INFO = 2, - REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_PORTAL_EXT = 3, - REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_TRANSLUCENT_EXT = 4, - REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_OPAQUE_EXT = 5, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO = 6, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT = 7, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT = 8, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT = 9, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT = 10, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT = 11, - REMIXAPI_STRUCT_TYPE_MESH_INFO = 12, - REMIXAPI_STRUCT_TYPE_INSTANCE_INFO = 13, - REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_BONE_TRANSFORMS_EXT = 14, - REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_BLEND_EXT = 15, - REMIXAPI_STRUCT_TYPE_CAMERA_INFO = 16, - REMIXAPI_STRUCT_TYPE_CAMERA_INFO_PARAMETERIZED_EXT = 17, - REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_OPAQUE_SUBSURFACE_EXT = 18, - REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_OBJECT_PICKING_EXT = 19, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DOME_EXT = 20, - REMIXAPI_STRUCT_TYPE_LIGHT_INFO_USD_EXT = 21, - REMIXAPI_STRUCT_TYPE_STARTUP_INFO = 22, - REMIXAPI_STRUCT_TYPE_PRESENT_INFO = 23, - // NOTE: if adding a new struct, register it in 'rtx_remix_specialization.inl' - } remixapi_StructType; - - namespace x86 - { - typedef uint32_t remixapi_Bool; - - typedef struct remixapi_Rect2D { - int32_t left; - int32_t top; - int32_t right; - int32_t bottom; - } remixapi_Rect2D; - - typedef struct remixapi_Float2D { - float x; - float y; - } remixapi_Float2D; - - typedef struct remixapi_Float3D { - float x; - float y; - float z; - } remixapi_Float3D; - - typedef struct remixapi_Float4D { - float x; - float y; - float z; - float w; - } remixapi_Float4D; - - typedef struct remixapi_Transform { - float matrix[3][4]; - } remixapi_Transform; - - //typedef struct remixapi_MaterialHandle_T* remixapi_MaterialHandle; - //typedef struct remixapi_MeshHandle_T* remixapi_MeshHandle; - //typedef struct remixapi_LightHandle_T* remixapi_LightHandle; - - typedef const wchar_t* remixapi_Path; - - typedef struct remixapi_MaterialInfoOpaqueEXT { - remixapi_StructType sType; - //void* pNext; - remixapi_Path roughnessTexture; - remixapi_Path metallicTexture; - float anisotropy; - remixapi_Float3D albedoConstant; - float opacityConstant; - float roughnessConstant; - float metallicConstant; - remixapi_Bool thinFilmThickness_hasvalue; - float thinFilmThickness_value; - remixapi_Bool alphaIsThinFilmThickness; - remixapi_Path heightTexture; - float heightTextureStrength; - // If true, InstanceInfoBlendEXT is used as a source for alpha state - remixapi_Bool useDrawCallAlphaState; - remixapi_Bool blendType_hasvalue; - int blendType_value; - remixapi_Bool invertedBlend; - int alphaTestType; - uint8_t alphaReferenceValue; - } remixapi_MaterialInfoOpaqueEXT; - - // Valid only if remixapi_MaterialInfo contains remixapi_MaterialInfoOpaqueEXT in pNext chain - typedef struct remixapi_MaterialInfoOpaqueSubsurfaceEXT { - remixapi_StructType sType; - //void* pNext; - remixapi_Path subsurfaceTransmittanceTexture; - remixapi_Path subsurfaceThicknessTexture; - remixapi_Path subsurfaceSingleScatteringAlbedoTexture; - remixapi_Float3D subsurfaceTransmittanceColor; - float subsurfaceMeasurementDistance; - remixapi_Float3D subsurfaceSingleScatteringAlbedo; - float subsurfaceVolumetricAnisotropy; - } remixapi_MaterialInfoOpaqueSubsurfaceEXT; - - typedef struct remixapi_MaterialInfoTranslucentEXT { - remixapi_StructType sType; - //void* pNext; - remixapi_Path transmittanceTexture; - float refractiveIndex; - remixapi_Float3D transmittanceColor; - float transmittanceMeasurementDistance; - remixapi_Bool thinWallThickness_hasvalue; - float thinWallThickness_value; - remixapi_Bool useDiffuseLayer; - } remixapi_MaterialInfoTranslucentEXT; - - typedef struct remixapi_MaterialInfoPortalEXT { - remixapi_StructType sType; - //void* pNext; - uint8_t rayPortalIndex; - float rotationSpeed; - } remixapi_MaterialInfoPortalEXT; - - typedef struct remixapi_MaterialInfo { - remixapi_StructType sType; - //void* pNext; - uint64_t hash; - remixapi_Path albedoTexture; - remixapi_Path normalTexture; - remixapi_Path tangentTexture; - remixapi_Path emissiveTexture; - float emissiveIntensity; - remixapi_Float3D emissiveColorConstant; - uint8_t spriteSheetRow; - uint8_t spriteSheetCol; - uint8_t spriteSheetFps; - uint8_t filterMode; // Nearest: 0 Linear: 1 - uint8_t wrapModeU; // Clamp: 0 Repeat: 1 Mirrored_Repeat: 2 Clip: 3 - uint8_t wrapModeV; // Clamp: 0 Repeat: 1 Mirrored_Repeat: 2 Clip: 3 - } remixapi_MaterialInfo; - - - typedef struct remixapi_HardcodedVertex { - float position[3]; - float normal[3]; - float texcoord[2]; - uint32_t color; - uint32_t _pad0; - uint32_t _pad1; - uint32_t _pad2; - uint32_t _pad3; - uint32_t _pad4; - uint32_t _pad5; - uint32_t _pad6; - } remixapi_HardcodedVertex; - - // # TODO remixapi_MeshInfoSkinning - - typedef struct remixapi_MeshInfoSurfaceTriangles { - const remixapi_HardcodedVertex* vertices_values; - uint64_t vertices_count; - const uint32_t* indices_values; - uint64_t indices_count; - remixapi_Bool skinning_hasvalue; - //remixapi_MeshInfoSkinning skinning_value; // # TODO - uint64_t material; // CHANGED - was remixapi_MaterialHandle - } remixapi_MeshInfoSurfaceTriangles; - - typedef struct remixapi_MeshInfo { - remixapi_StructType sType; - //void* pNext; - uint64_t hash; - const remixapi_MeshInfoSurfaceTriangles* surfaces_values; - uint32_t surfaces_count; - } remixapi_MeshInfo; - - - typedef struct remixapi_LightInfoLightShaping { - // The direction the Light Shaping is pointing in. Must be normalized. - remixapi_Float3D direction; - float coneAngleDegrees; - float coneSoftness; - float focusExponent; - } remixapi_LightInfoLightShaping; - - typedef struct remixapi_LightInfoSphereEXT { - remixapi_StructType sType; - //void* pNext; - remixapi_Float3D position; - float radius; - remixapi_Bool shaping_hasvalue; - remixapi_LightInfoLightShaping shaping_value; - } remixapi_LightInfoSphereEXT; - - typedef struct remixapi_LightInfoRectEXT { - remixapi_StructType sType; - //void* pNext; - remixapi_Float3D position; - // The X axis of the Rect Light. Must be normalized and orthogonal to the Y and direction axes. - remixapi_Float3D xAxis; - float xSize; - // The Y axis of the Rect Light. Must be normalized and orthogonal to the X and direction axes. - remixapi_Float3D yAxis; - float ySize; - // The direction the Rect Light is pointing in, should match the Shaping direction if present. - // Must be normalized and orthogonal to the X and Y axes. - remixapi_Float3D direction; - remixapi_Bool shaping_hasvalue; - remixapi_LightInfoLightShaping shaping_value; - } remixapi_LightInfoRectEXT; - - typedef struct remixapi_LightInfoDiskEXT { - remixapi_StructType sType; - //void* pNext; - remixapi_Float3D position; - // The X axis of the Disk Light. Must be normalized and orthogonal to the Y and direction axes. - remixapi_Float3D xAxis; - float xRadius; - // The Y axis of the Disk Light. Must be normalized and orthogonal to the X and direction axes. - remixapi_Float3D yAxis; - float yRadius; - // The direction the Disk Light is pointing in, should match the Shaping direction if present - // Must be normalized and orthogonal to the X and Y axes. - remixapi_Float3D direction; - remixapi_Bool shaping_hasvalue; - remixapi_LightInfoLightShaping shaping_value; - } remixapi_LightInfoDiskEXT; - - typedef struct remixapi_LightInfoCylinderEXT { - remixapi_StructType sType; - //void* pNext; - remixapi_Float3D position; - float radius; - // The "center" axis of the Cylinder Light. Must be normalized. - remixapi_Float3D axis; - float axisLength; - } remixapi_LightInfoCylinderEXT; - - typedef struct remixapi_LightInfoDistantEXT { - remixapi_StructType sType; - //void* pNext; - // The direction the Distant Light is pointing in. Must be normalized. - remixapi_Float3D direction; - float angularDiameterDegrees; - } remixapi_LightInfoDistantEXT; - - typedef struct remixapi_LightInfo { - remixapi_StructType sType; - //void* pNext; - uint64_t hash; - remixapi_Float3D radiance; - } remixapi_LightInfo; - } - - // -------------------------------------------- - // remix api types end -> - - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DebugPrint)(const char* text); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateOpaqueMaterial)(const x86::remixapi_MaterialInfo* info, const x86::remixapi_MaterialInfoOpaqueEXT* ext, const x86::remixapi_MaterialInfoOpaqueSubsurfaceEXT* ext_ss); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateTranslucentMaterial)(const x86::remixapi_MaterialInfo* info, const x86::remixapi_MaterialInfoTranslucentEXT* ext); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreatePortalMaterial)(const x86::remixapi_MaterialInfo* info, const x86::remixapi_MaterialInfoPortalEXT* ext); - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DestroyMaterial)(uint64_t handle); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateTriangleMesh)(const x86::remixapi_MeshInfo* info); - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DestroyMesh)(uint64_t handle); - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DrawMeshInstance)(uint64_t handle, const x86::remixapi_Transform* t, x86::remixapi_Bool double_sided); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateSphereLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoSphereEXT* ext); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateRectLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoRectEXT* ext); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateDiskLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoDiskEXT* ext); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateCylinderLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoCylinderEXT* ext); - typedef uint64_t(BRIDGEAPI_PTR* PFN_bridgeapi_CreateDistantLight)(const x86::remixapi_LightInfo* info, const x86::remixapi_LightInfoDistantEXT* ext); - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DestroyLight)(uint64_t handle); - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_DrawLightInstance)(uint64_t handle); - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_SetConfigVariable)(const char* var, const char* value); - typedef void(BRIDGEAPI_PTR* PFN_bridgeapi_RegisterDevice)(void); - typedef void(__cdecl* PFN_bridgeapi_RegisterEndSceneCallback)(void); - - typedef struct bridgeapi_Interface { - bool initialized; - PFN_bridgeapi_DebugPrint DebugPrint; // const char* text - PFN_bridgeapi_CreateOpaqueMaterial CreateOpaqueMaterial; // x86::remixapi_MaterialInfo* - PFN_bridgeapi_CreateTranslucentMaterial CreateTranslucentMaterial; // x86::remixapi_MaterialInfo* --- x86::remixapi_MaterialInfoTranslucentEXT* - PFN_bridgeapi_CreatePortalMaterial CreatePortalMaterial; // x86::remixapi_MaterialInfo* --- x86::remixapi_MaterialInfoPortalEXT* - PFN_bridgeapi_DestroyMaterial DestroyMaterial; // uint64_t handle - PFN_bridgeapi_CreateTriangleMesh CreateTriangleMesh; // x86::remixapi_MeshInfo* - PFN_bridgeapi_DestroyMesh DestroyMesh; // uint64_t handle - PFN_bridgeapi_DrawMeshInstance DrawMeshInstance; // uint64_t handle --- x86::remixapi_Transform* t --- x86::remixapi_Bool double_sided - PFN_bridgeapi_CreateSphereLight CreateSphereLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoSphereEXT* - PFN_bridgeapi_CreateRectLight CreateRectLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoRectEXT* - PFN_bridgeapi_CreateDiskLight CreateDiskLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoDiskEXT* - PFN_bridgeapi_CreateCylinderLight CreateCylinderLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoCylinderEXT* - PFN_bridgeapi_CreateDistantLight CreateDistantLight; // x86::remixapi_LightInfo* --- x86::remixapi_LightInfoDistantEXT* - PFN_bridgeapi_DestroyLight DestroyLight; // uint64_t handle - PFN_bridgeapi_DrawLightInstance DrawLightInstance; // uint64_t handle - PFN_bridgeapi_SetConfigVariable SetConfigVariable; // const char* var --- const char* value - PFN_bridgeapi_RegisterDevice RegisterDevice; // void - void (*RegisterEndSceneCallback)(PFN_bridgeapi_RegisterEndSceneCallback callback); - } bridgeapi_Interface; - - BRIDGE_API BRIDGEAPI_ErrorCode __cdecl bridgeapi_InitFuncs(bridgeapi_Interface* out_result); - typedef BRIDGEAPI_ErrorCode(__cdecl* PFN_bridgeapi_InitFuncs)(bridgeapi_Interface* out_result); - - // -------- - // -------- - - inline BRIDGEAPI_ErrorCode bridgeapi_initialize(bridgeapi_Interface* out_bridgeInterface) { - - PFN_bridgeapi_InitFuncs pfn_Initialize = nullptr; - HMODULE hModule = GetModuleHandleA("d3d9.dll"); - if (hModule) { - PROC func = GetProcAddress(hModule, "bridgeapi_InitFuncs"); - if (func) { - pfn_Initialize = (PFN_bridgeapi_InitFuncs) func; - } - else { - return BRIDGEAPI_ERROR_CODE_GET_PROC_ADDRESS_FAILURE; - } - - bridgeapi_Interface bridgeInterface = { 0 }; - bridgeapi_ErrorCode status = pfn_Initialize(&bridgeInterface); - if (status != BRIDGEAPI_ERROR_CODE_SUCCESS) { - return status; - } - - bridgeInterface.initialized = true; - *out_bridgeInterface = bridgeInterface; - - return status; - } - return BRIDGEAPI_ERROR_CODE_GET_MODULE_HANDLE_FAILURE; - } - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // BRIDGE_C_H_ diff --git a/RtxDrv/Src/remix_c.h b/RtxDrv/Src/remix_c.h new file mode 100644 index 00000000..e41b4b9d --- /dev/null +++ b/RtxDrv/Src/remix_c.h @@ -0,0 +1,756 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +// Bridge API header for both the x86 bridge client and the x86 game + +#ifndef BRIDGE_C_H_ +#define BRIDGE_C_H_ + +#include "UnVcWin32.h" + +typedef BYTE uint8_t; +typedef INT int32_t; +typedef DWORD uint32_t; +typedef QWORD uint64_t; + +// __stdcall convention +#define REMIXAPI_CALL __stdcall +#define REMIXAPI_PTR REMIXAPI_CALL + +#ifdef REMIX_LIBRARY_EXPORTS + #define REMIXAPI __declspec(dllexport) +#else + #define REMIXAPI __declspec(dllimport) +#endif // REMIX_LIBRARY_EXPORTS + + +#define REMIXAPI_VERSION_MAKE(major, minor, patch) ( \ + (((uint64_t)(major)) << 48) | \ + (((uint64_t)(minor)) << 16) | \ + (((uint64_t)(patch)) ) ) +#define REMIXAPI_VERSION_GET_MAJOR(version) (((uint64_t)(version) >> 48) & (uint64_t)0xFFFF) +#define REMIXAPI_VERSION_GET_MINOR(version) (((uint64_t)(version) >> 16) & (uint64_t)0xFFFFFFFF) +#define REMIXAPI_VERSION_GET_PATCH(version) (((uint64_t)(version) ) & (uint64_t)0xFFFF) + +#define REMIXAPI_VERSION_MAJOR 0 +#define REMIXAPI_VERSION_MINOR 4 +#define REMIXAPI_VERSION_PATCH 1 + + +// External +typedef struct IDirect3D9Ex IDirect3D9Ex; +typedef struct IDirect3DDevice9Ex IDirect3DDevice9Ex; +typedef struct IDirect3DSurface9 IDirect3DSurface9; + + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + typedef enum remixapi_StructType { + REMIXAPI_STRUCT_TYPE_NONE = 0, + REMIXAPI_STRUCT_TYPE_INITIALIZE_LIBRARY_INFO = 1, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO = 2, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_PORTAL_EXT = 3, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_TRANSLUCENT_EXT = 4, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_OPAQUE_EXT = 5, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO = 6, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT = 7, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT = 8, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT = 9, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT = 10, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT = 11, + REMIXAPI_STRUCT_TYPE_MESH_INFO = 12, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO = 13, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_BONE_TRANSFORMS_EXT = 14, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_BLEND_EXT = 15, + REMIXAPI_STRUCT_TYPE_CAMERA_INFO = 16, + REMIXAPI_STRUCT_TYPE_CAMERA_INFO_PARAMETERIZED_EXT = 17, + REMIXAPI_STRUCT_TYPE_MATERIAL_INFO_OPAQUE_SUBSURFACE_EXT = 18, + REMIXAPI_STRUCT_TYPE_INSTANCE_INFO_OBJECT_PICKING_EXT = 19, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DOME_EXT = 20, + REMIXAPI_STRUCT_TYPE_LIGHT_INFO_USD_EXT = 21, + REMIXAPI_STRUCT_TYPE_STARTUP_INFO = 22, + REMIXAPI_STRUCT_TYPE_PRESENT_INFO = 23, + // NOTE: if adding a new struct, register it in 'rtx_remix_specialization.inl' + } remixapi_StructType; + + typedef enum remixapi_ErrorCode { + REMIXAPI_ERROR_CODE_SUCCESS = 0, + REMIXAPI_ERROR_CODE_GENERAL_FAILURE = 1, + // WinAPI's LoadLibrary has failed + REMIXAPI_ERROR_CODE_LOAD_LIBRARY_FAILURE = 2, + REMIXAPI_ERROR_CODE_INVALID_ARGUMENTS = 3, + // Couldn't find 'remixInitialize' function in the .dll + REMIXAPI_ERROR_CODE_GET_PROC_ADDRESS_FAILURE = 4, + // CreateD3D9 / RegisterD3D9Device can be called only once + REMIXAPI_ERROR_CODE_ALREADY_EXISTS = 5, + // RegisterD3D9Device requires the device that was created with IDirect3DDevice9Ex, returned by CreateD3D9 + REMIXAPI_ERROR_CODE_REGISTERING_NON_REMIX_D3D9_DEVICE = 6, + // RegisterD3D9Device was not called + REMIXAPI_ERROR_CODE_REMIX_DEVICE_WAS_NOT_REGISTERED = 7, + REMIXAPI_ERROR_CODE_INCOMPATIBLE_VERSION = 8, + // WinAPI's SetDllDirectory has failed + REMIXAPI_ERROR_CODE_SET_DLL_DIRECTORY_FAILURE = 9, + // WinAPI's GetFullPathName has failed + REMIXAPI_ERROR_CODE_GET_FULL_PATH_NAME_FAILURE = 10, + REMIXAPI_ERROR_CODE_NOT_INITIALIZED = 11, + // Error codes that are encoded as HRESULT, i.e. returned from D3D9 functions. + // Look MAKE_D3DHRESULT, but with _FACD3D=0x896, instead of D3D9's 0x876 + REMIXAPI_ERROR_CODE_HRESULT_NO_REQUIRED_GPU_FEATURES = 0x88960001, + REMIXAPI_ERROR_CODE_HRESULT_DRIVER_VERSION_BELOW_MINIMUM = 0x88960002, + REMIXAPI_ERROR_CODE_HRESULT_DXVK_INSTANCE_EXTENSION_FAIL = 0x88960003, + REMIXAPI_ERROR_CODE_HRESULT_VK_CREATE_INSTANCE_FAIL = 0x88960004, + REMIXAPI_ERROR_CODE_HRESULT_VK_CREATE_DEVICE_FAIL = 0x88960005, + REMIXAPI_ERROR_CODE_HRESULT_GRAPHICS_QUEUE_FAMILY_MISSING = 0x88960006, + } remixapi_ErrorCode; + + typedef uint32_t remixapi_Bool; + + typedef struct remixapi_Rect2D { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; + } remixapi_Rect2D; + + typedef struct remixapi_Float2D { + float x; + float y; + } remixapi_Float2D; + + typedef struct remixapi_Float3D { + float x; + float y; + float z; + } remixapi_Float3D; + + typedef struct remixapi_Float4D { + float x; + float y; + float z; + float w; + } remixapi_Float4D; + + typedef struct remixapi_Transform { + float matrix[3][4]; + } remixapi_Transform; + + typedef struct remixapi_MaterialHandle_T* remixapi_MaterialHandle; + typedef struct remixapi_MeshHandle_T* remixapi_MeshHandle; + typedef struct remixapi_LightHandle_T* remixapi_LightHandle; + + typedef const wchar_t* remixapi_Path; + + + + typedef struct remixapi_StartupInfo { + remixapi_StructType sType; + void* pNext; + HWND hwnd; + remixapi_Bool disableSrgbConversionForOutput; + // If true, 'dxvk_GetExternalSwapchain' can be used to retrieve a raw VkImage, + // so the application can present it, for example by using OpenGL interop: + // converting VkImage to OpenGL, and presenting it via OpenGL. + // Default: false. Use VkSwapchainKHR to present frame into HWND. + remixapi_Bool forceNoVkSwapchain; + remixapi_Bool editorModeEnabled; + } remixapi_StartupInfo; + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_Startup)(const remixapi_StartupInfo* info); + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_Shutdown)(void); + + + + typedef struct remixapi_MaterialInfoOpaqueEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Path roughnessTexture; + remixapi_Path metallicTexture; + float anisotropy; + remixapi_Float3D albedoConstant; + float opacityConstant; + float roughnessConstant; + float metallicConstant; + remixapi_Bool thinFilmThickness_hasvalue; + float thinFilmThickness_value; + remixapi_Bool alphaIsThinFilmThickness; + remixapi_Path heightTexture; + float heightTextureStrength; + // If true, InstanceInfoBlendEXT is used as a source for alpha state + remixapi_Bool useDrawCallAlphaState; + remixapi_Bool blendType_hasvalue; + int blendType_value; + remixapi_Bool invertedBlend; + int alphaTestType; + uint8_t alphaReferenceValue; + } remixapi_MaterialInfoOpaqueEXT; + + // Valid only if remixapi_MaterialInfo contains remixapi_MaterialInfoOpaqueEXT in pNext chain + typedef struct remixapi_MaterialInfoOpaqueSubsurfaceEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Path subsurfaceTransmittanceTexture; + remixapi_Path subsurfaceThicknessTexture; + remixapi_Path subsurfaceSingleScatteringAlbedoTexture; + remixapi_Float3D subsurfaceTransmittanceColor; + float subsurfaceMeasurementDistance; + remixapi_Float3D subsurfaceSingleScatteringAlbedo; + float subsurfaceVolumetricAnisotropy; + } remixapi_MaterialInfoOpaqueSubsurfaceEXT; + + typedef struct remixapi_MaterialInfoTranslucentEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Path transmittanceTexture; + float refractiveIndex; + remixapi_Float3D transmittanceColor; + float transmittanceMeasurementDistance; + remixapi_Bool thinWallThickness_hasvalue; + float thinWallThickness_value; + remixapi_Bool useDiffuseLayer; + } remixapi_MaterialInfoTranslucentEXT; + + typedef struct remixapi_MaterialInfoPortalEXT { + remixapi_StructType sType; + void* pNext; + uint8_t rayPortalIndex; + float rotationSpeed; + } remixapi_MaterialInfoPortalEXT; + + typedef struct remixapi_MaterialInfo { + remixapi_StructType sType; + void* pNext; + uint64_t hash; + remixapi_Path albedoTexture; + remixapi_Path normalTexture; + remixapi_Path tangentTexture; + remixapi_Path emissiveTexture; + float emissiveIntensity; + remixapi_Float3D emissiveColorConstant; + uint8_t spriteSheetRow; + uint8_t spriteSheetCol; + uint8_t spriteSheetFps; + uint8_t filterMode; + uint8_t wrapModeU; + uint8_t wrapModeV; + } remixapi_MaterialInfo; + + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_CreateMaterial)( + const remixapi_MaterialInfo* info, + remixapi_MaterialHandle* out_handle); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_DestroyMaterial)( + remixapi_MaterialHandle handle); + + typedef struct remixapi_HardcodedVertex { + float position[3]; + float normal[3]; + float texcoord[2]; + uint32_t color; + uint32_t _pad0; + uint32_t _pad1; + uint32_t _pad2; + uint32_t _pad3; + uint32_t _pad4; + uint32_t _pad5; + uint32_t _pad6; + } remixapi_HardcodedVertex; + + typedef struct remixapi_MeshInfoSkinning { + uint32_t bonesPerVertex; + // Each tuple of 'bonesPerVertex' float-s defines a vertex. + // I.e. the size must be (bonesPerVertex * vertexCount). + const float* blendWeights_values; + uint32_t blendWeights_count; + // Each tuple of 'bonesPerVertex' uint32_t-s defines a vertex. + // I.e. the size must be (bonesPerVertex * vertexCount). + const uint32_t* blendIndices_values; + uint32_t blendIndices_count; + } remixapi_MeshInfoSkinning; + + typedef struct remixapi_MeshInfoSurfaceTriangles { + const remixapi_HardcodedVertex* vertices_values; + uint64_t vertices_count; + const uint32_t* indices_values; + uint64_t indices_count; + remixapi_Bool skinning_hasvalue; + remixapi_MeshInfoSkinning skinning_value; + remixapi_MaterialHandle material; + } remixapi_MeshInfoSurfaceTriangles; + + typedef struct remixapi_MeshInfo { + remixapi_StructType sType; + void* pNext; + uint64_t hash; + const remixapi_MeshInfoSurfaceTriangles* surfaces_values; + uint32_t surfaces_count; + } remixapi_MeshInfo; + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_CreateMesh)( + const remixapi_MeshInfo* info, + remixapi_MeshHandle* out_handle); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_DestroyMesh)( + remixapi_MeshHandle handle); + + + + typedef enum remixapi_CameraType { + REMIXAPI_CAMERA_TYPE_WORLD, + REMIXAPI_CAMERA_TYPE_SKY, + REMIXAPI_CAMERA_TYPE_VIEW_MODEL, + } remixapi_CameraType; + + typedef struct remixapi_CameraInfoParameterizedEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Float3D position; + remixapi_Float3D forward; + remixapi_Float3D up; + remixapi_Float3D right; + float fovYInDegrees; + float aspect; + float nearPlane; + float farPlane; + } remixapi_CameraInfoParameterizedEXT; + + typedef struct remixapi_CameraInfo { + remixapi_StructType sType; + void* pNext; + remixapi_CameraType type; + float view[4][4]; + float projection[4][4]; + } remixapi_CameraInfo; + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_SetupCamera)( + const remixapi_CameraInfo* info); + + + +#define REMIXAPI_INSTANCE_INFO_MAX_BONES_COUNT 256 + + typedef struct remixapi_InstanceInfoBoneTransformsEXT { + remixapi_StructType sType; + void* pNext; + const remixapi_Transform* boneTransforms_values; + uint32_t boneTransforms_count; + } remixapi_InstanceInfoBoneTransformsEXT; + + typedef struct remixapi_InstanceInfoBlendEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Bool alphaTestEnabled; + uint8_t alphaTestReferenceValue; + uint32_t alphaTestCompareOp; + remixapi_Bool alphaBlendEnabled; + uint32_t srcColorBlendFactor; + uint32_t dstColorBlendFactor; + uint32_t colorBlendOp; + uint32_t textureColorArg1Source; + uint32_t textureColorArg2Source; + uint32_t textureColorOperation; + uint32_t textureAlphaArg1Source; + uint32_t textureAlphaArg2Source; + uint32_t textureAlphaOperation; + uint32_t tFactor; + remixapi_Bool isTextureFactorBlend; + } remixapi_InstanceInfoBlendEXT; + + typedef struct remixapi_InstanceInfoObjectPickingEXT { + remixapi_StructType sType; + void* pNext; + // A value to write for 'RequestObjectPicking' + uint32_t objectPickingValue; + } remixapi_InstanceInfoObjectPickingEXT; + + typedef enum remixapi_InstanceCategoryBit { + REMIXAPI_INSTANCE_CATEGORY_BIT_WORLD_UI = 1 << 0, + REMIXAPI_INSTANCE_CATEGORY_BIT_WORLD_MATTE = 1 << 1, + REMIXAPI_INSTANCE_CATEGORY_BIT_SKY = 1 << 2, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE = 1 << 3, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_LIGHTS = 1 << 4, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_ANTI_CULLING = 1 << 5, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_MOTION_BLUR = 1 << 6, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_OPACITY_MICROMAP = 1 << 7, + REMIXAPI_INSTANCE_CATEGORY_BIT_HIDDEN = 1 << 8, + REMIXAPI_INSTANCE_CATEGORY_BIT_PARTICLE = 1 << 9, + REMIXAPI_INSTANCE_CATEGORY_BIT_BEAM = 1 << 10, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_STATIC = 1 << 11, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_DYNAMIC = 1 << 12, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_SINGLE_OFFSET = 1 << 13, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_NO_OFFSET = 1 << 14, + REMIXAPI_INSTANCE_CATEGORY_BIT_ALPHA_BLEND_TO_CUTOUT = 1 << 15, + REMIXAPI_INSTANCE_CATEGORY_BIT_TERRAIN = 1 << 16, + REMIXAPI_INSTANCE_CATEGORY_BIT_ANIMATED_WATER = 1 << 17, + REMIXAPI_INSTANCE_CATEGORY_BIT_THIRD_PERSON_PLAYER_MODEL = 1 << 18, + REMIXAPI_INSTANCE_CATEGORY_BIT_THIRD_PERSON_PLAYER_BODY = 1 << 19, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_BAKED_LIGHTING = 1 << 20, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_ALPHA_CHANNEL = 1 << 21, + } remixapi_InstanceCategoryBit; + + typedef uint32_t remixapi_InstanceCategoryFlags; + + typedef struct remixapi_InstanceInfo { + remixapi_StructType sType; + void* pNext; + remixapi_InstanceCategoryFlags categoryFlags; + remixapi_MeshHandle mesh; + remixapi_Transform transform; + remixapi_Bool doubleSided; + } remixapi_InstanceInfo; + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_DrawInstance)( + const remixapi_InstanceInfo* info); + + + + typedef struct remixapi_LightInfoLightShaping { + // The direction the Light Shaping is pointing in. Must be normalized. + remixapi_Float3D direction; + float coneAngleDegrees; + float coneSoftness; + float focusExponent; + } remixapi_LightInfoLightShaping; + + typedef struct remixapi_LightInfoSphereEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Float3D position; + float radius; + remixapi_Bool shaping_hasvalue; + remixapi_LightInfoLightShaping shaping_value; + } remixapi_LightInfoSphereEXT; + + typedef struct remixapi_LightInfoRectEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Float3D position; + // The X axis of the Rect Light. Must be normalized and orthogonal to the Y and direction axes. + remixapi_Float3D xAxis; + float xSize; + // The Y axis of the Rect Light. Must be normalized and orthogonal to the X and direction axes. + remixapi_Float3D yAxis; + float ySize; + // The direction the Rect Light is pointing in, should match the Shaping direction if present. + // Must be normalized and orthogonal to the X and Y axes. + remixapi_Float3D direction; + remixapi_Bool shaping_hasvalue; + remixapi_LightInfoLightShaping shaping_value; + } remixapi_LightInfoRectEXT; + + typedef struct remixapi_LightInfoDiskEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Float3D position; + // The X axis of the Disk Light. Must be normalized and orthogonal to the Y and direction axes. + remixapi_Float3D xAxis; + float xRadius; + // The Y axis of the Disk Light. Must be normalized and orthogonal to the X and direction axes. + remixapi_Float3D yAxis; + float yRadius; + // The direction the Disk Light is pointing in, should match the Shaping direction if present + // Must be normalized and orthogonal to the X and Y axes. + remixapi_Float3D direction; + remixapi_Bool shaping_hasvalue; + remixapi_LightInfoLightShaping shaping_value; + } remixapi_LightInfoDiskEXT; + + typedef struct remixapi_LightInfoCylinderEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Float3D position; + float radius; + // The "center" axis of the Cylinder Light. Must be normalized. + remixapi_Float3D axis; + float axisLength; + } remixapi_LightInfoCylinderEXT; + + typedef struct remixapi_LightInfoDistantEXT { + remixapi_StructType sType; + void* pNext; + // The direction the Distant Light is pointing in. Must be normalized. + remixapi_Float3D direction; + float angularDiameterDegrees; + } remixapi_LightInfoDistantEXT; + + typedef struct remixapi_LightInfoDomeEXT { + remixapi_StructType sType; + void* pNext; + remixapi_Transform transform; + remixapi_Path colorTexture; + } remixapi_LightInfoDomeEXT; + + // Attachable to remixapi_LightInfo. + // If attached, 'remixapi_LightInfo::radiance' is ignored. + // Any other attached 'remixapi_LightInfo*EXT' are ignored. + // Most fields correspond to a usd token. Set to null, if no value. + typedef struct remixapi_LightInfoUSDEXT { + remixapi_StructType sType; + void* pNext; + remixapi_StructType lightType; + remixapi_Transform transform; + const float* pRadius; // "radius" + const float* pWidth; // "width" + const float* pHeight; // "height" + const float* pLength; // "length" + const float* pAngleRadians; // "angle" + const remixapi_Bool* pEnableColorTemp; // "enableColorTemperature" + const remixapi_Float3D* pColor; // "color" + const float* pColorTemp; // "colorTemperature" + const float* pExposure; // "exposure" + const float* pIntensity; // "intensity" + const float* pConeAngleRadians; // "shaping:cone:angle" + const float* pConeSoftness; // "shaping:cone:softness" + const float* pFocus; // "shaping:focus" + } remixapi_LightInfoUSDEXT; + + typedef struct remixapi_LightInfo { + remixapi_StructType sType; + void* pNext; + uint64_t hash; + remixapi_Float3D radiance; + } remixapi_LightInfo; + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_CreateLight)( + const remixapi_LightInfo* info, + remixapi_LightHandle* out_handle); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_DestroyLight)( + remixapi_LightHandle handle); + + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_DrawLightInstance)( + remixapi_LightHandle lightHandle); + + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_SetConfigVariable)( + const char* key, + const char* value); + + typedef struct remixapi_PresentInfo { + remixapi_StructType sType; + void* pNext; + HWND hwndOverride; // Can be NULL + } remixapi_PresentInfo; + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_Present)(const remixapi_PresentInfo* info); + + typedef void (REMIXAPI_PTR* PFN_remixapi_pick_RequestObjectPickingUserCallback)( + const uint32_t* objectPickingValues_values, + uint32_t objectPickingValues_count, + void* callbackUserData); + + // Invokes 'callback' on a successful readback of 'remixapi_InstanceInfoObjectPickingEXT::objectPickingValue' + // of objects that are drawn in the 'pixelRegion'. 'pixelRegion' specified relative to the output size, + // not render size. 'callback' can be invoked from any thread. + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_pick_RequestObjectPicking)( + const remixapi_Rect2D* pixelRegion, + PFN_remixapi_pick_RequestObjectPickingUserCallback callback, + void* callbackUserData); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_pick_HighlightObjects)( + const uint32_t* objectPickingValues_values, + uint32_t objectPickingValues_count, + uint8_t colorR, + uint8_t colorG, + uint8_t colorB); + + + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_dxvk_CreateD3D9)( + remixapi_Bool editorModeEnabled, + IDirect3D9Ex** out_pD3D9); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_dxvk_RegisterD3D9Device)( + IDirect3DDevice9Ex* d3d9Device); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_dxvk_GetExternalSwapchain)( + uint64_t* out_vkImage, + uint64_t* out_vkSemaphoreRenderingDone, + uint64_t* out_vkSemaphoreResumeSemaphore); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_dxvk_GetVkImage)( + IDirect3DSurface9* source, + uint64_t* out_vkImage); + + typedef enum remixapi_dxvk_CopyRenderingOutputType { + REMIXAPI_DXVK_COPY_RENDERING_OUTPUT_TYPE_FINAL_COLOR = 0, + REMIXAPI_DXVK_COPY_RENDERING_OUTPUT_TYPE_DEPTH = 1, + REMIXAPI_DXVK_COPY_RENDERING_OUTPUT_TYPE_NORMALS = 2, + REMIXAPI_DXVK_COPY_RENDERING_OUTPUT_TYPE_OBJECT_PICKING = 3, + } remixapi_dxvk_CopyRenderingOutputType; + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_dxvk_CopyRenderingOutput)( + IDirect3DSurface9* destination, + remixapi_dxvk_CopyRenderingOutputType type); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_dxvk_SetDefaultOutput)( + remixapi_dxvk_CopyRenderingOutputType type, + const remixapi_Float4D* color); + + + typedef struct remixapi_InitializeLibraryInfo { + remixapi_StructType sType; + void* pNext; + uint64_t version; + } remixapi_InitializeLibraryInfo; + + typedef struct remixapi_Interface { + PFN_remixapi_Shutdown Shutdown; + PFN_remixapi_CreateMaterial CreateMaterial; + PFN_remixapi_DestroyMaterial DestroyMaterial; + PFN_remixapi_CreateMesh CreateMesh; + PFN_remixapi_DestroyMesh DestroyMesh; + PFN_remixapi_SetupCamera SetupCamera; + PFN_remixapi_DrawInstance DrawInstance; + PFN_remixapi_CreateLight CreateLight; + PFN_remixapi_DestroyLight DestroyLight; + PFN_remixapi_DrawLightInstance DrawLightInstance; + PFN_remixapi_SetConfigVariable SetConfigVariable; + + // DXVK interoperability + PFN_remixapi_dxvk_CreateD3D9 dxvk_CreateD3D9; + PFN_remixapi_dxvk_RegisterD3D9Device dxvk_RegisterD3D9Device; + PFN_remixapi_dxvk_GetExternalSwapchain dxvk_GetExternalSwapchain; + PFN_remixapi_dxvk_GetVkImage dxvk_GetVkImage; + PFN_remixapi_dxvk_CopyRenderingOutput dxvk_CopyRenderingOutput; + PFN_remixapi_dxvk_SetDefaultOutput dxvk_SetDefaultOutput; + // Object picking utils + PFN_remixapi_pick_RequestObjectPicking pick_RequestObjectPicking; + PFN_remixapi_pick_HighlightObjects pick_HighlightObjects; + + PFN_remixapi_Startup Startup; + PFN_remixapi_Present Present; + } remixapi_Interface; + + REMIXAPI remixapi_ErrorCode REMIXAPI_CALL remixapi_InitializeLibrary( + const remixapi_InitializeLibraryInfo* info, + remixapi_Interface* out_result); + + typedef remixapi_ErrorCode(REMIXAPI_CALL* PFN_remixapi_InitializeLibrary)( + const remixapi_InitializeLibraryInfo* info, + remixapi_Interface* out_result); + + + inline remixapi_ErrorCode REMIXAPI_CALL remixapi_lib_loadRemixDllAndInitialize( + const wchar_t* remixD3D9DllPath, + remixapi_Interface* out_remixInterface, + HMODULE* out_remixDll + ) { + if (remixD3D9DllPath == NULL || remixD3D9DllPath[0] == '\0') { + return REMIXAPI_ERROR_CODE_INVALID_ARGUMENTS; + } + if (out_remixInterface == NULL || out_remixDll == NULL) { + return REMIXAPI_ERROR_CODE_INVALID_ARGUMENTS; + } + + HMODULE remixDll = NULL; + PFN_remixapi_InitializeLibrary pfn_InitializeLibrary = NULL; + { + // firstly, try the default method first, e.g. DLL is already loaded, + // DLL-s are around .exe, or an app has called SetDllDirectory + { + HMODULE dll = LoadLibraryW(remixD3D9DllPath); + if (dll) { + PROC func = GetProcAddress(dll, "remixapi_InitializeLibrary"); + if (func) { + remixDll = dll; + pfn_InitializeLibrary = (PFN_remixapi_InitializeLibrary) func; + } else { + FreeLibrary(dll); + } + } + } + + // then try raw user-provided 'remixD3D9DllPath' file + if (!pfn_InitializeLibrary) { + // set LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR to search + // dependency DLL-s in the folder of 'remixD3D9DllPath' + HMODULE dll = LoadLibraryW(remixD3D9DllPath); + if (dll) { + PROC func = GetProcAddress(dll, "remixapi_InitializeLibrary"); + if (func) { + remixDll = dll; + pfn_InitializeLibrary = (PFN_remixapi_InitializeLibrary) func; + } else { + FreeLibrary(dll); + } + } + } + } + + if (!remixDll) { + return REMIXAPI_ERROR_CODE_LOAD_LIBRARY_FAILURE; + } + if (!pfn_InitializeLibrary){ + return REMIXAPI_ERROR_CODE_GET_PROC_ADDRESS_FAILURE; + } + + remixapi_InitializeLibraryInfo info; + { + info.pNext = NULL; + info.sType = REMIXAPI_STRUCT_TYPE_INITIALIZE_LIBRARY_INFO; + info.version = REMIXAPI_VERSION_MAKE(REMIXAPI_VERSION_MAJOR, + REMIXAPI_VERSION_MINOR, + REMIXAPI_VERSION_PATCH); + } + remixapi_Interface remixInterface = { 0 }; + + remixapi_ErrorCode status = pfn_InitializeLibrary(&info, &remixInterface); + if (status != REMIXAPI_ERROR_CODE_SUCCESS) { + FreeLibrary(remixDll); + return status; + } + + *out_remixInterface = remixInterface; + *out_remixDll = remixDll; + return status; + } + + inline remixapi_ErrorCode REMIXAPI_CALL remixapi_lib_shutdownAndUnloadRemixDll( + remixapi_Interface* remixInterface, + HMODULE remixDll + ) { + if (remixInterface == NULL || remixInterface->Shutdown == NULL) { + if (remixDll != NULL) { + FreeLibrary(remixDll); + } + return REMIXAPI_ERROR_CODE_INVALID_ARGUMENTS; + } + + remixapi_ErrorCode status = remixInterface->Shutdown(); + if (remixDll != NULL) { + FreeLibrary(remixDll); + } + + remixapi_Interface nullInterface = { 0 }; + *remixInterface = nullInterface; + return status; + } + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // REMIX_C_H_ From 36542051a6f374061b801081fb1547609da3ff1f Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Thu, 26 Sep 2024 00:06:17 +0200 Subject: [PATCH 25/48] Add capture mode where everything is drawn without culling --- RtxDrv/Classes/RtxInterface.uc | 1 + RtxDrv/Inc/RtxDrvClasses.h | 1 + RtxDrv/Src/RtxRenderDevice.cpp | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/RtxInterface.uc index 3e9a2893..2ecabffd 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/RtxInterface.uc @@ -2,6 +2,7 @@ class RtxInterface extends Object within RtxRenderDevice native transient config var(General) config color AnchorTriangleColor; var(General) config bool bDrawAnchorTriangle; +var(General) config bool bCaptureMode; var(Lighting) bool bEnableLights; var(Lighting) editinline array Lights; diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 28cf3b7a..3bc861ab 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -22,6 +22,7 @@ class RTXDRV_API URtxInterface : public UObject public: FColor AnchorTriangleColor; BITFIELD bDrawAnchorTriangle:1 GCC_PACK(4); + BITFIELD bCaptureMode:1; BITFIELD bEnableLights:1; TArrayNoInit Lights GCC_PACK(4); TArrayNoInit DestroyedLights; diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index f1fae68e..2ebca47e 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -134,6 +134,9 @@ void URtxRenderDevice::Flush(UViewport* Viewport) FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) { + if(Rtx->bCaptureMode) + Viewport->Precaching = 1; + DepthCleared = 0; D3D = Super::Lock(Viewport, HitData, HitSize); @@ -206,6 +209,10 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) } Rtx->RenderLights(); + + if(Rtx->bCaptureMode) + LockedViewport->Precaching = 0; + LockedViewport = NULL; Super::Unlock(static_cast(RI)->D3D); From ee1603696a9f7940e78d6fcee6cbb09ee7dcf403 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 30 Sep 2024 17:13:46 +0200 Subject: [PATCH 26/48] Rename RtxInterface to Rtx --- RtxDrv/Classes/{RtxInterface.uc => Rtx.uc} | 6 ++--- RtxDrv/Classes/RtxLight.uc | 2 +- RtxDrv/Inc/RtxDrvClasses.h | 8 +++---- RtxDrv/Src/Rtx.cpp | 26 +++++++++++----------- RtxDrv/Src/RtxDrvClasses.cpp | 6 ++--- RtxDrv/Src/RtxRenderDevice.cpp | 2 +- RtxDrv/Src/RtxRenderDevice.h | 6 ++--- 7 files changed, 28 insertions(+), 28 deletions(-) rename RtxDrv/Classes/{RtxInterface.uc => Rtx.uc} (77%) diff --git a/RtxDrv/Classes/RtxInterface.uc b/RtxDrv/Classes/Rtx.uc similarity index 77% rename from RtxDrv/Classes/RtxInterface.uc rename to RtxDrv/Classes/Rtx.uc index 2ecabffd..f7ffc53e 100644 --- a/RtxDrv/Classes/RtxInterface.uc +++ b/RtxDrv/Classes/Rtx.uc @@ -1,4 +1,4 @@ -class RtxInterface extends Object within RtxRenderDevice native transient config(RtxDrv) hidecategories(Object, None); +class Rtx extends Object within RtxRenderDevice native transient config(RtxDrv) hidecategories(Object, None); var(General) config color AnchorTriangleColor; var(General) config bool bDrawAnchorTriangle; @@ -7,13 +7,13 @@ var(General) config bool bCaptureMode; var(Lighting) bool bEnableLights; var(Lighting) editinline array Lights; -var array DestroyedLights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights +var const editconst array DestroyedLights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights native final function RtxLight CreateLight(); native final function DestroyLight(RtxLight Light); native final function DestroyAllLights(); -native static final function RtxInterface GetInstance(); +native static final function Rtx GetInstance(); cpptext { diff --git a/RtxDrv/Classes/RtxLight.uc b/RtxDrv/Classes/RtxLight.uc index 85e431e9..d5e034bc 100644 --- a/RtxDrv/Classes/RtxLight.uc +++ b/RtxDrv/Classes/RtxLight.uc @@ -1,4 +1,4 @@ -class RtxLight extends Object within RtxInterface native transient hidecategories(Object, None); +class RtxLight extends Object within Rtx native transient hidecategories(Object, None); var(Common) enum ERtxLightType{ RTXLIGHT_Sphere, diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 3bc861ab..40fbb750 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -17,7 +17,7 @@ -class RTXDRV_API URtxInterface : public UObject +class RTXDRV_API URtx : public UObject { public: FColor AnchorTriangleColor; @@ -30,14 +30,14 @@ class RTXDRV_API URtxInterface : public UObject void execDestroyLight(FFrame& Stack, void* Result); void execDestroyAllLights(FFrame& Stack, void* Result); void execGetInstance(FFrame& Stack, void* Result); - DECLARE_CLASS(URtxInterface,UObject,0|CLASS_Transient|CLASS_Config,RtxDrv) + DECLARE_CLASS(URtx,UObject,0|CLASS_Transient|CLASS_Config,RtxDrv) void Init(); void Exit(); URtxLight* CreateLight(bool ForceDefaultConstructed = false); void DestroyLight(URtxLight* Light); void DestroyAllLights(); void RenderLights(); - DECLARE_NATIVES(URtxInterface) + DECLARE_NATIVES(URtx) }; enum ERtxLightType @@ -131,7 +131,7 @@ class RTXDRV_API URtxLight : public UObject #define AUTO_INITIALIZE_REGISTRANTS_RTXDRV \ USolidColorMaterial::StaticClass(); \ - URtxInterface::StaticClass(); \ + URtx::StaticClass(); \ URtxLight::StaticClass(); \ URtxRenderDevice::StaticClass(); \ diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index f5a800bd..c49ed36a 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -3,7 +3,7 @@ static remixapi_Interface GRemixInterface; -void URtxInterface::Init() +void URtx::Init() { if(!GRemixInterface.Startup) { @@ -23,19 +23,19 @@ void URtxInterface::Init() DestroyedLights.SetNoShrink(true); } -void URtxInterface::Exit() +void URtx::Exit() { appMemzero(&GRemixInterface, sizeof(GRemixInterface)); } -URtxLight* URtxInterface::CreateLight(bool ForceDefaultConstructed) +URtxLight* URtx::CreateLight(bool ForceDefaultConstructed) { URtxLight* Light; if(!ForceDefaultConstructed && DestroyedLights.Num() > 0) Light = DestroyedLights.Pop(); else - Light = ConstructObject(URtxLight::StaticClass(), this); + Light = new(this) URtxLight; Light->bShouldBeDestroyed = 0; Light->bEnabled = 1; @@ -43,19 +43,19 @@ URtxLight* URtxInterface::CreateLight(bool ForceDefaultConstructed) return Light; } -void URtxInterface::DestroyLight(URtxLight* Light) +void URtx::DestroyLight(URtxLight* Light) { if(Light) Light->bShouldBeDestroyed = 1; } -void URtxInterface::DestroyAllLights() +void URtx::DestroyAllLights() { DestroyedLights += Lights; Lights.Empty(); } -void URtxInterface::RenderLights() +void URtx::RenderLights() { if(!bEnableLights) return; @@ -79,7 +79,7 @@ void URtxInterface::RenderLights() if(!Light) // NULL entry can happen if a light was added via the property window UI. In that case just create it { - Light = ConstructObject(URtxLight::StaticClass(), this); + Light = new(this) URtxLight; Lights[i] = Light; } @@ -94,33 +94,33 @@ void URtxInterface::RenderLights() } } -void URtxInterface::execCreateLight(FFrame& Stack, void* Result) +void URtx::execCreateLight(FFrame& Stack, void* Result) { P_FINISH; *static_cast(Result) = CreateLight(); } -void URtxInterface::execDestroyLight(FFrame& Stack, void* Result) +void URtx::execDestroyLight(FFrame& Stack, void* Result) { P_GET_OBJECT(URtxLight, Light); P_FINISH; DestroyLight(Light); } -void URtxInterface::execDestroyAllLights(FFrame& Stack, void* Result) +void URtx::execDestroyAllLights(FFrame& Stack, void* Result) { P_FINISH; DestroyAllLights(); } -void URtxInterface::execGetInstance(FFrame& Stack, void* Result) +void URtx::execGetInstance(FFrame& Stack, void* Result) { P_FINISH; URtxRenderDevice* RenDev = Cast(GEngine->GRenDev); if(RenDev) - *static_cast(Result) = RenDev->GetRtxInterface(); + *static_cast(Result) = RenDev->GetRtxInterface(); } diff --git a/RtxDrv/Src/RtxDrvClasses.cpp b/RtxDrv/Src/RtxDrvClasses.cpp index 92da0d54..5d4d9450 100644 --- a/RtxDrv/Src/RtxDrvClasses.cpp +++ b/RtxDrv/Src/RtxDrvClasses.cpp @@ -10,15 +10,15 @@ IMPLEMENT_PACKAGE(RtxDrv) -IMPLEMENT_CLASS(URtxInterface); -FNativeEntry URtxInterface::StaticNativeMap[] = { +IMPLEMENT_CLASS(URtx); +FNativeEntry URtx::StaticNativeMap[] = { MAP_NATIVE(CreateLight,0) MAP_NATIVE(DestroyLight,0) MAP_NATIVE(DestroyAllLights,0) MAP_NATIVE(GetInstance,0) {NULL,NULL} }; -LINK_NATIVES(URtxInterface); +LINK_NATIVES(URtx); IMPLEMENT_CLASS(URtxLight); FNativeEntry URtxLight::StaticNativeMap[] = { diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 2ebca47e..b884ccad 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -103,7 +103,7 @@ UBOOL URtxRenderDevice::Init() GetDefault()->bVisor = 0; GetDefault()->VisorModeDefault = 1; - Rtx = new(this) URtxInterface; + Rtx = new(this) URtx; return Super::Init(); } diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index ff6609fc..85de2f8f 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -2,7 +2,7 @@ #include "../../D3DDrv/Inc/D3DDrv.h" -class URtxInterface; +class URtx; class FAnchorTriangleVertexStream : public FVertexStream{ public: @@ -57,7 +57,7 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ virtual void Unlock(FRenderInterface* RI); virtual void Present(UViewport* Viewport); - URtxInterface* GetRtxInterface(){ return Rtx; } + URtx* GetRtxInterface(){ return Rtx; } // FRenderInterface @@ -105,7 +105,7 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ ULevel* CurrentLevel; FAnchorTriangleVertexStream AnchorTriangleStream; FRenderInterface* D3D; - URtxInterface* Rtx; + URtx* Rtx; UBOOL DepthCleared; void ClearMaterialFlags(); From ab8c6a51b9cc6488535023ae77d4c4b3e206dae7 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 30 Sep 2024 17:32:46 +0200 Subject: [PATCH 27/48] No fatal error when remix api fails to initialize --- RtxDrv/Src/Rtx.cpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index c49ed36a..fb7414dd 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -1,11 +1,12 @@ #include "RtxDrvPrivate.h" #include "RtxRenderDevice.h" -static remixapi_Interface GRemixInterface; +static bool GRemixApiInitialized = false; +static remixapi_Interface GRemixApi; void URtx::Init() { - if(!GRemixInterface.Startup) + if(!GRemixApiInitialized) { debugf("Initializing remix bridge API"); @@ -14,9 +15,11 @@ void URtx::Init() HMODULE DllHandle; MultiByteToWideChar(CP_ACP, 0, *DllPath, -1, DllPathBuffer, ARRAY_COUNT(DllPathBuffer)); - remixapi_ErrorCode Error = remixapi_lib_loadRemixDllAndInitialize(DllPathBuffer, &GRemixInterface, &DllHandle) ; - if(Error != REMIXAPI_ERROR_CODE_SUCCESS) - appErrorf("Failed to initialize remix API: %i", Error); + remixapi_ErrorCode Error = remixapi_lib_loadRemixDllAndInitialize(DllPathBuffer, &GRemixApi, &DllHandle) ; + GRemixApiInitialized = Error == REMIXAPI_ERROR_CODE_SUCCESS; + + if(!GRemixApiInitialized) + debugf(NAME_Error, "Failed to initialize remix API: %i", Error); } Lights.SetNoShrink(true); @@ -25,7 +28,8 @@ void URtx::Init() void URtx::Exit() { - appMemzero(&GRemixInterface, sizeof(GRemixInterface)); + GRemixApiInitialized = false; + appMemzero(&GRemixApi, sizeof(GRemixApi)); } URtxLight* URtx::CreateLight(bool ForceDefaultConstructed) @@ -89,7 +93,7 @@ void URtx::RenderLights() Light->Update(); if(Light->Handle) - GRemixInterface.DrawLightInstance(Light->Handle); + GRemixApi.DrawLightInstance(Light->Handle); } } } @@ -152,6 +156,9 @@ static void InitShaping(remixapi_LightInfoLightShaping& Dest, const FRtxLightSha void URtxLight::Update() { + if(!GRemixApiInitialized) + return; + DestroyHandle(); remixapi_LightInfo LightInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO}; @@ -171,7 +178,7 @@ void URtxLight::Update() InitShaping(SphereInfo.shaping_value, Shaping); LightInfo.pNext = &SphereInfo; - GRemixInterface.CreateLight(&LightInfo, &Handle); + GRemixApi.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Rect: @@ -188,7 +195,7 @@ void URtxLight::Update() InitShaping(RectInfo.shaping_value, Shaping); LightInfo.pNext = &RectInfo; - GRemixInterface.CreateLight(&LightInfo, &Handle); + GRemixApi.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Disk: @@ -205,7 +212,7 @@ void URtxLight::Update() InitShaping(DiskInfo.shaping_value, Shaping); LightInfo.pNext = &DiskInfo; - GRemixInterface.CreateLight(&LightInfo, &Handle); + GRemixApi.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Cylinder: @@ -216,7 +223,7 @@ void URtxLight::Update() CylinderInfo.radius = Cylinder.Radius; CylinderInfo.axisLength = Cylinder.Length; LightInfo.pNext = &CylinderInfo; - GRemixInterface.CreateLight(&LightInfo, &Handle); + GRemixApi.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Distant: @@ -225,7 +232,7 @@ void URtxLight::Update() InitFloat3D(DistantInfo.direction, Distant.Direction.GetNormalized()); DistantInfo.angularDiameterDegrees = Distant.AngularDiameterDegrees; LightInfo.pNext = &DistantInfo; - GRemixInterface.CreateLight(&LightInfo, &Handle); + GRemixApi.CreateLight(&LightInfo, &Handle); break; } } @@ -233,11 +240,9 @@ void URtxLight::Update() void URtxLight::DestroyHandle() { - if(Handle) + if(GRemixApiInitialized && Handle) { - if(GRemixInterface.DestroyLight) - GRemixInterface.DestroyLight(Handle); - + GRemixApi.DestroyLight(Handle); Handle = NULL; } } From 54f074f1af63d18434b1fd306e31f50481396410 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Wed, 2 Oct 2024 21:00:06 +0200 Subject: [PATCH 28/48] Add missing HardwareShaderWrapper classes --- Engine/Inc/EngineClasses.h | 119 +++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/Engine/Inc/EngineClasses.h b/Engine/Inc/EngineClasses.h index 76da9d69..7ad08c3a 100644 --- a/Engine/Inc/EngineClasses.h +++ b/Engine/Inc/EngineClasses.h @@ -5972,6 +5972,105 @@ class ENGINE_API UHardwareShaderWrapper : public URenderedMaterial{ } }; +/* + * HsBumpDiffBlend + */ + +class ENGINE_API UHsBumpDiffBlend : public UHardwareShaderWrapper{ +public: + class UTexture* DiffuseTexture; + class UTexture* BlendTexture; + class UTexture* NormalMap; + FLOAT DiffUVScale; + FLOAT BlendUVScale; + FLOAT BumpUVScale; + + DECLARE_CLASS(UHsBumpDiffBlend,UHardwareShaderWrapper,0,Engine) + // Make sure to implement this function in UnHardwareShaderWrapper.cpp + virtual INT SetupShaderWrapper(class FRenderInterface* RI); +}; + +/* + * HsBumpDiffBlendMask + */ + +class ENGINE_API UHsBumpDiffBlendMask : public UHardwareShaderWrapper{ +public: + class UTexture* DiffuseTexture; + class UTexture* BlendTexture; + class UTexture* NormalMap; + FLOAT DiffUVScale; + FLOAT BlendUVScale; + FLOAT BumpUVScale; + BYTE VertexToTextureBlend; + + DECLARE_CLASS(UHsBumpDiffBlendMask,UHardwareShaderWrapper,0,Engine) + // Make sure to implement this function in UnHardwareShaderWrapper.cpp + virtual INT SetupShaderWrapper(class FRenderInterface* RI); +}; + +/* + * HsBumpDiffBlendMaskIllum + */ + +class ENGINE_API UHsBumpDiffBlendMaskIllum : public UHardwareShaderWrapper{ +public: + class UTexture* DiffuseTexture; + class UTexture* BlendTexture; + class UTexture* NormalMap; + FLOAT DiffUVScale; + FLOAT BlendUVScale; + FLOAT BumpUVScale; + BYTE VertexToTextureBlend; + + DECLARE_CLASS(UHsBumpDiffBlendMaskIllum,UHardwareShaderWrapper,0,Engine) + // Make sure to implement this function in UnHardwareShaderWrapper.cpp + virtual INT SetupShaderWrapper(class FRenderInterface* RI); +}; + +/* + * HsBumpDiffSpec + */ + +class ENGINE_API UHsBumpDiffSpec : public UHardwareShaderWrapper{ +public: + class UTexture* DiffuseTexture; + class UTexture* NormalMap; + FLOAT DiffUVScale; + FLOAT BumpUVScale; + BYTE Specularity; + FColor SpecularTint; + + DECLARE_CLASS(UHsBumpDiffSpec,UHardwareShaderWrapper,0,Engine) + // Make sure to implement this function in UnHardwareShaderWrapper.cpp + virtual INT SetupShaderWrapper(class FRenderInterface* RI); +}; + +/* + * HsFalloff + */ + +class ENGINE_API UHsFalloff : public UHardwareShaderWrapper{ +public: + class UTexture* DiffuseTexture; + class UTexture* FalloffGradient; + FLOAT UPanRate; + FLOAT VPanRate; + FLOAT UOscilationRate; + FLOAT VOscilationRate; + FLOAT GradientBlendMode; + FColor DiffuseTint; + FColor GradientTint; + BYTE SrcBlend; + BYTE DestBlend; + BITFIELD ZTest:1; + BITFIELD ZWrite:1; + + DECLARE_CLASS(UHsFalloff,UHardwareShaderWrapper,0,Engine) + // Make sure to implement this function in UnHardwareShaderWrapper.cpp + virtual INT SetupShaderWrapper(class FRenderInterface* RI); +}; + /* * HsHologram */ @@ -5987,6 +6086,26 @@ class ENGINE_API UHsHologram : public UHardwareShaderWrapper{ virtual INT SetupShaderWrapper(class FRenderInterface* RI); }; +/* + * HsWorldDistortion + */ + +class ENGINE_API UHsWorldDistortion : public UHardwareShaderWrapper{ +public: + FColor ColorAdd; + FColor ColorVariation; + float WorldDistortion; + FLOAT WobbleScale; + FLOAT WobbleSpeed; + FLOAT WobbleAmplitute; + BITFIELD VortexEffect:1; + BYTE Alpha; + + DECLARE_CLASS(UHsWorldDistortion,UHardwareShaderWrapper,0,Engine) + // Make sure to implement this function in UnHardwareShaderWrapper.cpp + virtual INT SetupShaderWrapper(class FRenderInterface* RI); +}; + /* * ParticleMaterial */ From c8d46baa5ddfe64e4525acef047ba985f5374341 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Wed, 2 Oct 2024 21:04:52 +0200 Subject: [PATCH 29/48] Replace hardware shader materials with fixed function materials --- Core/Inc/UnClass.h | 6 ++++++ RtxDrv/Classes/Rtx.uc | 6 +++++- RtxDrv/Inc/RtxDrvClasses.h | 2 ++ RtxDrv/Src/RtxRenderDevice.cpp | 32 +++++++++++++++++++++++++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Core/Inc/UnClass.h b/Core/Inc/UnClass.h index 208a0ef9..5b5d1670 100644 --- a/Core/Inc/UnClass.h +++ b/Core/Inc/UnClass.h @@ -240,6 +240,12 @@ class CORE_API UStruct : public UField{ UStruct* GetSuperStruct() const; bool StructCompare(const void* A, const void* B); + template + bool IsChildOf() + { + return IsChildOf(T::StaticClass()); + } + protected: // Cheat Protection BYTE FunctionMD5Digest[16]; // Holds a MD5 digest for this function diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc index f7ffc53e..8c4e014a 100644 --- a/RtxDrv/Classes/Rtx.uc +++ b/RtxDrv/Classes/Rtx.uc @@ -3,8 +3,10 @@ class Rtx extends Object within RtxRenderDevice native transient config(RtxDrv) var(General) config color AnchorTriangleColor; var(General) config bool bDrawAnchorTriangle; var(General) config bool bCaptureMode; +var(General) config bool bReplaceHardwareShaderMaterials; -var(Lighting) bool bEnableLights; +var(Lighting) config bool bEnableD3DLights; +var(Lighting) config bool bEnableLights; var(Lighting) editinline array Lights; var const editconst array DestroyedLights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights @@ -29,5 +31,7 @@ defaultproperties { AnchorTriangleColor=(R=255,G=255,B=0,A=255) bDrawAnchorTriangle=True + bReplaceHardwareShaderMaterials=True + bEnableD3DLights=True bEnableLights=True } diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 40fbb750..695df018 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -23,6 +23,8 @@ class RTXDRV_API URtx : public UObject FColor AnchorTriangleColor; BITFIELD bDrawAnchorTriangle:1 GCC_PACK(4); BITFIELD bCaptureMode:1; + BITFIELD bReplaceHardwareShaderMaterials:1; + BITFIELD bEnableD3DLights:1; BITFIELD bEnableLights:1; TArrayNoInit Lights GCC_PACK(4); TArrayNoInit DestroyedLights; diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index b884ccad..b9502a1d 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -358,7 +358,8 @@ void URtxRenderDevice::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL M void URtxRenderDevice::SetLight(INT LightIndex, FDynamicLight* Light, FLOAT Scale) { - // D3D->SetLight(LightIndex, Light, Scale); + if(Rtx->bEnableD3DLights) + D3D->SetLight(LightIndex, Light, Scale); } void URtxRenderDevice::SetTransform(ETransformType Type, const FMatrix& Matrix) @@ -368,6 +369,35 @@ void URtxRenderDevice::SetTransform(ETransformType Type, const FMatrix& Matrix) void URtxRenderDevice::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) { + UMaterial** ActualMaterial = &Material; + + while(*ActualMaterial && (*ActualMaterial)->IsA()) + ActualMaterial = &((UModifier*)*ActualMaterial)->Material; + + if(*ActualMaterial) + { + if(Rtx->bReplaceHardwareShaderMaterials && (*ActualMaterial)->IsA()) + { + UClass* Class = (*ActualMaterial)->GetClass(); + + if(Class->IsChildOf()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsBumpDiffBlend::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsBumpDiffBlendMask::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsBumpDiffBlendMaskIllum::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsFalloff::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsHologram::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + } + } + + if(!*ActualMaterial) + *ActualMaterial = GetDefault()->DefaultMaterial; + D3D->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); } From fa45e2c47dd6b0ed8ae45a082c7210d4f36ab1e7 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 8 Oct 2024 20:11:11 +0200 Subject: [PATCH 30/48] Fix light shaping not applied --- RtxDrv/Src/Rtx.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index fb7414dd..0cbf6758 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -149,6 +149,7 @@ static void InitFloat3D(remixapi_Float3D& Dest, const FVector& Src) static void InitShaping(remixapi_LightInfoLightShaping& Dest, const FRtxLightShaping& Src) { + InitFloat3D(Dest.direction, Src.Direction); Dest.coneAngleDegrees = Src.ConeAngleDegrees; Dest.coneSoftness = Src.ConeSoftness; Dest.focusExponent = Src.FocusExponent; @@ -190,6 +191,7 @@ void URtxLight::Update() InitFloat3D(RectInfo.yAxis, Rect.YAxis.GetNormalized()); RectInfo.ySize = Rect.YSize; InitFloat3D(RectInfo.direction, Rect.Direction.GetNormalized()); + RectInfo.shaping_hasvalue = bUseShaping; if(RectInfo.shaping_hasvalue) InitShaping(RectInfo.shaping_value, Shaping); @@ -207,6 +209,7 @@ void URtxLight::Update() InitFloat3D(DiskInfo.yAxis, Disk.YAxis.GetNormalized()); DiskInfo.yRadius = Disk.YRadius; InitFloat3D(DiskInfo.direction, Disk.Direction.GetNormalized()); + DiskInfo.shaping_hasvalue = bUseShaping; if(DiskInfo.shaping_hasvalue) InitShaping(DiskInfo.shaping_value, Shaping); From 2c127ab552ca4745c0e1cc39019934148fcb3a49 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 8 Oct 2024 20:14:02 +0200 Subject: [PATCH 31/48] Normalize light direction --- RtxDrv/Src/Rtx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 0cbf6758..1f426909 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -149,7 +149,7 @@ static void InitFloat3D(remixapi_Float3D& Dest, const FVector& Src) static void InitShaping(remixapi_LightInfoLightShaping& Dest, const FRtxLightShaping& Src) { - InitFloat3D(Dest.direction, Src.Direction); + InitFloat3D(Dest.direction, Src.Direction.GetNormalized()); Dest.coneAngleDegrees = Src.ConeAngleDegrees; Dest.coneSoftness = Src.ConeSoftness; Dest.focusExponent = Src.FocusExponent; From 7eebf913f8d00927b4526e0c002f2f44a78fdf59 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 8 Oct 2024 20:16:57 +0200 Subject: [PATCH 32/48] Formatting --- RtxDrv/Src/Rtx.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 1f426909..37a2b09d 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -172,14 +172,13 @@ void URtxLight::Update() { remixapi_LightInfoSphereEXT SphereInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT}; InitFloat3D(SphereInfo.position, Position); - SphereInfo.radius = Sphere.Radius; + SphereInfo.radius = Sphere.Radius; SphereInfo.shaping_hasvalue = bUseShaping; if(SphereInfo.shaping_hasvalue) InitShaping(SphereInfo.shaping_value, Shaping); LightInfo.pNext = &SphereInfo; - GRemixApi.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Rect: @@ -197,7 +196,6 @@ void URtxLight::Update() InitShaping(RectInfo.shaping_value, Shaping); LightInfo.pNext = &RectInfo; - GRemixApi.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Disk: @@ -215,7 +213,6 @@ void URtxLight::Update() InitShaping(DiskInfo.shaping_value, Shaping); LightInfo.pNext = &DiskInfo; - GRemixApi.CreateLight(&LightInfo, &Handle); break; } case RTXLIGHT_Cylinder: @@ -223,10 +220,9 @@ void URtxLight::Update() remixapi_LightInfoCylinderEXT CylinderInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT}; InitFloat3D(CylinderInfo.position, Position); InitFloat3D(CylinderInfo.axis, Cylinder.Axis.GetNormalized()); - CylinderInfo.radius = Cylinder.Radius; + CylinderInfo.radius = Cylinder.Radius; CylinderInfo.axisLength = Cylinder.Length; - LightInfo.pNext = &CylinderInfo; - GRemixApi.CreateLight(&LightInfo, &Handle); + LightInfo.pNext = &CylinderInfo; break; } case RTXLIGHT_Distant: @@ -235,10 +231,11 @@ void URtxLight::Update() InitFloat3D(DistantInfo.direction, Distant.Direction.GetNormalized()); DistantInfo.angularDiameterDegrees = Distant.AngularDiameterDegrees; LightInfo.pNext = &DistantInfo; - GRemixApi.CreateLight(&LightInfo, &Handle); break; } } + + GRemixApi.CreateLight(&LightInfo, &Handle); } void URtxLight::DestroyHandle() From 56bfc15506109a18752f68de6bac4ca56bd3ece5 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Thu, 17 Oct 2024 15:53:10 +0200 Subject: [PATCH 33/48] Add extensible components for rtx features --- RtxDrv/Classes/Rtx.uc | 25 +++-- RtxDrv/Classes/RtxComponent.uc | 16 +++ RtxDrv/Classes/RtxFlashlight.uc | 123 +++++++++++++++++++++++ RtxDrv/Classes/RtxFlashlightComponent.uc | 93 +++++++++++++++++ RtxDrv/Inc/RtxDrvClasses.h | 20 +++- RtxDrv/Src/Rtx.cpp | 22 ++-- RtxDrv/Src/RtxDrvClasses.cpp | 3 +- RtxDrv/Src/RtxRenderDevice.cpp | 12 ++- RtxDrv/Src/RtxRenderDevice.h | 2 +- 9 files changed, 293 insertions(+), 23 deletions(-) create mode 100644 RtxDrv/Classes/RtxComponent.uc create mode 100644 RtxDrv/Classes/RtxFlashlight.uc create mode 100644 RtxDrv/Classes/RtxFlashlightComponent.uc diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc index 8c4e014a..c0c86bd4 100644 --- a/RtxDrv/Classes/Rtx.uc +++ b/RtxDrv/Classes/Rtx.uc @@ -1,19 +1,21 @@ -class Rtx extends Object within RtxRenderDevice native transient config(RtxDrv) hidecategories(Object, None); +class Rtx extends Object native transient config(Rtx) hidecategories(Object, None); -var(General) config color AnchorTriangleColor; -var(General) config bool bDrawAnchorTriangle; -var(General) config bool bCaptureMode; -var(General) config bool bReplaceHardwareShaderMaterials; +var(Components) config array > ComponentClasses; +var(Components) native editconst editinline array Components; // Must be native so the property is excluded from gc. The array is cleared in native code when the level changes. -var(Lighting) config bool bEnableD3DLights; -var(Lighting) config bool bEnableLights; -var(Lighting) editinline array Lights; +var(General) config color AnchorTriangleColor; +var(General) config bool bDrawAnchorTriangle; +var(General) config bool bCaptureMode; +var(General) config bool bReplaceHardwareShaderMaterials; + +var(Lighting) config bool bEnableD3DLights; +var(Lighting) config bool bEnableLights; +var(Lighting) const editinline array Lights; var const editconst array DestroyedLights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights native final function RtxLight CreateLight(); native final function DestroyLight(RtxLight Light); -native final function DestroyAllLights(); native static final function Rtx GetInstance(); @@ -23,7 +25,7 @@ cpptext void Exit(); URtxLight* CreateLight(bool ForceDefaultConstructed = false); void DestroyLight(URtxLight* Light); - void DestroyAllLights(); + void LevelChanged(class ULevel* Level); void RenderLights(); } @@ -32,6 +34,7 @@ defaultproperties AnchorTriangleColor=(R=255,G=255,B=0,A=255) bDrawAnchorTriangle=True bReplaceHardwareShaderMaterials=True - bEnableD3DLights=True + bEnableD3DLights=False bEnableLights=True + ComponentClasses(0)=class'RtxFlashlightComponent' } diff --git a/RtxDrv/Classes/RtxComponent.uc b/RtxDrv/Classes/RtxComponent.uc new file mode 100644 index 00000000..68c67bef --- /dev/null +++ b/RtxDrv/Classes/RtxComponent.uc @@ -0,0 +1,16 @@ +class RtxComponent extends Actor native transient config(Rtx) hidecategories(Advanced, AI, Collision, CollisionAdvanced, Display, DisplayAdvanced, Events, Karma, LightColor, Lighting, marker, Movement, MovementAdvanced, Object, Sound); + +var Rtx Rtx; + +event OnSaveConfig(); + +function PostBeginPlay() +{ + Rtx = class'Rtx'.static.GetInstance(); +} + +defaultproperties +{ + bHidden=True + DrawType=DT_None +} diff --git a/RtxDrv/Classes/RtxFlashlight.uc b/RtxDrv/Classes/RtxFlashlight.uc new file mode 100644 index 00000000..cbbedd13 --- /dev/null +++ b/RtxDrv/Classes/RtxFlashlight.uc @@ -0,0 +1,123 @@ +class RtxFlashlight extends Object config(Rtx) hidecategories(Object); + +var() bool bIsOn; + +struct FlashlightCone{ + var() config float Angle; + var() config float Radius; + var() config float Radiance; + var() config float Softness; + var() config color Color; +}; + +var() config Vector FirstPersonOffset; +var() config float FocusDistance; +var() config FlashlightCone OuterCone; +var() config FlashlightCone MainCone; +var() config FlashlightCone InnerCone; + +var RtxLight OuterLight; +var RtxLight MainLight; +var RtxLight InnerLight; + +function CalcLightPositionAndDirection(Pawn Pawn, out vector Position, out vector Direction) +{ + local vector ViewPosition; + local rotator ViewRotation; + local vector X,Y,Z; + + ViewPosition = Pawn.Location; + ViewPosition.Z += Pawn.EyeHeight; + + if(Pawn.IsLocallyControlled()) + { + ViewRotation = Pawn.Controller.Rotation; + Position = ViewPosition + QuatRotateVector(QuatFromRotator(ViewRotation), FirstPersonOffset); + } + else + { + ViewRotation = Pawn.GetBoneRotation('LightAttach'); + GetAxes(ViewRotation, X, Y, Z); + Position = Pawn.GetBoneLocation('LightAttach') + Y * 5; // FIXME: Don't hardcode this + } + + if(FocusDistance >= 1.0) + Direction = (ViewPosition + vector(ViewRotation) * FocusDistance) - Position; + else + Direction = vector(ViewRotation); +} + +function UpdateLight(Pawn Pawn, RtxLight Light, FlashlightCone Cone) +{ + Light.Color = Cone.Color; + Light.Radiance = Cone.Radiance; + Light.Sphere.Radius = Cone.Radius; + Light.Shaping.ConeAngleDegrees = Cone.Angle; + Light.Shaping.ConeSoftness = Cone.Softness; + + CalcLightPositionAndDirection(Pawn, Light.Position, Light.Shaping.Direction); + Light.Update(); +} + +function Init() +{ + local Rtx Rtx; + + Rtx = class'Rtx'.static.GetInstance(); + + OuterLight = Rtx.CreateLight(); + OuterLight.Type = RTXLIGHT_Sphere; + OuterLight.bEnabled = false; + OuterLight.bUseShaping = true; + OuterLight.Update(); + + MainLight = Rtx.CreateLight(); + MainLight.Type = RTXLIGHT_Sphere; + OuterLight.bEnabled = false; + MainLight.bUseShaping = true; + MainLight.Update(); + + InnerLight = Rtx.CreateLight(); + InnerLight.Type = RTXLIGHT_Sphere; + OuterLight.bEnabled = false; + InnerLight.bUseShaping = true; + InnerLight.Update(); +} + +function Exit() +{ + local Rtx Rtx; + + Rtx = class'Rtx'.static.GetInstance(); + + Rtx.DestroyLight(OuterLight); + Rtx.DestroyLight(MainLight); + Rtx.DestroyLight(InnerLight); +} + +function Update(Pawn Pawn, bool bOn) +{ + if(bOn != bIsOn) + { + OuterLight.bEnabled = bOn; + MainLight.bEnabled = bOn; + InnerLight.bEnabled = bOn; + bIsOn = bOn; + } + + if(bIsOn && Pawn != None) + { + UpdateLight(Pawn, OuterLight, OuterCone); + UpdateLight(Pawn, MainLight, MainCone); + UpdateLight(Pawn, InnerLight, InnerCone); + } +} + +defaultproperties +{ + FirstPersonOffset=(X=0,Y=13,Z=4) + FocusDistance=256 + OuterCone=(Angle=30,Color=(R=176,G=249,B=255,A=255),Radiance=10000,Radius=2,Softness=0.02) + MainCone=(Angle=25,Color=(R=253,G=255,B=217,A=255),Radiance=15000,Radius=3,Softness=0.05) + InnerCone=(Angle=5,Color=(R=254,G=248,B=205,A=255),Radiance=20000,Radius=4,Softness=0) +} diff --git a/RtxDrv/Classes/RtxFlashlightComponent.uc b/RtxDrv/Classes/RtxFlashlightComponent.uc new file mode 100644 index 00000000..4c648ffa --- /dev/null +++ b/RtxDrv/Classes/RtxFlashlightComponent.uc @@ -0,0 +1,93 @@ +class RtxFlashlightComponent extends RtxComponent; + +struct SquadMemberFlashlight{ + var Pawn Pawn; + var RtxFlashlight Flashlight; +}; + +var array SquadFlashlights; +var() editinline RtxFlashlight PlayerFlashlight; + +function OnSaveConfig() +{ + PlayerFlashlight.SaveConfig(); +} + +function SetupSquadLights(Squad Squad) +{ + local int i, j; + + for(i = 1; i < Squad.SquadMembers.Length; ++i) + { + for(j = 0; j < SquadFlashlights.Length; ++j) + { + if(SquadFlashlights[j].Pawn == Squad.SquadMembers[i].Pawn) + goto end; + + if(SquadFlashlights[j].Pawn == None) + { + SquadFlashlights.Remove(j, 1); + goto end; + } + } + + j = SquadFlashlights.Length; + SquadFlashlights.Length = j + 1; + SquadFlashlights[j].Pawn = Squad.SquadMembers[i].Pawn; + SquadFlashlights[j].Flashlight = new class'RtxFlashlight'; + SquadFlashlights[j].Flashlight.Init(); +end: + } +} + +function PostBeginPlay() +{ + Super.PostBeginPlay(); + + if(PlayerFlashlight == None) + { + PlayerFlashlight = new class'RtxFlashlight'; + PlayerFlashlight.Init(); + } +} + +function Destroyed() +{ + local int i; + + for(i = 0; i < SquadFlashlights.Length; ++i) + SquadFlashlights[i].Flashlight.Exit(); + + SquadFlashlights.Length = 0; + PlayerFlashlight.Exit(); + Super.Destroyed(); +} + +function Tick(float DeltaTime) +{ + local PlayerController PC; + local Pawn Pawn; + local int i; + + PC = Level.GetLocalPlayerController(); + + if(PC == None || PC.Pawn == None) + return; + + Pawn = PC.Pawn; + + if(Pawn.Squad != None) + SetupSquadLights(PC.Pawn.Squad); + + PlayerFlashlight.Update(Pawn, Pawn.Flashlight.bIsOn); + + // Disable light spawned in Pawn::SetFlashlight + if(PC.PlayerSpotlight != None) + { + PC.PlayerSpotlight.LightType = LT_None; + PC.PlayerSpotlight.bLightPriorityOverride = false; + } + + for(i = 0; i < SquadFlashlights.Length; ++i) + SquadFlashlights[i].Flashlight.Update(SquadFlashlights[i].Pawn, PC.Pawn.Flashlight.bIsOn); +} diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 695df018..54b6cf75 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -17,9 +17,25 @@ +class RTXDRV_API ARtxComponent : public AActor +{ +public: + class URtx* Rtx; + void OnSaveConfig() + { + DECLARE_NAME(OnSaveConfig); + ProcessEvent(NOnSaveConfig, NULL); + } + DECLARE_CLASS(ARtxComponent,AActor,0|CLASS_Transient,RtxDrv) + NO_DEFAULT_CONSTRUCTOR(ARtxComponent) +}; + + class RTXDRV_API URtx : public UObject { public: + TArrayNoInit ComponentClasses; + TArrayNoInit Components; FColor AnchorTriangleColor; BITFIELD bDrawAnchorTriangle:1 GCC_PACK(4); BITFIELD bCaptureMode:1; @@ -30,14 +46,13 @@ class RTXDRV_API URtx : public UObject TArrayNoInit DestroyedLights; void execCreateLight(FFrame& Stack, void* Result); void execDestroyLight(FFrame& Stack, void* Result); - void execDestroyAllLights(FFrame& Stack, void* Result); void execGetInstance(FFrame& Stack, void* Result); DECLARE_CLASS(URtx,UObject,0|CLASS_Transient|CLASS_Config,RtxDrv) void Init(); void Exit(); URtxLight* CreateLight(bool ForceDefaultConstructed = false); void DestroyLight(URtxLight* Light); - void DestroyAllLights(); + void LevelChanged(class ULevel* Level); void RenderLights(); DECLARE_NATIVES(URtx) }; @@ -132,6 +147,7 @@ class RTXDRV_API URtxLight : public UObject #if __STATIC_LINK #define AUTO_INITIALIZE_REGISTRANTS_RTXDRV \ + ARtxComponent::StaticClass(); \ USolidColorMaterial::StaticClass(); \ URtx::StaticClass(); \ URtxLight::StaticClass(); \ diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 37a2b09d..4a86a25b 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -53,10 +53,24 @@ void URtx::DestroyLight(URtxLight* Light) Light->bShouldBeDestroyed = 1; } -void URtx::DestroyAllLights() +void URtx::LevelChanged(ULevel* Level) { DestroyedLights += Lights; Lights.Empty(); + Components.Empty(); + + for(INT i = 0; i < ComponentClasses.Num(); ++i) + { + UClass* ComponentClass = ComponentClasses[i]; + if(ComponentClass) + { + ARtxComponent* Actor = static_cast(Level->SpawnActor(ComponentClass)); + if(Actor) + Components.AddItem(Actor); + else + debugf("Failed to spawn Rtx component of class %s", ComponentClass->GetName()); + } + } } void URtx::RenderLights() @@ -111,12 +125,6 @@ void URtx::execDestroyLight(FFrame& Stack, void* Result) DestroyLight(Light); } -void URtx::execDestroyAllLights(FFrame& Stack, void* Result) -{ - P_FINISH; - DestroyAllLights(); -} - void URtx::execGetInstance(FFrame& Stack, void* Result) { P_FINISH; diff --git a/RtxDrv/Src/RtxDrvClasses.cpp b/RtxDrv/Src/RtxDrvClasses.cpp index 5d4d9450..05dcb73c 100644 --- a/RtxDrv/Src/RtxDrvClasses.cpp +++ b/RtxDrv/Src/RtxDrvClasses.cpp @@ -10,11 +10,12 @@ IMPLEMENT_PACKAGE(RtxDrv) +IMPLEMENT_CLASS(ARtxComponent); + IMPLEMENT_CLASS(URtx); FNativeEntry URtx::StaticNativeMap[] = { MAP_NATIVE(CreateLight,0) MAP_NATIVE(DestroyLight,0) - MAP_NATIVE(DestroyAllLights,0) MAP_NATIVE(GetInstance,0) {NULL,NULL} }; diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index b9502a1d..5bddd78b 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -67,6 +67,16 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) else if(ParseCommand(&Cmd, "SAVECONFIG")) { Rtx->SaveConfig(); + + for(INT i = 0; i < Rtx->Components.Num(); ++i) + { + if(Rtx->Components[i]) + { + Rtx->Components[i]->SaveConfig(); + Rtx->Components[i]->OnSaveConfig(); + } + } + return 1; } } @@ -150,7 +160,7 @@ FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT { CurrentLevel = Level; AnchorTriangleStream.Update(CurrentLevel ? (appStrihash(CurrentLevel->GetPathName()) / (FLOAT)MAXDWORD) : 0.0f); - Rtx->DestroyAllLights(); + Rtx->LevelChanged(CurrentLevel); } LockedViewport = Viewport; diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 85de2f8f..57a809e6 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -43,7 +43,7 @@ class FAnchorTriangleVertexStream : public FVertexStream{ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ DECLARE_CLASS(URtxRenderDevice,UD3DRenderDevice,CLASS_Config,RtxDrv) - static const TCHAR* StaticConfigName(){ return "RtxDrv"; } + static const TCHAR* StaticConfigName(){ return "Rtx"; } public: void StaticConstructor(); From 518eb6c2fcaf06c820365c7a9333e4d7b46ffa56 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Thu, 17 Oct 2024 15:53:33 +0200 Subject: [PATCH 34/48] Ignore certain materials --- RtxDrv/Src/RtxRenderDevice.cpp | 62 +++++++++++++++++++++------------- RtxDrv/Src/RtxRenderDevice.h | 7 ++++ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 5bddd78b..ca22a1ab 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -360,6 +360,11 @@ void URtxRenderDevice::Clear(UBOOL UseColor, FColor Color, UBOOL UseDepth, FLOAT void URtxRenderDevice::EnableLighting(UBOOL UseDynamic, UBOOL UseStatic, UBOOL Modulate2X, FBaseTexture* Lightmap, UBOOL LightingOnly, const FSphere& LitSphere, int IntValue) { + if(UseStatic && Lightmap) + IgnoreDrawCall |= IgnoreDrawCall_Lightmap; + else + IgnoreDrawCall &= ~IgnoreDrawCall_Lightmap; + UseDynamic = 0; Lightmap = NULL; Modulate2X = 0; @@ -379,39 +384,48 @@ void URtxRenderDevice::SetTransform(ETransformType Type, const FMatrix& Matrix) void URtxRenderDevice::SetMaterial(UMaterial* Material, FString* ErrorString, UMaterial** ErrorMaterial, INT* NumPasses) { - UMaterial** ActualMaterial = &Material; + if(Material) + { + if(Material->IsA()) + IgnoreDrawCall |= IgnoreDrawCall_Material; + else + IgnoreDrawCall &= ~IgnoreDrawCall_Material; - while(*ActualMaterial && (*ActualMaterial)->IsA()) - ActualMaterial = &((UModifier*)*ActualMaterial)->Material; + UMaterial** ActualMaterial = &Material; - if(*ActualMaterial) - { - if(Rtx->bReplaceHardwareShaderMaterials && (*ActualMaterial)->IsA()) + while(*ActualMaterial && (*ActualMaterial)->IsA()) + ActualMaterial = &((UModifier*)*ActualMaterial)->Material; + + if(*ActualMaterial) { - UClass* Class = (*ActualMaterial)->GetClass(); - - if(Class->IsChildOf()) - *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; - else if(Class == UHsBumpDiffBlend::StaticClass()) - *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; - else if(Class == UHsBumpDiffBlendMask::StaticClass()) - *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; - else if(Class == UHsBumpDiffBlendMaskIllum::StaticClass()) - *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; - else if(Class == UHsFalloff::StaticClass()) - *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; - else if(Class == UHsHologram::StaticClass()) - *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + if(Rtx->bReplaceHardwareShaderMaterials && (*ActualMaterial)->IsA()) + { + UClass* Class = (*ActualMaterial)->GetClass(); + + if(Class->IsChildOf()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsBumpDiffBlend::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsBumpDiffBlendMask::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsBumpDiffBlendMaskIllum::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsFalloff::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + else if(Class == UHsHologram::StaticClass()) + *ActualMaterial = static_cast(*ActualMaterial)->DiffuseTexture; + } } - } - if(!*ActualMaterial) - *ActualMaterial = GetDefault()->DefaultMaterial; + if(!*ActualMaterial) + *ActualMaterial = GetDefault()->DefaultMaterial; + } D3D->SetMaterial(Material, ErrorString, ErrorMaterial, NumPasses); } void URtxRenderDevice::DrawPrimitive(EPrimitiveType PrimitiveType, INT FirstIndex, INT NumPrimitives, INT MinIndex, INT MaxIndex) { - D3D->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); + if(!IgnoreDrawCall) + D3D->DrawPrimitive(PrimitiveType, FirstIndex, NumPrimitives, MinIndex, MaxIndex); } diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 57a809e6..355536b4 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -108,6 +108,13 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ URtx* Rtx; UBOOL DepthCleared; + enum EIgnoreDrawCallFlags{ + IgnoreDrawCall_Lightmap = 0x1, + IgnoreDrawCall_Material = 0x2, + }; + + BITFIELD IgnoreDrawCall; + void ClearMaterialFlags(); void DrawAnchorTriangle(); }; From e2a7470a162a043078c5129f9deb9d219d460ee9 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Fri, 18 Oct 2024 04:14:15 +0200 Subject: [PATCH 35/48] Fix flashlight still being enabled when loading a new map --- RtxDrv/Classes/RtxFlashlight.uc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RtxDrv/Classes/RtxFlashlight.uc b/RtxDrv/Classes/RtxFlashlight.uc index cbbedd13..92807166 100644 --- a/RtxDrv/Classes/RtxFlashlight.uc +++ b/RtxDrv/Classes/RtxFlashlight.uc @@ -1,6 +1,6 @@ class RtxFlashlight extends Object config(Rtx) hidecategories(Object); -var() bool bIsOn; +var() bool bIsOn; struct FlashlightCone{ var() config float Angle; @@ -73,13 +73,13 @@ function Init() MainLight = Rtx.CreateLight(); MainLight.Type = RTXLIGHT_Sphere; - OuterLight.bEnabled = false; + MainLight.bEnabled = false; MainLight.bUseShaping = true; MainLight.Update(); InnerLight = Rtx.CreateLight(); InnerLight.Type = RTXLIGHT_Sphere; - OuterLight.bEnabled = false; + InnerLight.bEnabled = false; InnerLight.bUseShaping = true; InnerLight.Update(); } From 0b5f7abcf80c96b107f9222f6fbf3714f8ff5197 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sat, 19 Oct 2024 14:35:35 +0200 Subject: [PATCH 36/48] Add functions to access material flags --- RtxDrv/Classes/RtxFlashlight.uc | 2 +- RtxDrv/Src/Rtx.cpp | 2 +- RtxDrv/Src/RtxRenderDevice.cpp | 12 +++++++++++- RtxDrv/Src/RtxRenderDevice.h | 1 - 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/RtxDrv/Classes/RtxFlashlight.uc b/RtxDrv/Classes/RtxFlashlight.uc index 92807166..e05c3770 100644 --- a/RtxDrv/Classes/RtxFlashlight.uc +++ b/RtxDrv/Classes/RtxFlashlight.uc @@ -1,6 +1,6 @@ class RtxFlashlight extends Object config(Rtx) hidecategories(Object); -var() bool bIsOn; +var bool bIsOn; struct FlashlightCone{ var() config float Angle; diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 4a86a25b..4a579b39 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -57,7 +57,7 @@ void URtx::LevelChanged(ULevel* Level) { DestroyedLights += Lights; Lights.Empty(); - Components.Empty(); + Components.Empty(); // Component actors aren't valid anymore now that the level has changed so just clear the old ones for(INT i = 0; i < ComponentClasses.Num(); ++i) { diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index ca22a1ab..cd6608d3 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -233,7 +233,17 @@ void URtxRenderDevice::Present(UViewport* Viewport) Super::Present(Viewport); } -void URtxRenderDevice::ClearMaterialFlags() +static INT GetMaterialFlags(UMaterial* Material) +{ + return reinterpret_cast(Material)[24] >> 2; +} + +static INT SetMaterialFlags(UMaterial* Material, INT Flags) +{ + reinterpret_cast(Material)[24] = (Flags << 2) | (reinterpret_cast(Material)[24] & 0x3); +} + +void ClearMaterialFlags() { foreachobj(UMaterial, Material) reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 355536b4..1269f46a 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -115,6 +115,5 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ BITFIELD IgnoreDrawCall; - void ClearMaterialFlags(); void DrawAnchorTriangle(); }; From 74f75c66a7b7c6557a3d5dadfb1d816d55d52314 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Fri, 25 Oct 2024 22:28:45 +0200 Subject: [PATCH 37/48] Use INT for 4-byte padding --- D3DDrv/Inc/D3DDrv.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/D3DDrv/Inc/D3DDrv.h b/D3DDrv/Inc/D3DDrv.h index c5558373..7ae7ca01 100644 --- a/D3DDrv/Inc/D3DDrv.h +++ b/D3DDrv/Inc/D3DDrv.h @@ -21,7 +21,7 @@ class D3DDRV_API UD3DRenderDevice : public URenderDevice{ char Padding1[16412]; // Padding UBOOL UsePrecaching; UBOOL UseTrilinear; - char Padding2; // Padding + INT Padding2; // Padding UBOOL UseVSync; UBOOL UseHardwareTL; UBOOL UseHardwareVS; @@ -36,9 +36,9 @@ class D3DDRV_API UD3DRenderDevice : public URenderDevice{ UBOOL DecompressTextures; UBOOL AvoidHitches; UBOOL OverrideDesktopRefreshRate; - char Padding5[4]; // Padding + INT Padding5; // Padding INT AdapterNumber; - char Padding6[4]; // Padding + INT Padding6; // Padding INT MaxPixelShaderVersion; INT LevelOfAnisotropy; FLOAT DetailTexMipBias; From b1d3b55d17e58bddaa8a10d2872754b1f6a2154d Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 16 Dec 2024 22:09:46 +0100 Subject: [PATCH 38/48] Disable targeted vision mode shaders for night vision --- RtxDrv/Classes/RtxFlashlightComponent.uc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/RtxDrv/Classes/RtxFlashlightComponent.uc b/RtxDrv/Classes/RtxFlashlightComponent.uc index 4c648ffa..9793a77f 100644 --- a/RtxDrv/Classes/RtxFlashlightComponent.uc +++ b/RtxDrv/Classes/RtxFlashlightComponent.uc @@ -42,6 +42,13 @@ end: function PostBeginPlay() { + local VisionModeSniper VisionMode; + + VisionMode = VisionModeSniper'FrameFx.VisionModes.VisionNight'; + VisionMode.VisionShader = HardwareShader'FrameFX.VisionShaders.VisionShaderNormal'; + VisionMode.TargetedOrganicShader = None; + VisionMode.TargetedMechanicalShader = None; + Super.PostBeginPlay(); if(PlayerFlashlight == None) From 20f5e6025b5869096de55d251c4792ece48cd088 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 16 Dec 2024 23:57:58 +0100 Subject: [PATCH 39/48] Don't create lights for grenade projectiles --- RtxDrv/Src/RtxRenderDevice.cpp | 36 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index cd6608d3..e0d622f6 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -16,6 +16,22 @@ static ULevel* GetLevel() return NULL; } +// static INT GetMaterialFlags(UMaterial* Material) +// { +// return reinterpret_cast(Material)[24] >> 2; +// } + +// static INT SetMaterialFlags(UMaterial* Material, INT Flags) +// { +// reinterpret_cast(Material)[24] = (Flags << 2) | (reinterpret_cast(Material)[24] & 0x3); +// } + +void ClearMaterialFlags() +{ + foreachobj(UMaterial, Material) + reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); +} + void URtxRenderDevice::Serialize(FArchive& Ar) { Super::Serialize(Ar); @@ -186,6 +202,10 @@ void URtxRenderDevice::Unlock(FRenderInterface* RI) foreach(AllActors, AProjectile, Proj, static_cast(GEngine)->GLevel) { + DECLARE_NAME(GrenadeProj); + if(Proj->IsA(NGrenadeProj)) + continue; + FProjectileLight* ProjLight = ProjLights.Find(*Proj); if(!ProjLight) @@ -233,22 +253,6 @@ void URtxRenderDevice::Present(UViewport* Viewport) Super::Present(Viewport); } -static INT GetMaterialFlags(UMaterial* Material) -{ - return reinterpret_cast(Material)[24] >> 2; -} - -static INT SetMaterialFlags(UMaterial* Material, INT Flags) -{ - reinterpret_cast(Material)[24] = (Flags << 2) | (reinterpret_cast(Material)[24] & 0x3); -} - -void ClearMaterialFlags() -{ - foreachobj(UMaterial, Material) - reinterpret_cast(*Material)[24] = (reinterpret_cast(*Material)[24] & 0x3); -} - /* * Draw anchor triangle at world center to parent assets to in remix */ From c05c292a93cdface67ddeac9ec096343bb64a160 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sun, 16 Mar 2025 20:07:40 +0100 Subject: [PATCH 40/48] Only do light position and direction calculation once instead of per light cone --- RtxDrv/Classes/RtxFlashlight.uc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/RtxDrv/Classes/RtxFlashlight.uc b/RtxDrv/Classes/RtxFlashlight.uc index e05c3770..f422d364 100644 --- a/RtxDrv/Classes/RtxFlashlight.uc +++ b/RtxDrv/Classes/RtxFlashlight.uc @@ -47,15 +47,16 @@ function CalcLightPositionAndDirection(Pawn Pawn, out vector Position, out vecto Direction = vector(ViewRotation); } -function UpdateLight(Pawn Pawn, RtxLight Light, FlashlightCone Cone) +function UpdateLight(Pawn Pawn, RtxLight Light, vector Position, vector Direction, FlashlightCone Cone) { + Light.Position = Position; + Light.Shaping.Direction = Direction; Light.Color = Cone.Color; Light.Radiance = Cone.Radiance; Light.Sphere.Radius = Cone.Radius; Light.Shaping.ConeAngleDegrees = Cone.Angle; Light.Shaping.ConeSoftness = Cone.Softness; - CalcLightPositionAndDirection(Pawn, Light.Position, Light.Shaping.Direction); Light.Update(); } @@ -97,6 +98,9 @@ function Exit() function Update(Pawn Pawn, bool bOn) { + local vector LightPosition; + local vector LightDirection; + if(bOn != bIsOn) { OuterLight.bEnabled = bOn; @@ -107,9 +111,10 @@ function Update(Pawn Pawn, bool bOn) if(bIsOn && Pawn != None) { - UpdateLight(Pawn, OuterLight, OuterCone); - UpdateLight(Pawn, MainLight, MainCone); - UpdateLight(Pawn, InnerLight, InnerCone); + CalcLightPositionAndDirection(Pawn, LightPosition, LightDirection); + UpdateLight(Pawn, OuterLight, LightPosition, LightDirection, OuterCone); + UpdateLight(Pawn, MainLight, LightPosition, LightDirection, MainCone); + UpdateLight(Pawn, InnerLight, LightPosition, LightDirection, InnerCone); } } From f67f94d03c903c7b2f77a629f9fa047bde666691 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Mon, 19 May 2025 20:38:10 +0200 Subject: [PATCH 41/48] Add Scipt function and console command to set rtx config variables --- RtxDrv/Classes/Rtx.uc | 2 ++ RtxDrv/Inc/RtxDrvClasses.h | 2 ++ RtxDrv/Src/Rtx.cpp | 13 +++++++++++++ RtxDrv/Src/RtxDrvClasses.cpp | 1 + RtxDrv/Src/RtxRenderDevice.cpp | 14 ++++++++++++++ 5 files changed, 32 insertions(+) diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc index c0c86bd4..cdd3973a 100644 --- a/RtxDrv/Classes/Rtx.uc +++ b/RtxDrv/Classes/Rtx.uc @@ -16,6 +16,7 @@ var const editconst array DestroyedLights; // Keep destroyed ligh native final function RtxLight CreateLight(); native final function DestroyLight(RtxLight Light); +native final function SetConfigVariable(string Key, string Value); native static final function Rtx GetInstance(); @@ -23,6 +24,7 @@ cpptext { void Init(); void Exit(); + void SetConfigVariable(const TCHAR* Key, const TCHAR* Value); URtxLight* CreateLight(bool ForceDefaultConstructed = false); void DestroyLight(URtxLight* Light); void LevelChanged(class ULevel* Level); diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 54b6cf75..71c7d01b 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -46,10 +46,12 @@ class RTXDRV_API URtx : public UObject TArrayNoInit DestroyedLights; void execCreateLight(FFrame& Stack, void* Result); void execDestroyLight(FFrame& Stack, void* Result); + void execSetConfigVariable(FFrame& Stack, void* Result); void execGetInstance(FFrame& Stack, void* Result); DECLARE_CLASS(URtx,UObject,0|CLASS_Transient|CLASS_Config,RtxDrv) void Init(); void Exit(); + void SetConfigVariable(const TCHAR* Key, const TCHAR* Value); URtxLight* CreateLight(bool ForceDefaultConstructed = false); void DestroyLight(URtxLight* Light); void LevelChanged(class ULevel* Level); diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 4a579b39..447d9eff 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -32,6 +32,12 @@ void URtx::Exit() appMemzero(&GRemixApi, sizeof(GRemixApi)); } +void URtx::SetConfigVariable(const TCHAR* Key, const TCHAR* Value) +{ + if(GRemixApiInitialized) + GRemixApi.SetConfigVariable(Key, Value); +} + URtxLight* URtx::CreateLight(bool ForceDefaultConstructed) { URtxLight* Light; @@ -135,6 +141,13 @@ void URtx::execGetInstance(FFrame& Stack, void* Result) *static_cast(Result) = RenDev->GetRtxInterface(); } +void URtx::execSetConfigVariable(FFrame& Stack, void* Result) +{ + P_GET_STR(Key); + P_GET_STR(Value); + P_FINISH; + SetConfigVariable(*Key, *Value); +} void URtxLight::execUpdate(FFrame& Stack, void* Result) { diff --git a/RtxDrv/Src/RtxDrvClasses.cpp b/RtxDrv/Src/RtxDrvClasses.cpp index 05dcb73c..78adf58c 100644 --- a/RtxDrv/Src/RtxDrvClasses.cpp +++ b/RtxDrv/Src/RtxDrvClasses.cpp @@ -16,6 +16,7 @@ IMPLEMENT_CLASS(URtx); FNativeEntry URtx::StaticNativeMap[] = { MAP_NATIVE(CreateLight,0) MAP_NATIVE(DestroyLight,0) + MAP_NATIVE(SetConfigVariable,0) MAP_NATIVE(GetInstance,0) {NULL,NULL} }; diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index e0d622f6..e2e17bdc 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -58,6 +58,20 @@ UBOOL URtxRenderDevice::Exec(const TCHAR* Cmd, FOutputDevice& Ar) P->Show(1); return 1; } + else if(ParseCommand(&Cmd, "SET")) + { + FString Key = ParseToken(Cmd, 0); + FString Value = ParseToken(Cmd, 0); + + if(Key.Len() == 0) + Ar.Log("Missing variable name"); + else if(Value.Len() == 0) + Ar.Log("Missing value"); + else + Rtx->SetConfigVariable(*Key, *Value); + + return 1; + } else if(ParseCommand(&Cmd, "CREATELIGHT")) { APlayerController* PC = GEngine->Client->Viewports[0]->Actor; From 38ec5aeb4569d4df8cdbd28ba89eaed6d2778633 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Thu, 22 May 2025 19:22:00 +0200 Subject: [PATCH 42/48] Shutdown remix API in URtx::Exit --- RtxDrv/Src/Rtx.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 447d9eff..190ecb9c 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -2,7 +2,8 @@ #include "RtxRenderDevice.h" static bool GRemixApiInitialized = false; -static remixapi_Interface GRemixApi; +static remixapi_Interface GRemixApi = {0}; +static HMODULE GRemixDllHandle = NULL; void URtx::Init() { @@ -12,10 +13,9 @@ void URtx::Init() wchar_t DllPathBuffer[MAX_PATH]; FString DllPath = FStringTemp(appBaseDir()) * "d3d9.dll"; - HMODULE DllHandle; MultiByteToWideChar(CP_ACP, 0, *DllPath, -1, DllPathBuffer, ARRAY_COUNT(DllPathBuffer)); - remixapi_ErrorCode Error = remixapi_lib_loadRemixDllAndInitialize(DllPathBuffer, &GRemixApi, &DllHandle) ; + remixapi_ErrorCode Error = remixapi_lib_loadRemixDllAndInitialize(DllPathBuffer, &GRemixApi, &GRemixDllHandle) ; GRemixApiInitialized = Error == REMIXAPI_ERROR_CODE_SUCCESS; if(!GRemixApiInitialized) @@ -28,8 +28,12 @@ void URtx::Init() void URtx::Exit() { - GRemixApiInitialized = false; - appMemzero(&GRemixApi, sizeof(GRemixApi)); + if(GRemixApiInitialized) + { + remixapi_lib_shutdownAndUnloadRemixDll(&GRemixApi, GRemixDllHandle); + GRemixApiInitialized = false; + GRemixDllHandle = NULL; + } } void URtx::SetConfigVariable(const TCHAR* Key, const TCHAR* Value) From 4a1eff0eb3e63ff33ef6d9556e4f1cdedf3a4874 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Tue, 17 Jun 2025 02:56:06 +0200 Subject: [PATCH 43/48] Add options to disable frustum culling and sky rendering --- Engine/Inc/UnRender.h | 2 +- RtxDrv/Classes/Rtx.uc | 4 ++++ RtxDrv/Inc/RtxDrvClasses.h | 2 ++ RtxDrv/Src/RtxRenderDevice.cpp | 41 ++++++++++++++++++++++++++++++++++ RtxDrv/Src/RtxRenderDevice.h | 2 +- 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/Engine/Inc/UnRender.h b/Engine/Inc/UnRender.h index ab66798c..dd7b0414 100644 --- a/Engine/Inc/UnRender.h +++ b/Engine/Inc/UnRender.h @@ -137,7 +137,7 @@ class ENGINE_API FLevelSceneNode : public FSceneNode{ // Virtual functions virtual FConvexVolume GetViewFrustum(); virtual UBOOL FilterActor(AActor* Actor); - virtual UBOOL FilterAttachment(AActor* AttachedActor){ return 1; } + virtual UBOOL FilterAttachment(AActor* AttachedActor){ return 1; } virtual UBOOL FilterProjector(AProjector* Actor); }; diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc index cdd3973a..f0cf59c9 100644 --- a/RtxDrv/Classes/Rtx.uc +++ b/RtxDrv/Classes/Rtx.uc @@ -7,6 +7,8 @@ var(General) config color AnchorTriangleColor; var(General) config bool bDrawAnchorTriangle; var(General) config bool bCaptureMode; var(General) config bool bReplaceHardwareShaderMaterials; +var(General) config bool bDisableFrustumCulling; +var(General) config bool bDisableSkyZones; var(Lighting) config bool bEnableD3DLights; var(Lighting) config bool bEnableLights; @@ -36,6 +38,8 @@ defaultproperties AnchorTriangleColor=(R=255,G=255,B=0,A=255) bDrawAnchorTriangle=True bReplaceHardwareShaderMaterials=True + bDisableFrustumCulling=True + bDisableSkyZones=True bEnableD3DLights=False bEnableLights=True ComponentClasses(0)=class'RtxFlashlightComponent' diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 71c7d01b..0dc67595 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -40,6 +40,8 @@ class RTXDRV_API URtx : public UObject BITFIELD bDrawAnchorTriangle:1 GCC_PACK(4); BITFIELD bCaptureMode:1; BITFIELD bReplaceHardwareShaderMaterials:1; + BITFIELD bDisableFrustumCulling:1; + BITFIELD bDisableSkyZones:1; BITFIELD bEnableD3DLights:1; BITFIELD bEnableLights:1; TArrayNoInit Lights GCC_PACK(4); diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index e2e17bdc..4567c13d 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -2,9 +2,12 @@ #include "RtxDrvPrivate.h" #include "Window.h" #include "Editor.h" +#include "CodeInjection.h" IMPLEMENT_CLASS(URtxRenderDevice) +static URtxRenderDevice* GRtxRenDev = NULL; + static ULevel* GetLevel() { if(GEngine->IsA()) @@ -16,6 +19,23 @@ static ULevel* GetLevel() return NULL; } +typedef FConvexVolume&(__fastcall*FPlayerSceneNodeGetViewFrustum)(FLevelSceneNode* Self, DWORD Edx, FConvexVolume& Result); + +static FPlayerSceneNodeGetViewFrustum OriginalFPlayerSceneNodeGetViewFrustum = NULL; + +static FConvexVolume& __fastcall FPlayerSceneNodeGetViewFrustumOverride(FPlayerSceneNode* Self, DWORD Edx, FConvexVolume& Result) +{ + OriginalFPlayerSceneNodeGetViewFrustum(Self, Edx, Result); + + if(GRtxRenDev && GRtxRenDev->GetRtxInterface()->bDisableFrustumCulling) + { + for(INT i = 0; i < 5; i++) + Result.BoundingPlanes[i].W += 10000.0f; + } + + return Result; +} + // static INT GetMaterialFlags(UMaterial* Material) // { // return reinterpret_cast(Material)[24] >> 2; @@ -122,6 +142,8 @@ void URtxRenderDevice::StaticConstructor() UBOOL URtxRenderDevice::Init() { + GRtxRenDev = this; + // Init SWRCFix if it exists. Hacky but RenderDevice is always loaded at startup... HMODULE ModDLL = LoadLibraryA("Mod.dll"); @@ -133,6 +155,14 @@ UBOOL URtxRenderDevice::Init() InitSWRCFix(); } + static bool bCodeInjected = false; + if(!bCodeInjected) + { + OriginalFPlayerSceneNodeGetViewFrustum = reinterpret_cast( + PatchDllClassVTable("Engine.dll", "FPlayerSceneNode", NULL, 10, FPlayerSceneNodeGetViewFrustumOverride)); + bCodeInjected = true; + } + ClearMaterialFlags(); UClient* Client = GEngine->Client; Client->Shadows = 0; @@ -154,6 +184,7 @@ void URtxRenderDevice::Exit(UViewport* Viewport) delete Rtx; Rtx = NULL; Super::Exit(Viewport); + GRtxRenDev = NULL; } UBOOL URtxRenderDevice::SetRes(UViewport* Viewport, INT NewX, INT NewY, UBOOL Fullscreen, INT ColorBytes, UBOOL bSaveSize) @@ -190,6 +221,16 @@ FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT { CurrentLevel = Level; AnchorTriangleStream.Update(CurrentLevel ? (appStrihash(CurrentLevel->GetPathName()) / (FLOAT)MAXDWORD) : 0.0f); + + if(Rtx->bDisableSkyZones) + { + foreach(AllActors, AZoneInfo, Info, CurrentLevel) + { + Info->SkyZone = NULL; + Info->bUseSkyDome = 0; + } + } + Rtx->LevelChanged(CurrentLevel); } diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index 1269f46a..b37b8484 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -57,7 +57,7 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ virtual void Unlock(FRenderInterface* RI); virtual void Present(UViewport* Viewport); - URtx* GetRtxInterface(){ return Rtx; } + URtx* GetRtxInterface(){ checkSlow(Rtx); return Rtx; } // FRenderInterface From 602ca38f43e3eae2beb1347000fb9db29b577e85 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Wed, 18 Jun 2025 01:56:58 +0200 Subject: [PATCH 44/48] Remove nonexistent function --- Core/Inc/UnObjBas.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/Inc/UnObjBas.h b/Core/Inc/UnObjBas.h index 2cf1ac14..7cc2409b 100644 --- a/Core/Inc/UnObjBas.h +++ b/Core/Inc/UnObjBas.h @@ -514,7 +514,6 @@ class CORE_API UObject{ UBOOL IsA(FName SomeBaseClassName) const; UBOOL IsIn(UObject* SomeOuter) const; UBOOL IsProbing(FName ProbeName); - UField* FindObjectField(FName InName, UBOOL Global = 0); UFunction* FindFunction(FName InName, UBOOL Global = 0); UFunction* FindFunctionChecked(FName InName, UBOOL Global = 0); UState* FindState(FName InName); From d3f1c790f9cae3a9ea001983fcbf08ed4d79a151 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Fri, 11 Jul 2025 02:29:05 +0200 Subject: [PATCH 45/48] Add rtx particle component --- RtxDrv/Classes/Rtx.uc | 24 ++++++++++++++---------- RtxDrv/Classes/RtxParticleComponent.uc | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 RtxDrv/Classes/RtxParticleComponent.uc diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc index f0cf59c9..babd6175 100644 --- a/RtxDrv/Classes/Rtx.uc +++ b/RtxDrv/Classes/Rtx.uc @@ -3,18 +3,21 @@ class Rtx extends Object native transient config(Rtx) hidecategories(Object, Non var(Components) config array > ComponentClasses; var(Components) native editconst editinline array Components; // Must be native so the property is excluded from gc. The array is cleared in native code when the level changes. -var(General) config color AnchorTriangleColor; -var(General) config bool bDrawAnchorTriangle; -var(General) config bool bCaptureMode; -var(General) config bool bReplaceHardwareShaderMaterials; -var(General) config bool bDisableFrustumCulling; -var(General) config bool bDisableSkyZones; +// Most of these properties actually belong in RtxRenderDevice but can't be added there because the class is too large for 16 bit property offsets -var(Lighting) config bool bEnableD3DLights; -var(Lighting) config bool bEnableLights; -var(Lighting) const editinline array Lights; +var(General) config color AnchorTriangleColor; +var(General) config bool bDrawAnchorTriangle; +var(General) config bool bCaptureMode; +var(General) config bool bReplaceHardwareShaderMaterials; +var(General) config bool bDisableFrustumCulling; +var(General) config bool bDisableSkyZones; -var const editconst array DestroyedLights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights +var(Lighting) config bool bEnableD3DLights; +var(Lighting) config bool bEnableLights; +var(Lighting) const editinline array Lights; + +// Keep destroyed lights around to reduce overhead of creating/destroying short lived lights +var const editconst array DestroyedLights; native final function RtxLight CreateLight(); native final function DestroyLight(RtxLight Light); @@ -43,4 +46,5 @@ defaultproperties bEnableD3DLights=False bEnableLights=True ComponentClasses(0)=class'RtxFlashlightComponent' + ComponentClasses(1)=class'RtxParticleComponent' } diff --git a/RtxDrv/Classes/RtxParticleComponent.uc b/RtxDrv/Classes/RtxParticleComponent.uc new file mode 100644 index 00000000..2a86875f --- /dev/null +++ b/RtxDrv/Classes/RtxParticleComponent.uc @@ -0,0 +1,21 @@ +class RtxParticleComponent extends RtxComponent; + +var() config bool bDisableFlipbookAnimations; + +function PostBeginPlay() +{ + if(bDisableFlipbookAnimations) + { + ConsoleCommand("SET SpriteEmitter TextureUSubdivisions 0"); + ConsoleCommand("SET SpriteEmitter TextureVSubdivisions 0"); + } +} + +function Tick(float DeltaTime) +{ +} + +defaultproperties +{ + bDisableFlipbookAnimations=True +} From 0f080532dddf3456c5203c07145a2c019e3b8fe5 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Thu, 17 Jul 2025 04:14:51 +0200 Subject: [PATCH 46/48] Make level change check more robust --- RtxDrv/Src/RtxRenderDevice.cpp | 51 ++++++++++++++++++++++------------ RtxDrv/Src/RtxRenderDevice.h | 2 +- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 4567c13d..4f9fb7a5 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -203,36 +203,53 @@ void URtxRenderDevice::Flush(UViewport* Viewport) Super::Flush(Viewport); } -FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) +/* + * Check for a level change and notify the RTX interface so it can recreate the components. + * This is the most reliable way to do it that I've been able to find. + * UGameEngine::GLevel does not always change when restarting the level so the additional check for a non-empty travel URL is also needed. + */ +void URtxRenderDevice::CheckForLevelChange(UViewport* Viewport) { - if(Rtx->bCaptureMode) - Viewport->Precaching = 1; - - DepthCleared = 0; + static bool bPendingLevel = false; + static ULevel* Level = NULL; - D3D = Super::Lock(Viewport, HitData, HitSize); - - if(!D3D) - return NULL; - - ULevel* Level = GetLevel(); - - if(Level != CurrentLevel) + if(Viewport && Viewport->TravelURL.Len() > 0) + { + bPendingLevel = true; + } + else if(bPendingLevel || Level != GetLevel()) { - CurrentLevel = Level; - AnchorTriangleStream.Update(CurrentLevel ? (appStrihash(CurrentLevel->GetPathName()) / (FLOAT)MAXDWORD) : 0.0f); + bPendingLevel = false; + Level = GetLevel(); + + AnchorTriangleStream.Update(appStrihash(Level->GetPathName()) / (FLOAT)MAXDWORD); if(Rtx->bDisableSkyZones) { - foreach(AllActors, AZoneInfo, Info, CurrentLevel) + foreach(AllActors, AZoneInfo, Info, Level) { Info->SkyZone = NULL; Info->bUseSkyDome = 0; } } - Rtx->LevelChanged(CurrentLevel); + Rtx->LevelChanged(Level); } +} + +FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT* HitSize) +{ + CheckForLevelChange(Viewport); + + if(Rtx->bCaptureMode) + Viewport->Precaching = 1; + + DepthCleared = 0; + + D3D = Super::Lock(Viewport, HitData, HitSize); + + if(!D3D) + return NULL; LockedViewport = Viewport; diff --git a/RtxDrv/Src/RtxRenderDevice.h b/RtxDrv/Src/RtxRenderDevice.h index b37b8484..046dd343 100644 --- a/RtxDrv/Src/RtxRenderDevice.h +++ b/RtxDrv/Src/RtxRenderDevice.h @@ -102,7 +102,6 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ private: UViewport* LockedViewport; - ULevel* CurrentLevel; FAnchorTriangleVertexStream AnchorTriangleStream; FRenderInterface* D3D; URtx* Rtx; @@ -115,5 +114,6 @@ class URtxRenderDevice : public UD3DRenderDevice, FRenderInterface{ BITFIELD IgnoreDrawCall; + void CheckForLevelChange(UViewport* Viewport); void DrawAnchorTriangle(); }; From 6b0121efb674357c634b19ae0b04db820fa3bf5d Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Thu, 17 Jul 2025 04:19:52 +0200 Subject: [PATCH 47/48] Make it possible to create an RtxLight standalone without Rtx::CreateLight --- RtxDrv/Classes/Rtx.uc | 2 -- RtxDrv/Classes/RtxFlashlight.uc | 43 ++++++++------------------- RtxDrv/Classes/RtxLight.uc | 4 ++- RtxDrv/Inc/RtxDrvClasses.h | 3 +- RtxDrv/Src/Rtx.cpp | 52 +++++++++++++++++++++------------ RtxDrv/Src/RtxDrvClasses.cpp | 1 + 6 files changed, 52 insertions(+), 53 deletions(-) diff --git a/RtxDrv/Classes/Rtx.uc b/RtxDrv/Classes/Rtx.uc index babd6175..a0053c5f 100644 --- a/RtxDrv/Classes/Rtx.uc +++ b/RtxDrv/Classes/Rtx.uc @@ -13,7 +13,6 @@ var(General) config bool bDisableFrustumCulling; var(General) config bool bDisableSkyZones; var(Lighting) config bool bEnableD3DLights; -var(Lighting) config bool bEnableLights; var(Lighting) const editinline array Lights; // Keep destroyed lights around to reduce overhead of creating/destroying short lived lights @@ -44,7 +43,6 @@ defaultproperties bDisableFrustumCulling=True bDisableSkyZones=True bEnableD3DLights=False - bEnableLights=True ComponentClasses(0)=class'RtxFlashlightComponent' ComponentClasses(1)=class'RtxParticleComponent' } diff --git a/RtxDrv/Classes/RtxFlashlight.uc b/RtxDrv/Classes/RtxFlashlight.uc index f422d364..b55f5e95 100644 --- a/RtxDrv/Classes/RtxFlashlight.uc +++ b/RtxDrv/Classes/RtxFlashlight.uc @@ -47,7 +47,7 @@ function CalcLightPositionAndDirection(Pawn Pawn, out vector Position, out vecto Direction = vector(ViewRotation); } -function UpdateLight(Pawn Pawn, RtxLight Light, vector Position, vector Direction, FlashlightCone Cone) +function UpdateAndRenderLight(Pawn Pawn, RtxLight Light, vector Position, vector Direction, FlashlightCone Cone) { Light.Position = Position; Light.Shaping.Direction = Direction; @@ -58,42 +58,29 @@ function UpdateLight(Pawn Pawn, RtxLight Light, vector Position, vector Directio Light.Shaping.ConeSoftness = Cone.Softness; Light.Update(); + Light.Render(); } function Init() { - local Rtx Rtx; - - Rtx = class'Rtx'.static.GetInstance(); - - OuterLight = Rtx.CreateLight(); + OuterLight = new class'RtxLight'; OuterLight.Type = RTXLIGHT_Sphere; - OuterLight.bEnabled = false; OuterLight.bUseShaping = true; - OuterLight.Update(); - MainLight = Rtx.CreateLight(); + MainLight = new class'RtxLight'; MainLight.Type = RTXLIGHT_Sphere; - MainLight.bEnabled = false; MainLight.bUseShaping = true; - MainLight.Update(); - InnerLight = Rtx.CreateLight(); + InnerLight = new class'RtxLight'; InnerLight.Type = RTXLIGHT_Sphere; - InnerLight.bEnabled = false; InnerLight.bUseShaping = true; - InnerLight.Update(); } function Exit() { - local Rtx Rtx; - - Rtx = class'Rtx'.static.GetInstance(); - - Rtx.DestroyLight(OuterLight); - Rtx.DestroyLight(MainLight); - Rtx.DestroyLight(InnerLight); + OuterLight = None; + MainLight = None; + InnerLight = None; } function Update(Pawn Pawn, bool bOn) @@ -101,20 +88,14 @@ function Update(Pawn Pawn, bool bOn) local vector LightPosition; local vector LightDirection; - if(bOn != bIsOn) - { - OuterLight.bEnabled = bOn; - MainLight.bEnabled = bOn; - InnerLight.bEnabled = bOn; - bIsOn = bOn; - } + bIsOn = bOn; if(bIsOn && Pawn != None) { CalcLightPositionAndDirection(Pawn, LightPosition, LightDirection); - UpdateLight(Pawn, OuterLight, LightPosition, LightDirection, OuterCone); - UpdateLight(Pawn, MainLight, LightPosition, LightDirection, MainCone); - UpdateLight(Pawn, InnerLight, LightPosition, LightDirection, InnerCone); + UpdateAndRenderLight(Pawn, OuterLight, LightPosition, LightDirection, OuterCone); + UpdateAndRenderLight(Pawn, MainLight, LightPosition, LightDirection, MainCone); + UpdateAndRenderLight(Pawn, InnerLight, LightPosition, LightDirection, InnerCone); } } diff --git a/RtxDrv/Classes/RtxLight.uc b/RtxDrv/Classes/RtxLight.uc index d5e034bc..e7a9b681 100644 --- a/RtxDrv/Classes/RtxLight.uc +++ b/RtxDrv/Classes/RtxLight.uc @@ -1,4 +1,4 @@ -class RtxLight extends Object within Rtx native transient hidecategories(Object, None); +class RtxLight extends Object native transient hidecategories(Object, None); var(Common) enum ERtxLightType{ RTXLIGHT_Sphere, @@ -57,6 +57,7 @@ var(DistantLight) struct RtxDistantLight{ var const editconst noexport int Handle; native final function Update(); // Must be called whenever a property value has changed +native final function Render(); // Only needs to be called manually for lights that were not created with Rtx::CreateLight cpptext { @@ -65,6 +66,7 @@ cpptext virtual void Destroy(); virtual void PostEditChange(){ Super::PostEditChange(); Update(); } void Update(); + void Render(); void DestroyHandle(); } diff --git a/RtxDrv/Inc/RtxDrvClasses.h b/RtxDrv/Inc/RtxDrvClasses.h index 0dc67595..df2a1485 100644 --- a/RtxDrv/Inc/RtxDrvClasses.h +++ b/RtxDrv/Inc/RtxDrvClasses.h @@ -43,7 +43,6 @@ class RTXDRV_API URtx : public UObject BITFIELD bDisableFrustumCulling:1; BITFIELD bDisableSkyZones:1; BITFIELD bEnableD3DLights:1; - BITFIELD bEnableLights:1; TArrayNoInit Lights GCC_PACK(4); TArrayNoInit DestroyedLights; void execCreateLight(FFrame& Stack, void* Result); @@ -132,12 +131,14 @@ class RTXDRV_API URtxLight : public UObject FRtxCylinderLight Cylinder; FRtxDistantLight Distant; void execUpdate(FFrame& Stack, void* Result); + void execRender(FFrame& Stack, void* Result); DECLARE_CLASS(URtxLight,UObject,0|CLASS_Transient,RtxDrv) remixapi_LightHandle_T* Handle; virtual void Destroy(); virtual void PostEditChange(){ Super::PostEditChange(); Update(); } void Update(); + void Render(); void DestroyHandle(); DECLARE_NATIVES(URtxLight) }; diff --git a/RtxDrv/Src/Rtx.cpp b/RtxDrv/Src/Rtx.cpp index 190ecb9c..cbaacea1 100644 --- a/RtxDrv/Src/Rtx.cpp +++ b/RtxDrv/Src/Rtx.cpp @@ -65,6 +65,8 @@ void URtx::DestroyLight(URtxLight* Light) void URtx::LevelChanged(ULevel* Level) { + debugf("Level changed - Initializing RTX components"); + DestroyedLights += Lights; Lights.Empty(); Components.Empty(); // Component actors aren't valid anymore now that the level has changed so just clear the old ones @@ -74,20 +76,20 @@ void URtx::LevelChanged(ULevel* Level) UClass* ComponentClass = ComponentClasses[i]; if(ComponentClass) { + debugf("Spawning RTX component: %s", ComponentClass->GetName()); + ARtxComponent* Actor = static_cast(Level->SpawnActor(ComponentClass)); + if(Actor) Components.AddItem(Actor); else - debugf("Failed to spawn Rtx component of class %s", ComponentClass->GetName()); + debugf("Failed to spawn RTX component of class %s", ComponentClass->GetName()); } } } void URtx::RenderLights() { - if(!bEnableLights) - return; - for(INT i = 0; i < Lights.Num(); ++i) { URtxLight* Light = Lights[i]; @@ -107,18 +109,11 @@ void URtx::RenderLights() if(!Light) // NULL entry can happen if a light was added via the property window UI. In that case just create it { - Light = new(this) URtxLight; + Light = CreateLight(true); Lights[i] = Light; } - if(Light->bEnabled) - { - if(!Light->Handle) - Light->Update(); - - if(Light->Handle) - GRemixApi.DrawLightInstance(Light->Handle); - } + Light->Render(); } } @@ -159,6 +154,12 @@ void URtxLight::execUpdate(FFrame& Stack, void* Result) Update(); } +void URtxLight::execRender(FFrame& Stack, void* Result) +{ + P_FINISH; + Render(); +} + void URtxLight::Destroy() { DestroyHandle(); @@ -195,7 +196,7 @@ void URtxLight::Update() { case RTXLIGHT_Sphere: { - remixapi_LightInfoSphereEXT SphereInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT}; + static remixapi_LightInfoSphereEXT SphereInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_SPHERE_EXT}; InitFloat3D(SphereInfo.position, Position); SphereInfo.radius = Sphere.Radius; SphereInfo.shaping_hasvalue = bUseShaping; @@ -208,7 +209,7 @@ void URtxLight::Update() } case RTXLIGHT_Rect: { - remixapi_LightInfoRectEXT RectInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT}; + static remixapi_LightInfoRectEXT RectInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_RECT_EXT}; InitFloat3D(RectInfo.position, Position); InitFloat3D(RectInfo.xAxis, Rect.XAxis.GetNormalized()); RectInfo.xSize = Rect.XSize; @@ -225,7 +226,7 @@ void URtxLight::Update() } case RTXLIGHT_Disk: { - remixapi_LightInfoDiskEXT DiskInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT}; + static remixapi_LightInfoDiskEXT DiskInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISK_EXT}; InitFloat3D(DiskInfo.position, Position); InitFloat3D(DiskInfo.xAxis, Disk.XAxis.GetNormalized()); DiskInfo.xRadius = Disk.XRadius; @@ -242,7 +243,7 @@ void URtxLight::Update() } case RTXLIGHT_Cylinder: { - remixapi_LightInfoCylinderEXT CylinderInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT}; + static remixapi_LightInfoCylinderEXT CylinderInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_CYLINDER_EXT}; InitFloat3D(CylinderInfo.position, Position); InitFloat3D(CylinderInfo.axis, Cylinder.Axis.GetNormalized()); CylinderInfo.radius = Cylinder.Radius; @@ -252,7 +253,7 @@ void URtxLight::Update() } case RTXLIGHT_Distant: { - remixapi_LightInfoDistantEXT DistantInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT}; + static remixapi_LightInfoDistantEXT DistantInfo = {REMIXAPI_STRUCT_TYPE_LIGHT_INFO_DISTANT_EXT}; InitFloat3D(DistantInfo.direction, Distant.Direction.GetNormalized()); DistantInfo.angularDiameterDegrees = Distant.AngularDiameterDegrees; LightInfo.pNext = &DistantInfo; @@ -263,6 +264,21 @@ void URtxLight::Update() GRemixApi.CreateLight(&LightInfo, &Handle); } +void URtxLight::Render() +{ + if(GRemixApiInitialized && Handle) + { + if(bEnabled) + { + if(!Handle) + Update(); + + if(Handle) + GRemixApi.DrawLightInstance(Handle); + } + } +} + void URtxLight::DestroyHandle() { if(GRemixApiInitialized && Handle) diff --git a/RtxDrv/Src/RtxDrvClasses.cpp b/RtxDrv/Src/RtxDrvClasses.cpp index 78adf58c..2eb47527 100644 --- a/RtxDrv/Src/RtxDrvClasses.cpp +++ b/RtxDrv/Src/RtxDrvClasses.cpp @@ -25,6 +25,7 @@ LINK_NATIVES(URtx); IMPLEMENT_CLASS(URtxLight); FNativeEntry URtxLight::StaticNativeMap[] = { MAP_NATIVE(Update,0) + MAP_NATIVE(Render,0) {NULL,NULL} }; LINK_NATIVES(URtxLight); From 893c38176baa23d85a25400849875b257dbeadd1 Mon Sep 17 00:00:00 2001 From: Leon Buckel Date: Sun, 20 Jul 2025 22:03:15 +0200 Subject: [PATCH 48/48] Make sure relevant graphics settings are set to the correct values --- RtxDrv/Src/RtxRenderDevice.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RtxDrv/Src/RtxRenderDevice.cpp b/RtxDrv/Src/RtxRenderDevice.cpp index 4f9fb7a5..62e60ab0 100644 --- a/RtxDrv/Src/RtxRenderDevice.cpp +++ b/RtxDrv/Src/RtxRenderDevice.cpp @@ -165,7 +165,6 @@ UBOOL URtxRenderDevice::Init() ClearMaterialFlags(); UClient* Client = GEngine->Client; - Client->Shadows = 0; Client->FrameFXDisabled = 1; Client->BloomQuality = 0; Client->BlurEnabled = 0; @@ -241,6 +240,11 @@ FRenderInterface* URtxRenderDevice::Lock(UViewport* Viewport, BYTE* HitData, INT { CheckForLevelChange(Viewport); + // Make sure relevant graphics options are set to the correct values + UClient* Client = GEngine->Client; + appMemzero(Client->TextureLODSet, sizeof(Client->TextureLODSet)); + Client->Shadows = 0; + if(Rtx->bCaptureMode) Viewport->Precaching = 1;