From 22ca1df23fff6ece855a55e0238c1a994d675b57 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Tue, 14 Dec 2021 17:20:11 +0100 Subject: [PATCH 01/15] Code cleanup --- D3D11Engine/D3D11GraphicsEngine.cpp | 3 --- D3D11Engine/oCNPC.h | 20 ++++++++--------- D3D11Engine/oCSpawnManager.h | 6 ++--- D3D11Engine/zCMaterial.h | 8 +++---- D3D11Engine/zCParticleFX.h | 4 ++-- D3D11Engine/zCQuadMark.h | 14 ++++++------ D3D11Engine/zCVisual.h | 4 ++-- D3D11Engine/zCVob.h | 20 ++++++++--------- D3D11Engine/zCWorld.h | 34 ++++++++++++++--------------- 9 files changed, 55 insertions(+), 58 deletions(-) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index 43e26fdb..87a5a4ba 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -5757,9 +5757,6 @@ void D3D11GraphicsEngine::DrawQuadMarks() { break; case zMAT_ALPHA_FUNC_MUL: - MulQuadMarks.emplace_back( it.first, &it.second ); - continue; - case zMAT_ALPHA_FUNC_MUL2: MulQuadMarks.emplace_back( it.first, &it.second ); continue; diff --git a/D3D11Engine/oCNPC.h b/D3D11Engine/oCNPC.h index 81d902e8..8a58d5c6 100644 --- a/D3D11Engine/oCNPC.h +++ b/D3D11Engine/oCNPC.h @@ -33,35 +33,35 @@ class oCNPC : public zCVob { XHook( HookedFunctions::OriginalFunctions.original_oCNPCInitModel, GothicMemoryLocations::oCNPC::InitModel, oCNPC::hooked_oCNPCInitModel ); } - static void __fastcall hooked_oCNPCInitModel( void* thisptr, void* unknwn ) { + static void __fastcall hooked_oCNPCInitModel( zCVob* thisptr, void* unknwn ) { hook_infunc HookedFunctions::OriginalFunctions.original_oCNPCInitModel( thisptr ); - if (/*((zCVob *)thisptr)->GetVisual() || */Engine::GAPI->GetSkeletalVobByVob( (zCVob*)thisptr ) ) { + if ( /*((zCVob *)thisptr)->GetVisual() || */Engine::GAPI->GetSkeletalVobByVob( thisptr ) ) { // This may causes the vob to be added and removed multiple times, but makes sure we get all changes of armor - Engine::GAPI->OnRemovedVob( (zCVob*)thisptr, ((zCVob*)thisptr)->GetHomeWorld() ); - Engine::GAPI->OnAddVob( (zCVob*)thisptr, ((zCVob*)thisptr)->GetHomeWorld() ); + Engine::GAPI->OnRemovedVob( thisptr, thisptr->GetHomeWorld() ); + Engine::GAPI->OnAddVob( thisptr, thisptr->GetHomeWorld() ); } hook_outfunc } /** Reads config stuff */ - static void __fastcall hooked_oCNPCEnable( void* thisptr, void* unknwn, DirectX::XMFLOAT3& position ) { + static void __fastcall hooked_oCNPCEnable( zCVob* thisptr, void* unknwn, DirectX::XMFLOAT3& position ) { hook_infunc HookedFunctions::OriginalFunctions.original_oCNPCEnable( thisptr, position ); // Re-Add if needed - Engine::GAPI->OnRemovedVob( (zCVob*)thisptr, ((zCVob*)thisptr)->GetHomeWorld() ); - Engine::GAPI->OnAddVob( (zCVob*)thisptr, ((zCVob*)thisptr)->GetHomeWorld() ); + Engine::GAPI->OnRemovedVob( thisptr, thisptr->GetHomeWorld() ); + Engine::GAPI->OnAddVob( thisptr, thisptr->GetHomeWorld() ); hook_outfunc } - static void __fastcall hooked_oCNPCDisable( void* thisptr, void* unknwn ) { + static void __fastcall hooked_oCNPCDisable( oCNPC* thisptr, void* unknwn ) { hook_infunc // Remove vob from world - if ( !((oCNPC*)thisptr)->IsAPlayer() ) // Never disable the player vob - Engine::GAPI->OnRemovedVob( (zCVob*)thisptr, ((zCVob*)thisptr)->GetHomeWorld() ); + if ( !thisptr->IsAPlayer() ) // Never disable the player vob + Engine::GAPI->OnRemovedVob( thisptr, thisptr->GetHomeWorld() ); HookedFunctions::OriginalFunctions.original_oCNPCDisable( thisptr ); diff --git a/D3D11Engine/oCSpawnManager.h b/D3D11Engine/oCSpawnManager.h index 72a69de4..ff1a8d00 100644 --- a/D3D11Engine/oCSpawnManager.h +++ b/D3D11Engine/oCSpawnManager.h @@ -21,13 +21,13 @@ class oCSpawnManager { } /** Reads config stuff */ - static void __fastcall hooked_oCSpawnManagerSpawnNpc( void* thisptr, void* unknwn, oCNPC* npc, const DirectX::XMFLOAT3& position, float f ) { + static void __fastcall hooked_oCSpawnManagerSpawnNpc( zCVob* thisptr, void* unknwn, oCNPC* npc, const DirectX::XMFLOAT3& position, float f ) { hook_infunc HookedFunctions::OriginalFunctions.original_oCSpawnManagerSpawnNpc( thisptr, npc, position, f ); if ( npc->GetSleepingMode() != 0 || npc->IsAPlayer() ) { - Engine::GAPI->OnRemovedVob( (zCVob*)npc, ((zCVob*)npc)->GetHomeWorld() ); - Engine::GAPI->OnAddVob( (zCVob*)npc, ((zCVob*)npc)->GetHomeWorld() ); + Engine::GAPI->OnRemovedVob( npc, npc->GetHomeWorld() ); + Engine::GAPI->OnAddVob( npc, npc->GetHomeWorld() ); } hook_outfunc } diff --git a/D3D11Engine/zCMaterial.h b/D3D11Engine/zCMaterial.h index 1304a9f0..52d38507 100644 --- a/D3D11Engine/zCMaterial.h +++ b/D3D11Engine/zCMaterial.h @@ -38,12 +38,12 @@ class zCMaterial { } - static void __fastcall Hooked_Destructor( void* thisptr, void* unknwn ) { + static void __fastcall Hooked_Destructor( zCMaterial* thisptr, void* unknwn ) { hook_infunc // Notify the world if ( Engine::GAPI ) - Engine::GAPI->OnMaterialDeleted( (zCMaterial*)thisptr ); + Engine::GAPI->OnMaterialDeleted( thisptr ); HookedFunctions::OriginalFunctions.original_zCMaterialDestructor( thisptr ); @@ -60,12 +60,12 @@ class zCMaterial { hook_outfunc } - static void __fastcall Hooked_InitValues( void* thisptr, void* unknwn ) { + static void __fastcall Hooked_InitValues( zCMaterial* thisptr, void* unknwn ) { hook_infunc // Notify the world if ( Engine::GAPI ) - Engine::GAPI->OnMaterialCreated( (zCMaterial*)thisptr ); + Engine::GAPI->OnMaterialCreated( thisptr ); HookedFunctions::OriginalFunctions.original_zCMaterialInitValues( thisptr ); diff --git a/D3D11Engine/zCParticleFX.h b/D3D11Engine/zCParticleFX.h index 98208a92..ddab41b7 100644 --- a/D3D11Engine/zCParticleFX.h +++ b/D3D11Engine/zCParticleFX.h @@ -139,11 +139,11 @@ class zCParticleFX { XHook( HookedFunctions::OriginalFunctions.original_zCParticleFXDestructor, GothicMemoryLocations::zCParticleFX::Destructor, zCParticleFX::Hooked_Destructor ); } - static void __fastcall Hooked_Destructor( void* thisptr, void* unknwn ) { + static void __fastcall Hooked_Destructor( zCParticleFX* thisptr, void* unknwn ) { hook_infunc // Notify the world if ( Engine::GAPI ) - Engine::GAPI->OnParticleFXDeleted( (zCParticleFX*)thisptr ); + Engine::GAPI->OnParticleFXDeleted( thisptr ); HookedFunctions::OriginalFunctions.original_zCParticleFXDestructor( thisptr ); diff --git a/D3D11Engine/zCQuadMark.h b/D3D11Engine/zCQuadMark.h index eca96d60..fb54266a 100644 --- a/D3D11Engine/zCQuadMark.h +++ b/D3D11Engine/zCQuadMark.h @@ -16,21 +16,21 @@ class zCQuadMark { XHook( HookedFunctions::OriginalFunctions.original_zCQuadMarkDestructor, GothicMemoryLocations::zCQuadMark::Destructor, zCQuadMark::Hooked_Destructor ); } - static void __fastcall Hooked_CreateQuadMark( void* thisptr, void* unknwn, zCPolygon* poly, const float3& position, const float2& size, struct zTEffectParams* params ) { + static void __fastcall Hooked_CreateQuadMark( zCQuadMark* thisptr, void* unknwn, zCPolygon* poly, const float3& position, const float2& size, struct zTEffectParams* params ) { hook_infunc - if ( ((zCQuadMark*)thisptr)->GetDontRepositionConnectedVob() ) + if ( thisptr->GetDontRepositionConnectedVob() ) return; // Don't create quad-marks for particle-effects because it's kinda slow at the moment // And even for the original game using some emitters? (L'Hiver Light, Swampdragon) HookedFunctions::OriginalFunctions.original_zCQuadMarkCreateQuadMark( thisptr, poly, position, size, params ); - QuadMarkInfo* info = Engine::GAPI->GetQuadMarkInfo( (zCQuadMark*)thisptr ); + QuadMarkInfo* info = Engine::GAPI->GetQuadMarkInfo( thisptr ); - WorldConverter::UpdateQuadMarkInfo( info, (zCQuadMark*)thisptr, position ); + WorldConverter::UpdateQuadMarkInfo( info, thisptr, position ); if ( !info->Mesh ) - Engine::GAPI->RemoveQuadMark( (zCQuadMark*)thisptr ); + Engine::GAPI->RemoveQuadMark( thisptr ); hook_outfunc } @@ -43,12 +43,12 @@ class zCQuadMark { hook_outfunc } - static void __fastcall Hooked_Destructor( void* thisptr, void* unknwn ) { + static void __fastcall Hooked_Destructor( zCQuadMark* thisptr, void* unknwn ) { hook_infunc HookedFunctions::OriginalFunctions.original_zCQuadMarkDestructor( thisptr ); - Engine::GAPI->RemoveQuadMark( (zCQuadMark*)thisptr ); + Engine::GAPI->RemoveQuadMark( thisptr ); hook_outfunc } diff --git a/D3D11Engine/zCVisual.h b/D3D11Engine/zCVisual.h index d9e63018..a3526ce3 100644 --- a/D3D11Engine/zCVisual.h +++ b/D3D11Engine/zCVisual.h @@ -21,11 +21,11 @@ class zCVisual { XHook( HookedFunctions::OriginalFunctions.original_zCVisualDestructor, GothicMemoryLocations::zCVisual::Destructor, zCVisual::Hooked_Destructor ); } - static void __fastcall Hooked_Destructor( void* thisptr, void* unknwn ) { + static void __fastcall Hooked_Destructor( zCVisual* thisptr, void* unknwn ) { hook_infunc // Notify the world if ( Engine::GAPI ) - Engine::GAPI->OnVisualDeleted( (zCVisual*)thisptr ); + Engine::GAPI->OnVisualDeleted( thisptr ); HookedFunctions::OriginalFunctions.original_zCVisualDestructor( thisptr ); hook_outfunc diff --git a/D3D11Engine/zCVob.h b/D3D11Engine/zCVob.h index 264d1cf3..2b1a50fd 100644 --- a/D3D11Engine/zCVob.h +++ b/D3D11Engine/zCVob.h @@ -45,47 +45,47 @@ class zCVob { /** Called when this vob got it's world-matrix changed */ #ifdef BUILD_GOTHIC_1_08k - static void __fastcall Hooked_EndMovement( void* thisptr, void* unknwn ) { + static void __fastcall Hooked_EndMovement( zCVob* thisptr, void* unknwn ) { hook_infunc bool vobHasMoved = false; - if ( (*reinterpret_cast(reinterpret_cast(thisptr) + 0xE8) & 0x03) && reinterpret_cast(thisptr)->GetHomeWorld() ) { + if ( (*reinterpret_cast(reinterpret_cast(thisptr) + 0xE8) & 0x03) && thisptr->GetHomeWorld() ) { vobHasMoved = (*reinterpret_cast(*reinterpret_cast(reinterpret_cast(thisptr) + 0xFC) + 0x88) & 0x03); } HookedFunctions::OriginalFunctions.original_zCVobEndMovement( thisptr ); if ( Engine::GAPI && vobHasMoved ) - Engine::GAPI->OnVobMoved( (zCVob*)thisptr ); + Engine::GAPI->OnVobMoved( thisptr ); hook_outfunc } #else - static void __fastcall Hooked_EndMovement( void* thisptr, void* unknwn, int transformChanged_hint ) // G2 has one parameter more + static void __fastcall Hooked_EndMovement( zCVob* thisptr, void* unknwn, int transformChanged_hint ) // G2 has one parameter more { hook_infunc bool vobHasMoved = false; - if ( (*reinterpret_cast(reinterpret_cast(thisptr) + 0x108) & 0x03) && reinterpret_cast(thisptr)->GetHomeWorld() ) { + if ( (*reinterpret_cast(reinterpret_cast(thisptr) + 0x108) & 0x03) && thisptr->GetHomeWorld() ) { vobHasMoved = (*reinterpret_cast(*reinterpret_cast(reinterpret_cast(thisptr) + 0x11C) + 0x88) & 0x03); } HookedFunctions::OriginalFunctions.original_zCVobEndMovement( thisptr, transformChanged_hint ); if ( Engine::GAPI && vobHasMoved && transformChanged_hint ) - Engine::GAPI->OnVobMoved( (zCVob*)thisptr ); + Engine::GAPI->OnVobMoved( thisptr ); hook_outfunc } #endif /** Called on destruction */ - static void __fastcall Hooked_Destructor( void* thisptr, void* unknwn ) { + static void __fastcall Hooked_Destructor( zCVob* thisptr, void* unknwn ) { hook_infunc // Notify the world. We are doing this here for safety so nothing possibly deleted remains in our world. if ( Engine::GAPI ) - Engine::GAPI->OnRemovedVob( (zCVob*)thisptr, ((zCVob*)thisptr)->GetHomeWorld() ); + Engine::GAPI->OnRemovedVob( thisptr, thisptr->GetHomeWorld() ); HookedFunctions::OriginalFunctions.original_zCVobDestructor( thisptr ); @@ -93,14 +93,14 @@ class zCVob { } /** Called when this vob is about to change the visual */ - static void __fastcall Hooked_SetVisual( void* thisptr, void* unknwn, zCVisual* visual ) { + static void __fastcall Hooked_SetVisual( zCVob* thisptr, void* unknwn, zCVisual* visual ) { hook_infunc HookedFunctions::OriginalFunctions.original_zCVobSetVisual( thisptr, visual ); // Notify the world if ( Engine::GAPI ) - Engine::GAPI->OnSetVisual( (zCVob*)thisptr ); + Engine::GAPI->OnSetVisual( thisptr ); hook_outfunc } diff --git a/D3D11Engine/zCWorld.h b/D3D11Engine/zCWorld.h index 6f571701..31240cc1 100644 --- a/D3D11Engine/zCWorld.h +++ b/D3D11Engine/zCWorld.h @@ -32,22 +32,22 @@ class zCWorld { XHook( HookedFunctions::OriginalFunctions.original_oCWorldRemoveVob, GothicMemoryLocations::oCWorld::RemoveVob, zCWorld::hooked_oCWorldRemoveVob ); } - static void __fastcall hooked_oCWorldEnableVob( void* thisptr, void* unknwn, zCVob* vob, zCVob* parent ) { + static void __fastcall hooked_oCWorldEnableVob( zCWorld* thisptr, void* unknwn, zCVob* vob, zCVob* parent ) { hook_infunc HookedFunctions::OriginalFunctions.original_oCWorldEnableVob( thisptr, vob, parent ); // Re-Add it - Engine::GAPI->OnAddVob( vob, (zCWorld*)thisptr ); + Engine::GAPI->OnAddVob( vob, thisptr ); hook_outfunc } - static void __fastcall hooked_oCWorldDisableVob( void* thisptr, void* unknwn, zCVob* vob ) { + static void __fastcall hooked_oCWorldDisableVob( zCWorld* thisptr, void* unknwn, zCVob* vob ) { hook_infunc // Remove it - Engine::GAPI->OnRemovedVob( vob, (zCWorld*)thisptr ); + Engine::GAPI->OnRemovedVob( vob, thisptr ); HookedFunctions::OriginalFunctions.original_oCWorldDisableVob( thisptr, vob ); hook_outfunc @@ -61,11 +61,11 @@ class zCWorld { hook_outfunc } - static void __fastcall hooked_oCWorldRemoveFromLists( void* thisptr, zCVob* vob ) { + static void __fastcall hooked_oCWorldRemoveFromLists( zCWorld* thisptr, zCVob* vob ) { hook_infunc // Remove it - Engine::GAPI->OnRemovedVob( vob, (zCWorld*)thisptr ); + Engine::GAPI->OnRemovedVob( vob, thisptr ); HookedFunctions::OriginalFunctions.original_oCWorldRemoveFromLists( thisptr, vob ); hook_outfunc @@ -76,24 +76,24 @@ class zCWorld { HookedFunctions::OriginalFunctions.original_zCWorldDisposeWorld( thisptr ); } - static void __fastcall hooked_zCWorldDisposeVobs( void* thisptr, void* unknwn, zCTree* tree ) { + static void __fastcall hooked_zCWorldDisposeVobs( zCWorld* thisptr, void* unknwn, zCTree* tree ) { // Reset only if this is the main world, inventory worlds are handled differently - if ( (zCWorld*)thisptr == Engine::GAPI->GetLoadedWorldInfo()->MainWorld ) + if ( thisptr == Engine::GAPI->GetLoadedWorldInfo()->MainWorld ) Engine::GAPI->ResetVobs(); HookedFunctions::OriginalFunctions.original_zCWorldDisposeVobs( thisptr, tree ); } - static void __fastcall hooked_zCWorldVobRemovedFromWorld( void* thisptr, void* unknwn, zCVob* vob ) { + static void __fastcall hooked_zCWorldVobRemovedFromWorld( zCWorld* thisptr, void* unknwn, zCVob* vob ) { hook_infunc // Remove it first, before it becomes invalid - Engine::GAPI->OnRemovedVob( vob, (zCWorld*)thisptr ); + Engine::GAPI->OnRemovedVob( vob, thisptr ); HookedFunctions::OriginalFunctions.original_zCWorldVobRemovedFromWorld( thisptr, vob ); hook_outfunc } - static void __fastcall hooked_LoadWorld( void* thisptr, void* unknwn, const zSTRING& fileName, const int loadMode ) { + static void __fastcall hooked_LoadWorld( zCWorld* thisptr, void* unknwn, const zSTRING& fileName, const int loadMode ) { //hook_infunc //LogInfo() << "Loading: " << fileName.ToChar(); @@ -104,7 +104,7 @@ class zCWorld { HookedFunctions::OriginalFunctions.original_zCWorldLoadWorld( thisptr, fileName, loadMode ); - Engine::GAPI->GetLoadedWorldInfo()->MainWorld = (zCWorld*)thisptr; + Engine::GAPI->GetLoadedWorldInfo()->MainWorld = thisptr; //LogInfo() << "Loaded world: " << fileName.ToChar(); @@ -112,20 +112,20 @@ class zCWorld { //hook_outfunc } - static void __fastcall hooked_VobAddedToWorld( void* thisptr, void* unknwn, zCVob* vob ) { + static void __fastcall hooked_VobAddedToWorld( zCWorld* thisptr, void* unknwn, zCVob* vob ) { hook_infunc HookedFunctions::OriginalFunctions.original_zCWorldVobAddedToWorld( thisptr, vob ); if ( vob->GetVisual() ) { //LogInfo() << vob->GetVisual()->GetFileExtension(0); - Engine::GAPI->OnAddVob( vob, (zCWorld*)thisptr ); + Engine::GAPI->OnAddVob( vob, thisptr ); } hook_outfunc } // Get around C2712 - static void Do_hooked_Render( void* thisptr, zCCamera& camera ) { + static void Do_hooked_Render( zCWorld* thisptr, zCCamera& camera ) { Engine::GAPI->SetTextureTestBindMode( false, "" ); //HookedFunctions::OriginalFunctions.original_zCWorldRender(thisptr, camera); @@ -155,11 +155,11 @@ class zCWorld { HookedFunctions::OriginalFunctions.original_zCWorldRender( thisptr, camera ); // Inventory - Engine::GAPI->DrawInventory( (zCWorld*)thisptr, camera ); + Engine::GAPI->DrawInventory( thisptr, camera ); } } - static void __fastcall hooked_Render( void* thisptr, void* unknwn, zCCamera& camera ) { + static void __fastcall hooked_Render( zCWorld* thisptr, void* unknwn, zCCamera& camera ) { hook_infunc Do_hooked_Render( thisptr, camera ); hook_outfunc From 6ba9f4af604c4d101c2f45db947d4978e921c8d7 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Tue, 14 Dec 2021 17:21:10 +0100 Subject: [PATCH 02/15] Fix occlusion culling dangling pointer crash --- D3D11Engine/D3D11GraphicsEngine.cpp | 5 +- D3D11Engine/D3D11OcclusionQuerry.cpp | 80 +++++++++------------------- 2 files changed, 29 insertions(+), 56 deletions(-) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index 87a5a4ba..95eec426 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -6238,8 +6238,11 @@ void D3D11GraphicsEngine::UpdateOcclusion() { // Do occlusiontests for the BSP-Tree Occlusion->DoOcclusionForBSP( Engine::GAPI->GetNewRootNode() ); - + Occlusion->EndOcclusionPass(); + + // Setup default renderstates + SetDefaultStates(); } /** Saves a screenshot */ diff --git a/D3D11Engine/D3D11OcclusionQuerry.cpp b/D3D11Engine/D3D11OcclusionQuerry.cpp index db550ba8..08da474c 100644 --- a/D3D11Engine/D3D11OcclusionQuerry.cpp +++ b/D3D11Engine/D3D11OcclusionQuerry.cpp @@ -27,7 +27,7 @@ unsigned int D3D11OcclusionQuerry::AddPredicationObject() { HRESULT hr; Microsoft::WRL::ComPtr p; - + // Create new predication-object D3D11_QUERY_DESC qd; qd.Query = D3D11_QUERY_OCCLUSION_PREDICATE; @@ -35,7 +35,7 @@ unsigned int D3D11OcclusionQuerry::AddPredicationObject() { LE( g->GetDevice()->CreatePredicate( &qd, p.GetAddressOf() ) ); // Add to the end of the list and return its ID - Predicates.push_back( p.Get() ); + Predicates.push_back( p.Detach() ); return Predicates.size() - 1; } @@ -55,13 +55,10 @@ void D3D11OcclusionQuerry::DoOcclusionForBSP( BspInfo* root ) { CreateOcclusionNodeMeshFor( root ); } - DirectX::XMFLOAT4 c = DirectX::XMFLOAT4( 1, 1, 1, 1 ); - // Check last frustum-culling state int clipFlags = 63; int fstate = zCCamera::GetCamera()->BBox3DInFrustum( root->OriginalNode->BBox3D, clipFlags ); - // If this node wasn't inside the frustum last frame, but got inside it this frame, just draw it // to reduce the popping in dialogs where the camera switches heavily between targets // This may introduce a little framedrop when the camera switches targets, but it has to be ok. @@ -87,7 +84,6 @@ void D3D11OcclusionQuerry::DoOcclusionForBSP( BspInfo* root ) { if ( !root->OcclusionInfo.VisibleLastFrame || (root->OcclusionInfo.LastVisitedFrameID + VISIBLE_RECHECK_FRAME_DELAY <= FrameID && root->OcclusionInfo.VisibleLastFrame) ) { - // Take those which have the camera inside as visible // Also make leafs which don't contain anything just visible so we can save the draw-call if ( Toolbox::PositionInsideBox( Engine::GAPI->GetCameraPosition(), root->OriginalNode->BBox3D.Min, root->OriginalNode->BBox3D.Max ) || @@ -99,58 +95,32 @@ void D3D11OcclusionQuerry::DoOcclusionForBSP( BspInfo* root ) { root->OcclusionInfo.LastVisitedFrameID = FrameID; return; } - - Microsoft::WRL::ComPtr p = Predicates[root->OcclusionInfo.QueryID]; - - // Check if there is data available from the last query - if ( root->OcclusionInfo.LastVisitedFrameID != 0 && // Always do the first query - S_OK != g->GetContext()->GetData( p.Get(), nullptr, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH ) ) { - c = DirectX::XMFLOAT4( 0, 0, 1, 1 ); - - // Query is in progress and still not done, wait for it... - if ( !root->OcclusionInfo.VisibleLastFrame ) { - // Continue with the sub-nodes to see if they are visible to make sure nothing pops in - // Don't continue with the sub-nodes if this was visible last time we checked - DoOcclusionForBSP( root->Front ); - DoOcclusionForBSP( root->Back ); - } + + ID3D11Predicate* p = Predicates[root->OcclusionInfo.QueryID]; + + // Query is done. Save the result! + UINT32 data = 0; + g->GetContext()->GetData( p, &data, sizeof( UINT32 ), D3D11_ASYNC_GETDATA_DONOTFLUSH ); + root->OcclusionInfo.VisibleLastFrame = (data > 0); // data contains visible pixels of the object + + if ( data == 0 ) { + // Mark entire subtree invisible and don't waste draw-calls for it + MarkTreeVisible( root->Front, false ); + MarkTreeVisible( root->Back, false ); } else { - // Query is done. Save the result! - UINT32 data; - g->GetContext()->GetData( p.Get(), &data, sizeof( UINT32 ), D3D11_ASYNC_GETDATA_DONOTFLUSH ); - root->OcclusionInfo.VisibleLastFrame = data > 0; // data contains visible pixels of the object - - if ( data == 0 ) { - // Mark entire subtree invisible and don't waste draw-calls for it - MarkTreeVisible( root->Front, false ); - MarkTreeVisible( root->Back, false ); - } else { - // Try to check the next nodes as well - DoOcclusionForBSP( root->Front ); - DoOcclusionForBSP( root->Back ); - } - - if ( data > 0 ) - c = DirectX::XMFLOAT4( 0, 1, 0, 1 ); - else - c = DirectX::XMFLOAT4( 1, 0, 0, 1 ); - - // Issue the new query - MeshInfo* mi = root->OcclusionInfo.NodeMesh; - - g->GetContext()->Begin( p.Get() ); - g->DrawVertexBufferIndexed( mi->MeshVertexBuffer, mi->MeshIndexBuffer, mi->Indices.size() ); - g->GetContext()->End( p.Get() ); + // Try to check the next nodes as well + DoOcclusionForBSP( root->Front ); + DoOcclusionForBSP( root->Back ); } - root->OcclusionInfo.LastVisitedFrameID = FrameID; - } + // Issue the new query + MeshInfo* mi = root->OcclusionInfo.NodeMesh; - if ( !Engine::GAPI->GetRendererState().RendererSettings.DisableWatermark && root->OriginalNode->IsLeaf() ) { - if ( !root->OcclusionInfo.VisibleLastFrame ) { - //DebugVisualizeNodeMesh(root->OcclusionInfo.NodeMesh, c); - Engine::GraphicsEngine->GetLineRenderer()->AddAABBMinMax( root->OriginalNode->BBox3D.Min, root->OriginalNode->BBox3D.Max, c ); - } + g->GetContext()->Begin( p ); + g->DrawVertexBufferIndexed( mi->MeshVertexBuffer, mi->MeshIndexBuffer, mi->Indices.size() ); + g->GetContext()->End( p ); + + root->OcclusionInfo.LastVisitedFrameID = FrameID; } } @@ -255,4 +225,4 @@ void D3D11OcclusionQuerry::MarkTreeVisible( BspInfo* root, bool visible ) { MarkTreeVisible( root->Front, visible ); MarkTreeVisible( root->Back, visible ); -} \ No newline at end of file +} From f1b3fe639f554a94e2021596f28fe13c2caddeda Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Tue, 14 Dec 2021 17:22:58 +0100 Subject: [PATCH 03/15] Fix possible crash at GothicAPI::OnVisualDeleted --- D3D11Engine/GothicAPI.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/D3D11Engine/GothicAPI.cpp b/D3D11Engine/GothicAPI.cpp index 2c60b90e..f2eff516 100644 --- a/D3D11Engine/GothicAPI.cpp +++ b/D3D11Engine/GothicAPI.cpp @@ -1313,18 +1313,11 @@ void GothicAPI::OnVisualDeleted( zCVisual* visual ) { } // Clear + std::list list = VobsByVisual[visual]; if ( _canClearVobsByVisual ) { - std::list list = VobsByVisual[visual]; for ( auto const& it : list ) { OnRemovedVob( it->Vob, LoadedWorldInfo->MainWorld ); } - if ( list.size() > 0 ) { - if ( RendererState.RendererSettings.EnableDebugLog ) - LogInfo() << std::string( className ) << " had " + std::to_string( list.size() ) << " vobs"; - - VobsByVisual[visual].clear(); - VobsByVisual.erase( visual ); - } } else { // TODO: #8 - Figure out why exactly we don't get notified that a VOB is re-added after being removed. /*oCNPC* npcVob; @@ -1337,6 +1330,13 @@ void GothicAPI::OnVisualDeleted( zCVisual* visual ) { } }*/ } + if ( list.size() > 0 ) { + if ( RendererState.RendererSettings.EnableDebugLog ) + LogInfo() << std::string( className ) << " had " + std::to_string( list.size() ) << " vobs"; + + VobsByVisual[visual].clear(); + VobsByVisual.erase( visual ); + } } /** Draws a MeshInfo */ void GothicAPI::DrawMeshInfo( zCMaterial* mat, MeshInfo* msh ) { From 4b6a436e226b5f077e52a015441290862738e318 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Tue, 14 Dec 2021 17:31:22 +0100 Subject: [PATCH 04/15] Optimize a little file reads --- D3D11Engine/GothicAPI.cpp | 26 +++++++++++++++++--------- D3D11Engine/GothicAPI.h | 4 ++-- D3D11Engine/WorldObjects.cpp | 9 ++++----- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/D3D11Engine/GothicAPI.cpp b/D3D11Engine/GothicAPI.cpp index f2eff516..7e7de5bf 100644 --- a/D3D11Engine/GothicAPI.cpp +++ b/D3D11Engine/GothicAPI.cpp @@ -79,13 +79,16 @@ void MaterialInfo::LoadFromFile( const std::string& name ) { if ( !f ) return; + char ReadBuffer[sizeof( int ) + sizeof( MaterialInfo::Buffer ) + sizeof( VisualTesselationSettings::Buffer )]; + fread( ReadBuffer, 1, sizeof( ReadBuffer ), f ); + // Write the version first int version; - fread( &version, sizeof( int ), 1, f ); + memcpy( &version, ReadBuffer, sizeof( int ) ); // Then the data ZeroMemory( &buffer, sizeof( MaterialInfo::Buffer ) ); - fread( &buffer, sizeof( MaterialInfo::Buffer ), 1, f ); + memcpy( &buffer, ReadBuffer + sizeof( int ), sizeof( MaterialInfo::Buffer ) ); if ( version < 2 ) { if ( buffer.DisplacementFactor == 0.0f ) { @@ -94,7 +97,7 @@ void MaterialInfo::LoadFromFile( const std::string& name ) { } if ( version >= 4 ) { - fread( &TextureTesselationSettings.buffer, sizeof( VisualTesselationSettings::Buffer ), 1, f ); + memcpy( &TextureTesselationSettings.buffer, ReadBuffer + sizeof( int ) + sizeof( MaterialInfo::Buffer ), sizeof( VisualTesselationSettings::Buffer ) ); } fclose( f ); @@ -1373,7 +1376,7 @@ void GothicAPI::OnRemovedVob( zCVob* vob, zCWorld* world ) { //LogInfo() << "Removing vob: " << vob; Engine::GraphicsEngine->OnVobRemovedFromWorld( vob ); - std::set::iterator it = RegisteredVobs.find( vob ); + auto it = RegisteredVobs.find( vob ); if ( it == RegisteredVobs.end() ) { // Not registered return; @@ -1831,6 +1834,11 @@ void GothicAPI::DrawSkeletalMeshVob( SkeletalVobInfo* vi, float distance, bool u if ( !((SkeletalMeshVisualInfo*)vi->VisualInfo)->SkeletalMeshes.empty() ) { Engine::GraphicsEngine->DrawSkeletalMesh( vi, transforms, modelColor, fatness ); + } else { + if ( model->GetMeshSoftSkinList()->NumInArray > 0 ) { + // Just in case somehow we end up without skeletal meshes and they are available + WorldConverter::ExtractSkeletalMeshFromVob( model, (SkeletalMeshVisualInfo*)vi->VisualInfo ); + } } if ( g->GetRenderingStage() == DES_SHADOWMAP_CUBE ) @@ -2606,7 +2614,7 @@ DirectX::XMFLOAT4X4& GothicAPI::GetProjectionMatrix() { // Reverse depth buffer float NearZ = RendererState.RendererSettings.SectionDrawRadius * WORLD_SECTION_SIZE; - float FarZ = 0.001f; + float FarZ = 1.0f; float zRange = FarZ / (FarZ - NearZ); RendererState.TransformState.TransformProj._33 = zRange; RendererState.TransformState.TransformProj._34 = -zRange * NearZ; @@ -3219,7 +3227,7 @@ void GothicAPI::CollectVisibleVobsHelper( BspInfo* base, zTBBox3D boxCell, int c } VobLightInfo* vi = vit->second; - if ( !vi->VisibleInRenderPass && vi->Vob->IsEnabled() /*&& vi->Vob->GetShowVisual()*/ ) { + if ( !vi->VisibleInRenderPass && vob->IsEnabled() /*&& vob->GetShowVisual()*/ ) { vi->VisibleInRenderPass = true; // Update the lights shadows if: Light is dynamic or full shadow-updates are set @@ -3227,7 +3235,7 @@ void GothicAPI::CollectVisibleVobsHelper( BspInfo* base, zTBBox3D boxCell, int c || (RendererState.RendererSettings.EnablePointlightShadows >= GothicRendererSettings::PLS_UPDATE_DYNAMIC && !vob->IsStatic()) ) { // Now check for distances, etc float lightPlayerDist; - XMStoreFloat( &lightPlayerDist, DirectX::XMVector3Length( playerPosition - leaf->LightVobList.Array[i]->GetPositionWorldXM() ) ); + XMStoreFloat( &lightPlayerDist, DirectX::XMVector3Length( playerPosition - vob->GetPositionWorldXM() ) ); if ( vob->GetLightRange() > minDynamicUpdateLightRange && lightPlayerDist < vob->GetLightRange() * 1.5f ) vi->UpdateShadows = true; } @@ -3473,8 +3481,8 @@ void GothicAPI::ResetMaterialInfo() { /** Returns the material info associated with the given material */ MaterialInfo* GothicAPI::GetMaterialInfoFrom( zCTexture* tex ) { - std::unordered_map::iterator f = MaterialInfos.find( tex ); - if ( f == MaterialInfos.end() && tex ) { + auto it = MaterialInfos.find( tex ); + if ( it == MaterialInfos.end() && tex ) { // Make a new one and try to load it MaterialInfos[tex].LoadFromFile( tex->GetNameWithoutExt() ); } diff --git a/D3D11Engine/GothicAPI.h b/D3D11Engine/GothicAPI.h index 49dc99dc..19ebe012 100644 --- a/D3D11Engine/GothicAPI.h +++ b/D3D11Engine/GothicAPI.h @@ -28,7 +28,7 @@ struct BspInfo { OcclusionInfo.LastVisitedFrameID = 0; OcclusionInfo.QueryID = -1; OcclusionInfo.QueryInProgress = false; - OcclusionInfo.LastCameraClipType = 0; + OcclusionInfo.LastCameraClipType = ZTCAM_CLIPTYPE_OUT; OcclusionInfo.NodeMesh = nullptr; } @@ -748,7 +748,7 @@ class GothicAPI { std::unordered_map SkeletalMeshVisuals; /** Set of all vobs we registered by now */ - std::set RegisteredVobs; + std::unordered_set RegisteredVobs; /** List of dynamically added vobs */ std::list DynamicallyAddedVobs; diff --git a/D3D11Engine/WorldObjects.cpp b/D3D11Engine/WorldObjects.cpp index df8ab62a..277ffc3d 100644 --- a/D3D11Engine/WorldObjects.cpp +++ b/D3D11Engine/WorldObjects.cpp @@ -180,12 +180,11 @@ void BaseVisualInfo::LoadMeshVisualInfo( const std::string& name ) { return; } - // Read the version first - int version; - fread( &version, sizeof( version ), 1, f ); + char ReadBuffer[sizeof( int ) + sizeof( TesselationInfo )]; + fread( ReadBuffer, 1, sizeof( ReadBuffer ), f ); - // Then the TesselationInfo - fread( &TesselationInfo.buffer, sizeof( TesselationInfo ), 1, f ); + // Read the TesselationInfo + memcpy( &TesselationInfo.buffer, ReadBuffer + sizeof( int ), sizeof( TesselationInfo ) ); TesselationInfo.TesselationShader = Toolbox::LoadStringFromFILE( f ); TesselationInfo.UpdateConstantbuffer(); From 300f39c316f6f83393d7db670012e9b0dde01175 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Tue, 14 Dec 2021 17:37:18 +0100 Subject: [PATCH 05/15] 17.8-dev2 --- D3D11Engine/VersionCheck.cpp | 5 +++- D3D11Engine/pch.h | 2 +- Launcher/Launcher.vcxproj | 2 +- Launcher/ddraw.def | 14 +++++++++- Launcher/dllmain.cpp | 53 +++++++++++++++++++++++++++++++++++- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/D3D11Engine/VersionCheck.cpp b/D3D11Engine/VersionCheck.cpp index ac476dcb..065650b1 100644 --- a/D3D11Engine/VersionCheck.cpp +++ b/D3D11Engine/VersionCheck.cpp @@ -8,6 +8,8 @@ #include "Logger.h" +//#define DISABLE_EXECUTABLE_CHECKSUM_CHECK + namespace VersionCheck { static const int CHECKSUM_G2_2_6_FIX = 0x008a3e89; @@ -28,6 +30,7 @@ namespace VersionCheck { /** Checks the executable checksum for the right version */ void CheckExecutable() { +#ifndef DISABLE_EXECUTABLE_CHECKSUM_CHECK // Get checksum from header DWORD checksum; DWORD headersum; @@ -86,6 +89,7 @@ namespace VersionCheck { LogInfoBox() << "You are using the Gothic 1 version of GD3D11. This is not an official release, so please keep that in mind!\n" "Not everything is working yet and it may crash frequently. You don't need to report every bug you see, because I likely have seen it myself by now.\n"; #endif*/ +#endif #endif // Check for game data @@ -99,5 +103,4 @@ namespace VersionCheck { exit( 0 ); } } - } diff --git a/D3D11Engine/pch.h b/D3D11Engine/pch.h index 51a1d5cf..c3b06097 100644 --- a/D3D11Engine/pch.h +++ b/D3D11Engine/pch.h @@ -27,7 +27,7 @@ #define stdext std #endif -#define VERSION_NUMBER "17.8-dev1" +#define VERSION_NUMBER "17.8-dev2" __declspec(selectany) const char* VERSION_NUMBER_STR = VERSION_NUMBER; extern bool FeatureLevel10Compatibility; diff --git a/Launcher/Launcher.vcxproj b/Launcher/Launcher.vcxproj index 1f70a465..497253ed 100644 --- a/Launcher/Launcher.vcxproj +++ b/Launcher/Launcher.vcxproj @@ -45,7 +45,7 @@ NotUsing pch.h true - MultiThreaded + MultiThreadedDLL NoExtensions Fast stdcpp17 diff --git a/Launcher/ddraw.def b/Launcher/ddraw.def index bc0761e7..3fc16816 100644 --- a/Launcher/ddraw.def +++ b/Launcher/ddraw.def @@ -21,4 +21,16 @@ EXPORTS GetOLEThunkData = FakeGetOLEThunkData @19 GetSurfaceFromDC = FakeGetSurfaceFromDC @20 RegisterSpecialCase = FakeRegisterSpecialCase @21 - ReleaseDDThreadLock = FakeReleaseDDThreadLock @22 \ No newline at end of file + ReleaseDDThreadLock = FakeReleaseDDThreadLock @22 + GDX_AddPointLocator = FakeGDX_AddPointLocator @23 + GDX_SetFogColor = FakeGDX_SetFogColor @24 + GDX_SetFogDensity = FakeGDX_SetFogDensity @25 + GDX_SetFogHeight = FakeGDX_SetFogHeight @26 + GDX_SetFogHeightFalloff = FakeGDX_SetFogHeightFalloff @27 + GDX_SetSunColor = FakeGDX_SetSunColor @28 + GDX_SetSunStrength = FakeGDX_SetSunStrength @29 + GDX_SetShadowStrength = FakeGDX_SetShadowStrength @30 + GDX_SetShadowAOStrength = FakeGDX_SetShadowAOStrength @31 + GDX_SetWorldAOStrength = FakeGDX_SetWorldAOStrength @32 + GDX_OpenMessageBox = FakeGDX_OpenMessageBox @33 + GDX_Module = FakeGDX_Module @34 \ No newline at end of file diff --git a/Launcher/dllmain.cpp b/Launcher/dllmain.cpp index 18f13504..bc7d8417 100644 --- a/Launcher/dllmain.cpp +++ b/Launcher/dllmain.cpp @@ -31,6 +31,18 @@ struct ddraw_dll { FARPROC GetSurfaceFromDC; FARPROC RegisterSpecialCase; FARPROC ReleaseDDThreadLock; + + FARPROC GDX_AddPointLocator; + FARPROC GDX_SetFogColor; + FARPROC GDX_SetFogDensity; + FARPROC GDX_SetFogHeight; + FARPROC GDX_SetFogHeightFalloff; + FARPROC GDX_SetSunColor; + FARPROC GDX_SetSunStrength; + FARPROC GDX_SetShadowStrength; + FARPROC GDX_SetShadowAOStrength; + FARPROC GDX_SetWorldAOStrength; + FARPROC GDX_OpenMessageBox; } ddraw; __declspec(naked) void FakeAcquireDDThreadLock() { _asm { jmp[ddraw.AcquireDDThreadLock] } } @@ -56,6 +68,22 @@ __declspec(naked) void FakeGetSurfaceFromDC() { _asm { jmp[ddraw.GetSurfaceFromD __declspec(naked) void FakeRegisterSpecialCase() { _asm { jmp[ddraw.RegisterSpecialCase] } } __declspec(naked) void FakeReleaseDDThreadLock() { _asm { jmp[ddraw.ReleaseDDThreadLock] } } +__declspec(naked) void FakeGDX_AddPointLocator() { _asm { jmp[ddraw.GDX_AddPointLocator] } } +__declspec(naked) void FakeGDX_SetFogColor() { _asm { jmp[ddraw.GDX_SetFogColor] } } +__declspec(naked) void FakeGDX_SetFogDensity() { _asm { jmp[ddraw.GDX_SetFogDensity] } } +__declspec(naked) void FakeGDX_SetFogHeight() { _asm { jmp[ddraw.GDX_SetFogHeight] } } +__declspec(naked) void FakeGDX_SetFogHeightFalloff() { _asm { jmp[ddraw.GDX_SetFogHeightFalloff] } } +__declspec(naked) void FakeGDX_SetSunColor() { _asm { jmp[ddraw.GDX_SetSunColor] } } +__declspec(naked) void FakeGDX_SetSunStrength() { _asm { jmp[ddraw.GDX_SetSunStrength] } } +__declspec(naked) void FakeGDX_SetShadowStrength() { _asm { jmp[ddraw.GDX_SetShadowStrength] } } +__declspec(naked) void FakeGDX_SetShadowAOStrength() { _asm { jmp[ddraw.GDX_SetShadowAOStrength] } } +__declspec(naked) void FakeGDX_SetWorldAOStrength() { _asm { jmp[ddraw.GDX_SetWorldAOStrength] } } +__declspec(naked) void FakeGDX_OpenMessageBox() { _asm { jmp[ddraw.GDX_OpenMessageBox] } } + +extern "C" HMODULE WINAPI FakeGDX_Module() { + return ddraw.dll; +} + BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID ) { if ( reason == DLL_PROCESS_ATTACH ) { int foundExecutable = INVALID_EXECUTABLE; @@ -135,6 +163,7 @@ BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID ) { PathRemoveFileSpecA( executablePath ); ddraw.dll = nullptr; + bool showLoadingInfo = true; switch ( foundExecutable ) { case GOTHIC2A_EXECUTABLE: { if ( haveAVX2 && !ddraw.dll ) { @@ -199,10 +228,20 @@ BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID ) { } } break; + + default: { + MessageBoxA( nullptr, "GD3D11 Renderer doesn't work with your Gothic executable.", "Gothic GD3D11", MB_ICONERROR ); + showLoadingInfo = false; + } + break; } if ( !ddraw.dll ) { - MessageBoxA( nullptr, "GD3D11 Renderer doesn't work with your Gothic executable.", "Gothic GD3D11", MB_ICONERROR ); + if ( showLoadingInfo ) { + char buffer[32]; + sprintf_s(buffer, "0x%x", GetLastError()); + MessageBoxA( nullptr, (std::string( "GD3D11 Renderer couldn't be loaded.\nAccess Denied(" ) + std::string( buffer ) + std::string( ")." )).c_str(), "Gothic GD3D11", MB_ICONERROR ); + } char ddrawPath[MAX_PATH]; GetSystemDirectoryA( ddrawPath, MAX_PATH ); @@ -234,6 +273,18 @@ BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID ) { ddraw.GetSurfaceFromDC = GetProcAddress( ddraw.dll, "GetSurfaceFromDC" ); ddraw.RegisterSpecialCase = GetProcAddress( ddraw.dll, "RegisterSpecialCase" ); ddraw.ReleaseDDThreadLock = GetProcAddress( ddraw.dll, "ReleaseDDThreadLock" ); + + ddraw.GDX_AddPointLocator = GetProcAddress( ddraw.dll, "GDX_AddPointLocator" ); + ddraw.GDX_SetFogColor = GetProcAddress( ddraw.dll, "GDX_SetFogColor" ); + ddraw.GDX_SetFogDensity = GetProcAddress( ddraw.dll, "GDX_SetFogDensity" ); + ddraw.GDX_SetFogHeight = GetProcAddress( ddraw.dll, "GDX_SetFogHeight" ); + ddraw.GDX_SetFogHeightFalloff = GetProcAddress( ddraw.dll, "GDX_SetFogHeightFalloff" ); + ddraw.GDX_SetSunColor = GetProcAddress( ddraw.dll, "GDX_SetSunColor" ); + ddraw.GDX_SetSunStrength = GetProcAddress( ddraw.dll, "GDX_SetSunStrength" ); + ddraw.GDX_SetShadowStrength = GetProcAddress( ddraw.dll, "GDX_SetShadowStrength" ); + ddraw.GDX_SetShadowAOStrength = GetProcAddress( ddraw.dll, "GDX_SetShadowAOStrength" ); + ddraw.GDX_SetWorldAOStrength = GetProcAddress( ddraw.dll, "GDX_SetWorldAOStrength" ); + ddraw.GDX_OpenMessageBox = GetProcAddress( ddraw.dll, "GDX_OpenMessageBox" ); } else if ( reason == DLL_PROCESS_DETACH ) { FreeLibrary( ddraw.dll ); } From 9e742347054fc4e45fa804e6da86c7b4cf1e08be Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Thu, 16 Dec 2021 23:03:31 +0100 Subject: [PATCH 06/15] Don't issue new occlusion query when old still haven't finished --- D3D11Engine/D3D11OcclusionQuerry.cpp | 35 ++++++++++++++++++---------- D3D11Engine/GothicAPI.h | 6 ++--- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/D3D11Engine/D3D11OcclusionQuerry.cpp b/D3D11Engine/D3D11OcclusionQuerry.cpp index 08da474c..186947ef 100644 --- a/D3D11Engine/D3D11OcclusionQuerry.cpp +++ b/D3D11Engine/D3D11OcclusionQuerry.cpp @@ -100,25 +100,36 @@ void D3D11OcclusionQuerry::DoOcclusionForBSP( BspInfo* root ) { // Query is done. Save the result! UINT32 data = 0; - g->GetContext()->GetData( p, &data, sizeof( UINT32 ), D3D11_ASYNC_GETDATA_DONOTFLUSH ); - root->OcclusionInfo.VisibleLastFrame = (data > 0); // data contains visible pixels of the object - - if ( data == 0 ) { - // Mark entire subtree invisible and don't waste draw-calls for it - MarkTreeVisible( root->Front, false ); - MarkTreeVisible( root->Back, false ); + if ( g->GetContext()->GetData( p, &data, sizeof( UINT32 ), D3D11_ASYNC_GETDATA_DONOTFLUSH ) == S_OK ) { + root->OcclusionInfo.VisibleLastFrame = (data > 0); // data contains visible pixels of the object + + if ( data == 0 ) { + // Mark entire subtree invisible and don't waste draw-calls for it + MarkTreeVisible( root->Front, false ); + MarkTreeVisible( root->Back, false ); + } else { + // Try to check the next nodes as well + DoOcclusionForBSP( root->Front ); + DoOcclusionForBSP( root->Back ); + } + + root->OcclusionInfo.QueryInProgress = false; } else { // Try to check the next nodes as well DoOcclusionForBSP( root->Front ); DoOcclusionForBSP( root->Back ); } - // Issue the new query - MeshInfo* mi = root->OcclusionInfo.NodeMesh; + if ( !root->OcclusionInfo.QueryInProgress ) { + // Issue the new query + MeshInfo* mi = root->OcclusionInfo.NodeMesh; + + g->GetContext()->Begin( p ); + g->DrawVertexBufferIndexed( mi->MeshVertexBuffer, mi->MeshIndexBuffer, mi->Indices.size() ); + g->GetContext()->End( p ); - g->GetContext()->Begin( p ); - g->DrawVertexBufferIndexed( mi->MeshVertexBuffer, mi->MeshIndexBuffer, mi->Indices.size() ); - g->GetContext()->End( p ); + root->OcclusionInfo.QueryInProgress = true; + } root->OcclusionInfo.LastVisitedFrameID = FrameID; } diff --git a/D3D11Engine/GothicAPI.h b/D3D11Engine/GothicAPI.h index 19ebe012..77baf8a8 100644 --- a/D3D11Engine/GothicAPI.h +++ b/D3D11Engine/GothicAPI.h @@ -55,12 +55,12 @@ struct BspInfo { /** Occlusion info for this node */ struct OcclusionInfo_s { + MeshInfo* NodeMesh; unsigned int LastVisitedFrameID; - bool VisibleLastFrame; + int LastCameraClipType; int QueryID; + bool VisibleLastFrame; bool QueryInProgress; - MeshInfo* NodeMesh; - int LastCameraClipType; } OcclusionInfo; // Original bsp-node From c1316981831ce4fad96709820255b5671cbed38c Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Thu, 16 Dec 2021 23:06:38 +0100 Subject: [PATCH 07/15] Fix DXVK crashing at device creation --- D3D11Engine/D3D11GraphicsEngine.cpp | 78 ++++++++++++----------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index 95eec426..ea278171 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -109,37 +109,6 @@ D3D11GraphicsEngine::~D3D11GraphicsEngine() { // MemTrackerFinalReport(); } -HRESULT CheckD3D11FeatureLevel( D3D_FEATURE_LEVEL* maxFeatureLevel ) { - D3D_FEATURE_LEVEL featureLevels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1 - }; - - *maxFeatureLevel = D3D_FEATURE_LEVEL_9_1; - - // Check featurelevel - - HRESULT hr = D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, - featureLevels, ARRAYSIZE( featureLevels ), D3D11_SDK_VERSION, nullptr, maxFeatureLevel, nullptr ); - // Assume E_INVALIDARG occurs because D3D_FEATURE_LEVEL_11_1 is not supported on current platform - // retry with just 9.1-11.0 - if ( hr == E_INVALIDARG ) { - hr = D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, - &featureLevels[1], ARRAYSIZE( featureLevels ) - 1, D3D11_SDK_VERSION, nullptr, maxFeatureLevel, nullptr ); - } - - if ( FAILED( hr ) ) { - return hr; - } - - return hr; -} - void PrintD3DFeatureLevel( D3D_FEATURE_LEVEL lvl ) { std::map dxFeatureLevelsMap = { {D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_1, "D3D_FEATURE_LEVEL_11_1"}, @@ -227,11 +196,36 @@ XRESULT D3D11GraphicsEngine::Init() { LogInfo() << "Rendering on: " << deviceDescription.c_str(); D3D_FEATURE_LEVEL maxFeatureLevel = D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_9_1; - if ( FAILED( hr = CheckD3D11FeatureLevel( &maxFeatureLevel ) ) ) { - LogInfo() << "Could not determine D3D_FEATURE_LEVEL"; - } else { - PrintD3DFeatureLevel( maxFeatureLevel ); + D3D_FEATURE_LEVEL featureLevels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; + + // Create D3D11-Device + int flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; +#ifdef DEBUG_D3D11 + flags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + hr = D3D11CreateDevice( DXGIAdapter2.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, flags, featureLevels, ARRAYSIZE( featureLevels ), + D3D11_SDK_VERSION, Device11.GetAddressOf(), &maxFeatureLevel, Context11.GetAddressOf() ); + // Assume E_INVALIDARG occurs because D3D_FEATURE_LEVEL_11_1 is not supported on current platform + // retry with just 9.1-11.0 + if ( hr == E_INVALIDARG ) { + hr = D3D11CreateDevice( DXGIAdapter2.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, flags, &featureLevels[1], ARRAYSIZE( featureLevels ) - 1, + D3D11_SDK_VERSION, Device11.GetAddressOf(), &maxFeatureLevel, Context11.GetAddressOf() ); + } + if ( FAILED( hr ) ) { + LE( hr ); + exit( 2 ); } + + PrintD3DFeatureLevel( maxFeatureLevel ); if ( maxFeatureLevel < D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_10_0 ) { LogErrorBox() << "Your GPU (" << deviceDescription.c_str() << ") does not support Direct3D 11, so it can't run GD3D11!\n" @@ -243,13 +237,6 @@ XRESULT D3D11GraphicsEngine::Init() { exit( 2 ); } - // Create D3D11-Device - int flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; -#ifndef DEBUG_D3D11 - LE( D3D11CreateDevice( DXGIAdapter2.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, flags, &maxFeatureLevel, 1, D3D11_SDK_VERSION, Device11.GetAddressOf(), nullptr, Context11.GetAddressOf() ) ); -#else - LE( D3D11CreateDevice( DXGIAdapter2.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, flags | D3D11_CREATE_DEVICE_DEBUG, &maxFeatureLevel, 1, D3D11_SDK_VERSION, Device11.GetAddressOf(), nullptr, Context11.GetAddressOf() ) ); -#endif Device11.As( &Device ); Context11.As( &Context ); @@ -1087,7 +1074,7 @@ XRESULT D3D11GraphicsEngine::FetchDisplayModeList() { UINT numModes = 0; hr = output->GetDisplayModeList1( DXGI_FORMAT_R8G8B8A8_UNORM, 0, &numModes, nullptr ); - if ( FAILED( hr ) ) { + if ( FAILED( hr ) || numModes == 0 ) { CachedDisplayModes.emplace_back( Resolution.x, Resolution.y ); return XR_FAILED; } @@ -1099,7 +1086,8 @@ XRESULT D3D11GraphicsEngine::FetchDisplayModeList() { return XR_FAILED; } - DEVMODEA devMode; + DEVMODEA devMode = {}; + devMode.dmSize = sizeof( DEVMODEA ); DWORD currentRefreshRate = 0; if ( EnumDisplaySettingsA( nullptr, ENUM_CURRENT_SETTINGS, &devMode ) ) { currentRefreshRate = devMode.dmDisplayFrequency; @@ -1109,7 +1097,7 @@ XRESULT D3D11GraphicsEngine::FetchDisplayModeList() { DXGI_MODE_DESC1& displayMode = displayModes[i]; if ( static_cast(Resolution.x) == displayMode.Width && static_cast(Resolution.y) == displayMode.Height ) { DWORD displayRefreshRate = static_cast(displayMode.RefreshRate.Numerator / displayMode.RefreshRate.Denominator); - if ( (displayRefreshRate - 2) >= currentRefreshRate && (displayRefreshRate + 2) <= currentRefreshRate ) { + if ( currentRefreshRate >= (displayRefreshRate - 2) && currentRefreshRate <= (displayRefreshRate + 2) ) { CachedRefreshRate.Numerator = displayMode.RefreshRate.Numerator; CachedRefreshRate.Denominator = displayMode.RefreshRate.Denominator; } From ae762dc5c743d3314e29afd1feac9a07e418c329 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Fri, 17 Dec 2021 22:42:48 +0100 Subject: [PATCH 08/15] Fix GD3DX7 Z-buffer destruction possible crash --- D3D11Engine/HookedFunctions.cpp | 9 +++++++++ D3D11Engine/pch.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/D3D11Engine/HookedFunctions.cpp b/D3D11Engine/HookedFunctions.cpp index 5eb8db2e..f34aa34a 100644 --- a/D3D11Engine/HookedFunctions.cpp +++ b/D3D11Engine/HookedFunctions.cpp @@ -89,6 +89,9 @@ void HookedFunctionInfo::InitHooks() { LogInfo() << "Patching: Disable dx7 window transitions"; PatchAddr( 0x0075CA7B, "\x90\x90" ); PatchAddr( 0x0074DAD0, "\x90\x90" ); + + LogInfo() << "Patching: Fix dx7 zbuffer possible crash"; + PatchAddr( 0x007A4B08, "\xB8\x00\x00\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90\x90" ); #else LogInfo() << "Patching: BroadCast fix"; { @@ -139,6 +142,9 @@ void HookedFunctionInfo::InitHooks() { PatchAddr( 0x0072018B, "\x90\x90" ); PatchAddr( 0x00711F70, "\x90\x90" ); + LogInfo() << "Patching: Fix dx7 zbuffer possible crash"; + PatchAddr( 0x0075F907, "\xB8\x00\x00\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90\x90" ); + LogInfo() << "Patching: Show correct tris on toggle frame"; { char* trisHndl[5]; @@ -239,6 +245,9 @@ void HookedFunctionInfo::InitHooks() { PatchAddr( 0x00658BCB, "\x90\x90" ); PatchAddr( 0x006483A2, "\x90\x90" ); + LogInfo() << "Patching: Fix dx7 zbuffer possible crash"; + PatchAddr( 0x007B8FFB, "\xB8\x00\x00\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90\x90" ); + LogInfo() << "Patching: Show correct tris on toggle frame"; { char* trisHndl[5]; diff --git a/D3D11Engine/pch.h b/D3D11Engine/pch.h index c3b06097..e1d9f728 100644 --- a/D3D11Engine/pch.h +++ b/D3D11Engine/pch.h @@ -27,7 +27,7 @@ #define stdext std #endif -#define VERSION_NUMBER "17.8-dev2" +#define VERSION_NUMBER "17.8-dev2-fix2" __declspec(selectany) const char* VERSION_NUMBER_STR = VERSION_NUMBER; extern bool FeatureLevel10Compatibility; From d52908c3ff4f163a2deba30e84091c823314395e Mon Sep 17 00:00:00 2001 From: proxin Date: Wed, 22 Dec 2021 16:38:00 +0300 Subject: [PATCH 09/15] Fixes for SPACER_NET Fixes for SPACER_NET --- D3D11Engine/D3D11GraphicsEngine.cpp | 9 +++++---- D3D11Engine/GothicAPI.cpp | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index ea278171..ab62d609 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -472,9 +472,10 @@ XRESULT D3D11GraphicsEngine::SetWindow( HWND hWnd ) { // We need to update clip cursor here because we hook the window too late to receive proper window message UpdateClipCursor( hWnd ); - +#ifndef BUILD_SPACER_NET // Force hide mouse cursor while ( ShowCursor( false ) >= 0 ); +#endif } return XR_SUCCESS; @@ -3954,13 +3955,13 @@ XRESULT D3D11GraphicsEngine::DrawVOBsInstanced() { if ( showHelpers ) { WhiteTexture->BindToPixelShader( 0 ); - PS_Diffuse->Apply(); + PS_DiffuseAlphatest->Apply(); MaterialInfo::Buffer b = {}; b.Color = itt.first.Material->GetColor(); - PS_Diffuse->GetConstantBuffer()[2]->UpdateBuffer( &b ); - PS_Diffuse->GetConstantBuffer()[2]->BindToPixelShader( 2 ); + PS_DiffuseAlphatest->GetConstantBuffer()[2]->UpdateBuffer( &b ); + PS_DiffuseAlphatest->GetConstantBuffer()[2]->BindToPixelShader( 2 ); } else { continue; diff --git a/D3D11Engine/GothicAPI.cpp b/D3D11Engine/GothicAPI.cpp index 7e7de5bf..2b9dbabf 100644 --- a/D3D11Engine/GothicAPI.cpp +++ b/D3D11Engine/GothicAPI.cpp @@ -422,6 +422,7 @@ void GothicAPI::SetEnableGothicInput( bool value ) { } #ifndef BUILD_SPACER +#ifndef BUILD_SPACER_NET // zMouse, false input->SetDeviceEnabled( 2, value ? 1 : 0 ); input->SetDeviceEnabled( 1, value ? 1 : 0 ); @@ -469,6 +470,7 @@ void GothicAPI::SetEnableGothicInput( bool value ) { #endif*/ #endif +#endif } From 025e96fad10535fda5ffc2deeb29c2a74734a9d9 Mon Sep 17 00:00:00 2001 From: proxin Date: Wed, 22 Dec 2021 16:42:41 +0300 Subject: [PATCH 10/15] Fix SPACER_NET mouse Fix SPACER_NET mouse clip --- D3D11Engine/D3D11GraphicsEngine.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index ab62d609..ad3571dc 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -470,9 +470,12 @@ XRESULT D3D11GraphicsEngine::SetWindow( HWND hWnd ) { #endif if ( res.x != 0 && res.y != 0 ) OnResize( res ); + +#ifndef BUILD_SPACER_NET + // We need to update clip cursor here because we hook the window too late to receive proper window message UpdateClipCursor( hWnd ); -#ifndef BUILD_SPACER_NET + // Force hide mouse cursor while ( ShowCursor( false ) >= 0 ); #endif From 3bb1bd935be73430d991cd4a9ab2d51a73f27916 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Thu, 23 Dec 2021 05:30:47 +0100 Subject: [PATCH 11/15] Fixes -Fix dynamic shadows in indoor locations like sewers -Fix corrupted savegame thumbnails -Fix crash when loading corrupted setting files -Improve display resolutions detection --- D3D11Engine/D3D11GraphicsEngine.cpp | 68 ++++++++++++++++++--- D3D11Engine/D3D11GraphicsEngine.h | 2 + D3D11Engine/D3D11GraphicsEngineBase.h | 2 + D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp | 1 - D3D11Engine/D3D7/MyDirectDrawSurface7.cpp | 6 +- D3D11Engine/GothicAPI.cpp | 7 ++- D3D11Engine/HookedFunctions.cpp | 21 +++++++ D3D11Engine/Shaders/VS_PNAEN_Skeletal.hlsl | 32 ++++++---- D3D11Engine/pch.h | 2 +- 9 files changed, 114 insertions(+), 27 deletions(-) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index ad3571dc..e1774017 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -470,7 +470,6 @@ XRESULT D3D11GraphicsEngine::SetWindow( HWND hWnd ) { #endif if ( res.x != 0 && res.y != 0 ) OnResize( res ); - #ifndef BUILD_SPACER_NET // We need to update clip cursor here because we hook the window too late to receive proper window message @@ -1061,6 +1060,24 @@ XRESULT D3D11GraphicsEngine::CreateConstantBuffer( D3D11ConstantBuffer** outCB, /** Fetches a list of available display modes */ XRESULT D3D11GraphicsEngine::FetchDisplayModeList() { +#pragma warning(push) +#pragma warning(disable: 6320) + // First try to get display resolutions through DXGI + // if it for some reason fails get resolutions through WinApi + __try { + XRESULT result = FetchDisplayModeListDXGI(); + if ( result == XR_FAILED || CachedDisplayModes.size() <= 1 ) { + CachedDisplayModes.clear(); + result = FetchDisplayModeListWindows(); + } + return result; + } __except ( EXCEPTION_EXECUTE_HANDLER ) { + return FetchDisplayModeListWindows(); + } +#pragma warning(pop) +} + +XRESULT D3D11GraphicsEngine::FetchDisplayModeListDXGI() { if ( !DXGIAdapter2 ) { CachedDisplayModes.emplace_back( Resolution.x, Resolution.y ); return XR_FAILED; @@ -1118,6 +1135,27 @@ XRESULT D3D11GraphicsEngine::FetchDisplayModeList() { return XR_SUCCESS; } +XRESULT D3D11GraphicsEngine::FetchDisplayModeListWindows() { + for ( DWORD i = 0;; ++i ) { + DEVMODEA devmode = {}; + devmode.dmSize = sizeof( DEVMODEA ); + devmode.dmDriverExtra = 0; + if ( !EnumDisplaySettingsA( nullptr, i, &devmode ) || (devmode.dmFields & DM_BITSPERPEL) != DM_BITSPERPEL ) + break; + + if ( devmode.dmBitsPerPel < 24 ) + continue; + + DisplayModeInfo info( static_cast(devmode.dmPelsWidth), static_cast(devmode.dmPelsHeight) ); + auto it = std::find_if( CachedDisplayModes.begin(), CachedDisplayModes.end(), + [&info]( DisplayModeInfo& a ) { return (a.Width == info.Width && a.Height == info.Height); } ); + if ( it == CachedDisplayModes.end() ) { + CachedDisplayModes.push_back( info ); + } + } + return XR_SUCCESS; +} + /** Returns a list of available display modes */ XRESULT D3D11GraphicsEngine::GetDisplayModeList( std::vector* modeList, @@ -2660,7 +2698,7 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) { ActiveVS->GetConstantBuffer()[1]->UpdateBuffer( &XMMatrixIdentity() ); ActiveVS->GetConstantBuffer()[1]->BindToVertexShader( 1 ); - + InfiniteRangeConstantBuffer->BindToPixelShader( 3 ); static std::vector renderList; renderList.clear(); @@ -3265,6 +3303,7 @@ void XM_CALLCONV D3D11GraphicsEngine::DrawWorldAround( bool colorWritesEnabled = Engine::GAPI->GetRendererState().BlendState.ColorWritesEnabled; float alphaRef = Engine::GAPI->GetRendererState().GraphicsState.FF_AlphaRef; + bool isOutdoor = (Engine::GAPI->GetLoadedWorldInfo()->BspTree->GetBspTreeMode() == zBSP_MODE_OUTDOOR); std::vector drawnSections; @@ -3389,7 +3428,7 @@ void XM_CALLCONV D3D11GraphicsEngine::DrawWorldAround( // Check for inside vob. Don't render inside-vobs when the light is // outside and vice-versa. - if ( !it->IsIndoorVob && indoor || it->IsIndoorVob && !indoor ) { + if ( isOutdoor && it->IsIndoorVob != indoor ) { continue; } rndVob.emplace_back( it ); @@ -3454,8 +3493,7 @@ void XM_CALLCONV D3D11GraphicsEngine::DrawWorldAround( // Check for inside vob. Don't render inside-vobs when the light is // outside and vice-versa. - if ( !it->Vob->IsIndoorVob() && indoor || - it->Vob->IsIndoorVob() && !indoor ) { + if ( isOutdoor && it->Vob->IsIndoorVob() != indoor ) { continue; } @@ -3506,8 +3544,7 @@ void XM_CALLCONV D3D11GraphicsEngine::DrawWorldAround( } // Check for inside vob. Don't render inside-vobs when the light is // outside and vice-versa. - if ( !skeletalMeshVob->Vob->IsIndoorVob() && indoor || - skeletalMeshVob->Vob->IsIndoorVob() && !indoor ) { + if ( isOutdoor && skeletalMeshVob->Vob->IsIndoorVob() != indoor ) { continue; } @@ -5506,6 +5543,7 @@ void D3D11GraphicsEngine::GetBackbufferData( byte** data, int& pixelsize ) { // Downscale to 256x256 PfxRenderer->CopyTextureToRTV( HDRBackBuffer->GetShaderResView(), rt->GetRenderTargetView(), INT2( width, width ), true ); + GetContext()->Flush(); D3D11_TEXTURE2D_DESC texDesc; texDesc.ArraySize = 1; @@ -5528,11 +5566,25 @@ void D3D11GraphicsEngine::GetBackbufferData( byte** data, int& pixelsize ) { return; } GetContext()->CopyResource( texture.Get(), rt->GetTexture().Get() ); + GetContext()->Flush(); // Get data D3D11_MAPPED_SUBRESOURCE res; if ( SUCCEEDED( GetContext()->Map( texture.Get(), 0, D3D11_MAP_READ, 0, &res ) ) ) { - memcpy( d, res.pData, width * width * 4 ); + unsigned char* dstData = reinterpret_cast(res.pData); + unsigned char* srcData = reinterpret_cast(d); + UINT length = width * 4; + if ( length == res.RowPitch ) { + memcpy( srcData, dstData, length * width ); + } else { + if ( length > res.RowPitch ) + length = res.RowPitch; + for ( int row = 0; row < width; ++row ) { + memcpy( srcData, dstData, length ); + srcData += length; + dstData += res.RowPitch; + } + } GetContext()->Unmap( texture.Get(), 0 ); } else { LogInfo() << "Thumbnail failed"; diff --git a/D3D11Engine/D3D11GraphicsEngine.h b/D3D11Engine/D3D11GraphicsEngine.h index 3b500b80..396c850e 100644 --- a/D3D11Engine/D3D11GraphicsEngine.h +++ b/D3D11Engine/D3D11GraphicsEngine.h @@ -91,6 +91,8 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase { /** Fetches a list of available display modes */ XRESULT FetchDisplayModeList(); + XRESULT FetchDisplayModeListDXGI(); + XRESULT FetchDisplayModeListWindows(); /** Returns a list of available display modes */ virtual XRESULT GetDisplayModeList( std::vector* modeList, bool includeSuperSampling = false ); diff --git a/D3D11Engine/D3D11GraphicsEngineBase.h b/D3D11Engine/D3D11GraphicsEngineBase.h index 4949e813..4771a168 100644 --- a/D3D11Engine/D3D11GraphicsEngineBase.h +++ b/D3D11Engine/D3D11GraphicsEngineBase.h @@ -128,6 +128,8 @@ class D3D11GraphicsEngineBase : public BaseGraphicsEngine { virtual XRESULT SetActiveGShader( const std::string& shader ); //virtual int MeasureString(std::string str, zFont* zFont); + void ResetPresentPending() { PresentPending = false; } + protected: /** Updates the transformsCB with new values from the GAPI */ void UpdateTransformsCB(); diff --git a/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp b/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp index 37c32ed9..0b82571c 100644 --- a/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp +++ b/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp @@ -4,7 +4,6 @@ #include "../Engine.h" #include "../GothicAPI.h" - FakeDirectDrawSurface7::FakeDirectDrawSurface7() { RefCount = 1; Data = nullptr; diff --git a/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp b/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp index 1039b55c..9d065660 100644 --- a/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp +++ b/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp @@ -1,7 +1,7 @@ #include "MyDirectDrawSurface7.h" #include "../Engine.h" #include "../GothicAPI.h" -#include "../BaseGraphicsEngine.h" +#include "../D3D11GraphicsEngineBase.h" #include "../D3D11Texture.h" #include "../zCTexture.h" @@ -325,8 +325,8 @@ HRESULT MyDirectDrawSurface7::Lock( LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurf // Assume 32-bit byte* data; int pixelSize; - Engine::GraphicsEngine->Present(); // Get the old frame out, since the draw-function still waits for "PresentPending" - Engine::GraphicsEngine->OnStartWorldRendering(); // Render a frame without menus on the screen first + reinterpret_cast(Engine::GraphicsEngine)->ResetPresentPending(); + Engine::GraphicsEngine->OnStartWorldRendering(); Engine::GraphicsEngine->GetBackbufferData( &data, pixelSize ); lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 32; diff --git a/D3D11Engine/GothicAPI.cpp b/D3D11Engine/GothicAPI.cpp index 2b9dbabf..6b6d09ee 100644 --- a/D3D11Engine/GothicAPI.cpp +++ b/D3D11Engine/GothicAPI.cpp @@ -148,10 +148,15 @@ float GetPrivateProfileFloatA( const int float_str_max = 30; TCHAR nFloat[float_str_max]; if ( GetPrivateProfileStringA( lpAppName, lpKeyName, nullptr, nFloat, float_str_max, lpFileName.c_str() ) ) { - return std::stof( std::string( nFloat ) ); + try { + return std::stof( std::string( nFloat ) ); + } catch ( const std::exception& ) { + return nDefault; + } } return nDefault; } + std::string GetPrivateProfileStringA( const LPCSTR lpAppName, const LPCSTR lpKeyName, diff --git a/D3D11Engine/HookedFunctions.cpp b/D3D11Engine/HookedFunctions.cpp index f34aa34a..b2a95282 100644 --- a/D3D11Engine/HookedFunctions.cpp +++ b/D3D11Engine/HookedFunctions.cpp @@ -92,6 +92,13 @@ void HookedFunctionInfo::InitHooks() { LogInfo() << "Patching: Fix dx7 zbuffer possible crash"; PatchAddr( 0x007A4B08, "\xB8\x00\x00\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90\x90" ); + + LogInfo() << "Patching: Show correct savegame thumbnail"; + PatchAddr( 0x0042B4A7, "\x8B\xF8\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" );// + PatchAddr( 0x00438057, "\x89\x6C\x24\x10\xEB\x21" );// + PatchAddr( 0x004381D6, "\xEB\x07" );// + PatchAddr( 0x004381E1, "\x55" );// + PatchAddr( 0x00438218, "\xEB\x15" );// #else LogInfo() << "Patching: BroadCast fix"; { @@ -172,6 +179,13 @@ void HookedFunctionInfo::InitHooks() { XHook( 0x0071F5D9, HookedFunctionInfo::hooked_GetNumDevices ); } + + LogInfo() << "Patching: Show correct savegame thumbnail"; + PatchAddr( 0x004289F4, "\x8B\xF8\x90\x90\x90\x90\x90\x90\x90\x90" ); + PatchAddr( 0x00434167, "\x8B\xEE\xEB\x21" ); + PatchAddr( 0x004342AA, "\xEB\x07" ); + PatchAddr( 0x004342B5, "\x55" ); + PatchAddr( 0x004342E0, "\xEB\x15" ); #endif #endif @@ -274,6 +288,13 @@ void HookedFunctionInfo::InitHooks() { XHook( 0x00657EA9, HookedFunctionInfo::hooked_GetNumDevices ); } + LogInfo() << "Patching: Show correct savegame thumbnail"; + PatchAddr( 0x0042A5A9, "\x8B\xF8\x90\x90\x90\x90\x90\x90\x90\x90" ); + PatchAddr( 0x00437157, "\x8B\xEE\xEB\x21" ); + PatchAddr( 0x00437283, "\xEB\x07" ); + PatchAddr( 0x0043728E, "\x55" ); + PatchAddr( 0x004372B9, "\xEB\x15" ); + // HACK Workaround to fix debuglines in godmode LogInfo() << "Patching: Godmode Debuglines"; // oCMagFrontier::GetDistanceNewWorld diff --git a/D3D11Engine/Shaders/VS_PNAEN_Skeletal.hlsl b/D3D11Engine/Shaders/VS_PNAEN_Skeletal.hlsl index 00a00dc4..c0aa5981 100644 --- a/D3D11Engine/Shaders/VS_PNAEN_Skeletal.hlsl +++ b/D3D11Engine/Shaders/VS_PNAEN_Skeletal.hlsl @@ -15,6 +15,7 @@ cbuffer Matrices_PerFrame : register( b0 ) cbuffer Matrices_PerInstances : register( b1 ) { matrix M_World; + float4 PI_ModelColor; float PI_ModelFatness; float3 PI_Pad1; }; @@ -32,10 +33,10 @@ Texture2D TX_Texture0 : register( t0 ); //-------------------------------------------------------------------------------------- struct VS_INPUT { - float3 vPosition[4] : POSITION; + float4 vPosition[4] : POSITION; float3 vNormal : NORMAL; - float2 vTex1 : TEXCOORD0; - float4 vDiffuse : DIFFUSE; + float3 vBindPoseNormal : TEXCOORD0; + float2 vTex1 : TEXCOORD1; uint4 BoneIndices : BONEIDS; float4 Weights : WEIGHTS; }; @@ -57,22 +58,27 @@ struct VS_OUTPUT VS_OUTPUT VSMain( VS_INPUT Input ) { VS_OUTPUT Output; - - float3 position = float3(0,0,0); - for(int i=0;i<4;i++) - { - position += Input.Weights[i] * mul(float4(Input.vPosition[i], 1), BT_Transforms[Input.BoneIndices[i]]).xyz; - } + float3 position = float3(0, 0, 0); + position += Input.Weights.x * mul(float4(Input.vPosition[0].xyz, 1), BT_Transforms[Input.BoneIndices.x]).xyz; + position += Input.Weights.y * mul(float4(Input.vPosition[1].xyz, 1), BT_Transforms[Input.BoneIndices.y]).xyz; + position += Input.Weights.z * mul(float4(Input.vPosition[2].xyz, 1), BT_Transforms[Input.BoneIndices.z]).xyz; + position += Input.Weights.w * mul(float4(Input.vPosition[3].xyz, 1), BT_Transforms[Input.BoneIndices.w]).xyz; + + float3 normal = float3(0, 0, 0); + normal += Input.Weights.x * mul(Input.vNormal, (float3x3)BT_Transforms[Input.BoneIndices.x]); + normal += Input.Weights.y * mul(Input.vNormal, (float3x3)BT_Transforms[Input.BoneIndices.y]); + normal += Input.Weights.z * mul(Input.vNormal, (float3x3)BT_Transforms[Input.BoneIndices.z]); + normal += Input.Weights.w * mul(Input.vNormal, (float3x3)BT_Transforms[Input.BoneIndices.w]); - float3 positionWorld = mul(float4(position + PI_ModelFatness * Input.vNormal,1), M_World).xyz; + float3 positionWorld = mul(float4(position + PI_ModelFatness * normal,1), M_World).xyz; Output.vTexcoord = Input.vTex1; Output.vTexcoord2 = 0; - Output.vNormalVS = normalize(mul(Input.vNormal, (float3x3)mul(M_World, M_View))); - Output.vNormalWS = normalize(mul(Input.vNormal, (float3x3)M_World)); + Output.vNormalVS = normalize(mul(Input.vBindPoseNormal, (float3x3)mul(M_World, M_View))); + Output.vNormalWS = normalize(mul(Input.vBindPoseNormal, (float3x3)M_World)); Output.vViewPosition = mul(float4(positionWorld,1), M_View).xyz; - Output.vDiffuse = 1.0f;//Input.vDiffuse; + Output.vDiffuse = PI_ModelColor;//Input.vDiffuse; return Output; } diff --git a/D3D11Engine/pch.h b/D3D11Engine/pch.h index e1d9f728..92df8296 100644 --- a/D3D11Engine/pch.h +++ b/D3D11Engine/pch.h @@ -27,7 +27,7 @@ #define stdext std #endif -#define VERSION_NUMBER "17.8-dev2-fix2" +#define VERSION_NUMBER "17.8-dev3" __declspec(selectany) const char* VERSION_NUMBER_STR = VERSION_NUMBER; extern bool FeatureLevel10Compatibility; From 1ad4a28abc53641bb977902c859c4300dad108be Mon Sep 17 00:00:00 2001 From: Kirides Date: Thu, 23 Dec 2021 12:11:26 +0100 Subject: [PATCH 12/15] Only clip gothic window if settings window is hidden. Update Clipping when Settings window is opened/closed --- D3D11Engine/BaseGraphicsEngine.h | 3 ++- D3D11Engine/D2DSettingsDialog.cpp | 3 +++ D3D11Engine/D3D11GraphicsEngine.cpp | 10 ++++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/D3D11Engine/BaseGraphicsEngine.h b/D3D11Engine/BaseGraphicsEngine.h index 8fb933c3..9bc39f57 100644 --- a/D3D11Engine/BaseGraphicsEngine.h +++ b/D3D11Engine/BaseGraphicsEngine.h @@ -63,7 +63,8 @@ class BaseGraphicsEngine { public: enum EUIEvent { UI_OpenSettings, - UI_OpenEditor + UI_OpenEditor, + UI_ClosedSettings, }; BaseGraphicsEngine() { }; diff --git a/D3D11Engine/D2DSettingsDialog.cpp b/D3D11Engine/D2DSettingsDialog.cpp index d85016c6..2d42080e 100644 --- a/D3D11Engine/D2DSettingsDialog.cpp +++ b/D3D11Engine/D2DSettingsDialog.cpp @@ -718,4 +718,7 @@ void D2DSettingsDialog::SetHidden( bool hidden ) { OnOpenedSettings(); // Changed visibility from hidden to non-hidden D2DDialog::SetHidden( hidden ); + if ( hidden ) { + Engine::GraphicsEngine->OnUIEvent( BaseGraphicsEngine::EUIEvent::UI_ClosedSettings ); + } } diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index e1774017..add739bc 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -5277,7 +5277,9 @@ void D3D11GraphicsEngine::UpdateClipCursor( HWND hWnd ) { RECT rect; static RECT last_clipped_rect; - if ( m_isWindowActive ) { + + // People use open settings window to navigate to other screens + if ( m_isWindowActive && !HasSettingsWindow() ) { GetClientRect( hWnd, &rect ); ClientToScreen( hWnd, reinterpret_cast(&rect) + 0 ); ClientToScreen( hWnd, reinterpret_cast(&rect) + 1 ); @@ -5501,7 +5503,11 @@ void D3D11GraphicsEngine::OnUIEvent( EUIEvent uiEvent ) { Engine::GAPI->SetEnableGothicInput( UIView->GetSettingsDialog()->IsHidden() ); } - } else if ( uiEvent == UI_OpenEditor ) { + } else if ( uiEvent == UI_ClosedSettings ) { + // Settings can be closed in multiple ways + UpdateClipCursor( OutputWindow ); + } + else if ( uiEvent == UI_OpenEditor ) { if ( UIView ) { // Show settings Engine::GAPI->GetRendererState().RendererSettings.EnableEditorPanel = From b15a9a624ca022a6c14fffd72ac28c6efdd487a5 Mon Sep 17 00:00:00 2001 From: Kirides Date: Thu, 23 Dec 2021 18:36:37 +0100 Subject: [PATCH 13/15] ... --- D3D11Engine/D3D11GraphicsEngine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index add739bc..ee9f3ecc 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -5503,6 +5503,7 @@ void D3D11GraphicsEngine::OnUIEvent( EUIEvent uiEvent ) { Engine::GAPI->SetEnableGothicInput( UIView->GetSettingsDialog()->IsHidden() ); } + UpdateClipCursor( OutputWindow ); } else if ( uiEvent == UI_ClosedSettings ) { // Settings can be closed in multiple ways UpdateClipCursor( OutputWindow ); From 3c98d5d4462497cd9f75b2f74df7b0f2763f3e6e Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Fri, 28 Jan 2022 13:58:58 +0100 Subject: [PATCH 14/15] Improvements -Disable tesselation from build as it keeps to crash graphic drivers and make impossible to save zenresources from advanced menu -Fix getting threadid from main thread -Remove spheremap normals encoding as it make some horrible visual glitches -Make it possible to render scene without normalmaps to avoid artifacts from using standard normalmap -Fix potential problems with some drawcalls -Implement raining time calculations with atmospheric scattering enabled -Make zFILE_VDFS zengine class to be able to operate on pointers that are allocated above 2GB memory virtual address on older system packs --- D3D11Engine/BaseAntTweakBar.cpp | 4 + D3D11Engine/D2DEditorView.cpp | 22 +- D3D11Engine/D2DVobSettingsDialog.cpp | 16 + D3D11Engine/D3D11GraphicsEngine.cpp | 149 +++++--- D3D11Engine/D3D11GraphicsEngine.h | 7 +- D3D11Engine/D3D11NVHBAO.cpp | 7 +- D3D11Engine/D3D11PFX_SMAA.cpp | 25 +- D3D11Engine/D3D11PfxRenderer.cpp | 2 +- D3D11Engine/D3D11ShaderManager.cpp | 10 +- D3D11Engine/GothicAPI.cpp | 80 +++- D3D11Engine/GothicAPI.h | 6 + D3D11Engine/GothicGraphicsState.h | 9 + D3D11Engine/GothicMemoryLocations1_08k.h | 3 + D3D11Engine/GothicMemoryLocations1_12f.h | 3 + D3D11Engine/GothicMemoryLocations2_6_fix.h | 5 + D3D11Engine/HookedFunctions.cpp | 49 ++- D3D11Engine/MeshModifier.cpp | 7 +- D3D11Engine/MeshModifier.h | 2 + D3D11Engine/SV_GMeshInfoView.cpp | 9 +- D3D11Engine/Shaders/DS_Defines.h | 3 +- D3D11Engine/Shaders/PS_AtmosphereGround.hlsl | 8 +- .../Shaders/PS_DS_AtmosphericScattering.hlsl | 18 +- D3D11Engine/Shaders/PS_DS_PointLight.hlsl | 12 +- .../Shaders/PS_DS_PointLightDynShadow.hlsl | 12 +- D3D11Engine/Shaders/PS_DS_SimpleSunlight.hlsl | 14 +- D3D11Engine/Shaders/PS_Diffuse.hlsl | 17 +- D3D11Engine/Shaders/PS_Grass.hlsl | 9 +- D3D11Engine/Shaders/PS_LPP_SunLight.hlsl | 3 +- D3D11Engine/Shaders/PS_Ocean.hlsl | 8 +- D3D11Engine/Shaders/PS_PFX_ApplyWettness.hlsl | 2 +- D3D11Engine/Shaders/PS_PFX_GodRayMask.hlsl | 4 +- D3D11Engine/Shaders/PS_World.hlsl | 12 +- D3D11Engine/Shaders/PS_WorldPOM.hlsl | 8 +- D3D11Engine/Shaders/PS_WorldTriplanar.hlsl | 8 +- D3D11Engine/WorldConverter.cpp | 342 +----------------- D3D11Engine/WorldConverter.h | 11 +- D3D11Engine/WorldObjects.cpp | 44 ++- D3D11Engine/WorldObjects.h | 22 ++ D3D11Engine/pch.h | 4 +- D3D11Engine/zCSkyController_Outdoor.h | 57 ++- 40 files changed, 519 insertions(+), 514 deletions(-) diff --git a/D3D11Engine/BaseAntTweakBar.cpp b/D3D11Engine/BaseAntTweakBar.cpp index 94370a9c..36b5cad2 100644 --- a/D3D11Engine/BaseAntTweakBar.cpp +++ b/D3D11Engine/BaseAntTweakBar.cpp @@ -104,7 +104,9 @@ XRESULT BaseAntTweakBar::Init() { TwAddVarRW( Bar_General, "Draw ParticleEffects", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.DrawParticleEffects, nullptr ); //TwAddVarRW(Bar_General, "Draw Sky", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.DrawSky, nullptr); TwAddVarRW( Bar_General, "Draw Fog", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.DrawFog, nullptr ); +#if ENABLE_TESSELATION > 0 TwAddVarRW( Bar_General, "Tesselation", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.EnableTesselation, nullptr ); +#endif TwAddVarRW( Bar_General, "HDR", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.EnableHDR, nullptr ); TwEnumVal hdrToneMapValues[] = { {0, "ToneMap_jafEq4"}, {1, "Uncharted2Tonemap"}, {2, "ACESFilmTonemap"}, {3, "PerceptualQuantizerTonemap"}, {4, "ToneMap_Simple"}, {5, "ACESFittedTonemap"} }; @@ -129,8 +131,10 @@ XRESULT BaseAntTweakBar::Init() { TwAddVarRW( Bar_General, "Sort RenderQueue", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.SortRenderQueue, nullptr ); TwAddVarRW( Bar_General, "Draw Threaded", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.DrawThreaded, nullptr ); +#if ENABLE_TESSELATION > 0 TwAddVarRW( Bar_General, "AllowWorldMeshTesselation", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.AllowWorldMeshTesselation, nullptr ); TwAddVarRW( Bar_General, "TesselationFrustumCulling", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.TesselationFrustumCulling, nullptr ); +#endif TwAddVarRW( Bar_General, "AtmosphericScattering", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.AtmosphericScattering, nullptr ); TwAddVarRW( Bar_General, "SkeletalVertexNormals", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.ShowSkeletalVertexNormals, nullptr ); diff --git a/D3D11Engine/D2DEditorView.cpp b/D3D11Engine/D2DEditorView.cpp index 79634527..6c210de9 100644 --- a/D3D11Engine/D2DEditorView.cpp +++ b/D3D11Engine/D2DEditorView.cpp @@ -866,6 +866,7 @@ void D2DEditorView::UpdateSelectionPanel() { mi = nullptr; // Get settings from MI, if possible +#if ENABLE_TESSELATION > 0 if ( mi ) { SelectedTexDisplacementSlider->GetSlider()->SetValue( mi->TextureTesselationSettings.buffer.VT_DisplacementStrength ); SelectedMeshRoundnessSlider->GetSlider()->SetValue( mi->TextureTesselationSettings.buffer.VT_Roundness ); @@ -875,6 +876,11 @@ void D2DEditorView::UpdateSelectionPanel() { SelectedMeshRoundnessSlider->GetSlider()->SetValue( info->TesselationSettings.buffer.VT_Roundness ); SelectedMeshTessAmountSlider->GetSlider()->SetValue( info->TesselationSettings.buffer.VT_TesselationFactor ); } +#else + SelectedTexDisplacementSlider->GetSlider()->SetValue( 0.f ); + SelectedMeshRoundnessSlider->GetSlider()->SetValue( 0.f ); + SelectedMeshTessAmountSlider->GetSlider()->SetValue( 0.f ); +#endif } } @@ -1084,8 +1090,10 @@ bool D2DEditorView::OnWindowMessage( HWND hWnd, unsigned int msg, WPARAM wParam, MaterialInfo* info = Engine::GAPI->GetMaterialInfoFrom( Selection.SelectedMaterial->GetTexture() ); if ( info ) { +#if ENABLE_TESSELATION > 0 // Set the offline-tesselation factor info->TextureTesselationSettings.buffer.VT_TesselationFactor = 2; +#endif // Overwrite shader info->TesselationShaderPair = "PNAEN_Tesselation"; @@ -1335,12 +1343,15 @@ void D2DEditorView::TextureSettingsSliderChanged( SV_Slider* sender, void* userd } else if ( sender == v->SelectedTexSpecPowerSlider->GetSlider() ) { info->buffer.SpecularPower = sender->GetValue(); } else if ( sender == v->SelectedTexDisplacementSlider->GetSlider() && v->Selection.SelectedMesh ) { +#if ENABLE_TESSELATION > 0 WorldMeshInfo* mesh = (WorldMeshInfo*)v->Selection.SelectedMesh; // TODO: Make this nicer mesh->TesselationSettings.buffer.VT_DisplacementStrength = sender->GetValue(); mesh->TesselationSettings.UpdateConstantbuffer(); info->TextureTesselationSettings.buffer.VT_DisplacementStrength = sender->GetValue(); +#endif } else if ( sender == v->SelectedMeshTessAmountSlider->GetSlider() && v->Selection.SelectedMesh ) { +#if ENABLE_TESSELATION > 0 WorldMeshInfo* mesh = (WorldMeshInfo*)v->Selection.SelectedMesh; // TODO: Make this nicer if ( !mesh->MeshIndexBufferPNAEN ) { @@ -1352,12 +1363,15 @@ void D2DEditorView::TextureSettingsSliderChanged( SV_Slider* sender, void* userd mesh->TesselationSettings.UpdateConstantbuffer(); info->TextureTesselationSettings.buffer.VT_TesselationFactor = sender->GetValue(); +#endif } else if ( sender == v->SelectedMeshRoundnessSlider->GetSlider() && v->Selection.SelectedMesh ) { +#if ENABLE_TESSELATION > 0 WorldMeshInfo* mesh = (WorldMeshInfo*)v->Selection.SelectedMesh; // TODO: Make this nicer mesh->TesselationSettings.buffer.VT_Roundness = sender->GetValue(); mesh->TesselationSettings.UpdateConstantbuffer(); info->TextureTesselationSettings.buffer.VT_Roundness = sender->GetValue(); +#endif } /*else if (sender == v->SelectedTexSpecModulationSlider->GetSlider()) @@ -1367,7 +1381,9 @@ void D2DEditorView::TextureSettingsSliderChanged( SV_Slider* sender, void* userd // Update and save the info info->UpdateConstantbuffer(); +#if ENABLE_TESSELATION > 0 info->TextureTesselationSettings.UpdateConstantbuffer(); +#endif info->WriteToFile( v->Selection.SelectedMaterial->GetTexture()->GetNameWithoutExt() ); } } @@ -1386,6 +1402,7 @@ void D2DEditorView::SmoothMesh( WorldMeshInfo* mesh, bool tesselate ) { mesh->Indices.clear(); MeshModifier::DropTexcoords(vxOld, ixOld, mesh->Vertices, mesh->Indices);*/ +#if ENABLE_TESSELATION > 0 // Tesselate if the outcome would still be in 16-bit range if ( tesselate && mesh->Vertices.size() + (mesh->Indices.size() / 3) < 0x0000FFFF ) { std::vector meshTess; @@ -1395,7 +1412,6 @@ void D2DEditorView::SmoothMesh( WorldMeshInfo* mesh, bool tesselate ) { vx[1] = mesh->Vertices[mesh->Indices[i + 1]]; vx[2] = mesh->Vertices[mesh->Indices[i + 2]]; - std::vector triTess; WorldConverter::TesselateTriangle( vx, triTess, 1 ); @@ -1405,8 +1421,6 @@ void D2DEditorView::SmoothMesh( WorldMeshInfo* mesh, bool tesselate ) { } } - - mesh->Vertices.clear(); mesh->Indices.clear(); @@ -1423,7 +1437,6 @@ void D2DEditorView::SmoothMesh( WorldMeshInfo* mesh, bool tesselate ) { return; } - // Cleanup SAFE_DELETE(mesh->MeshVertexBuffer); SAFE_DELETE(mesh->MeshIndexBuffer); @@ -1442,6 +1455,7 @@ void D2DEditorView::SmoothMesh( WorldMeshInfo* mesh, bool tesselate ) { mesh->TesselationSettings.buffer.VT_TesselationFactor = 2.0f; mesh->TesselationSettings.buffer.VT_DisplacementStrength = 0.5f; mesh->TesselationSettings.UpdateConstantbuffer(); +#endif // Mark dirty mesh->SaveInfo = true; diff --git a/D3D11Engine/D2DVobSettingsDialog.cpp b/D3D11Engine/D2DVobSettingsDialog.cpp index 50c2aff8..cb6093d7 100644 --- a/D3D11Engine/D2DVobSettingsDialog.cpp +++ b/D3D11Engine/D2DVobSettingsDialog.cpp @@ -101,11 +101,14 @@ void D2DVobSettingsDialog::SliderDragged( SV_Slider* sender, void* userdata ) { if ( !d->Vob ) return; +#if ENABLE_TESSELATION > 0 VisualTesselationSettings* ts = nullptr; if ( d->Vob ) ts = &d->Vob->VisualInfo->TesselationInfo; +#endif if ( sender == d->DisplacementStrengthSetting->GetSlider() ) { +#if ENABLE_TESSELATION > 0 float oldValue = ts->buffer.VT_DisplacementStrength; ts->buffer.VT_DisplacementStrength = sender->GetValue(); @@ -123,24 +126,31 @@ void D2DVobSettingsDialog::SliderDragged( SV_Slider* sender, void* userdata ) { d->Vob->VisualInfo->CreatePNAENInfo( true ); } } +#endif } else if ( sender == d->RoundnessSetting->GetSlider() ) { +#if ENABLE_TESSELATION > 0 ts->buffer.VT_Roundness = sender->GetValue(); +#endif } else if ( sender == d->TesselationFactorSetting->GetSlider() ) { +#if ENABLE_TESSELATION > 0 ts->buffer.VT_TesselationFactor = sender->GetValue(); if ( ts->buffer.VT_TesselationFactor > 0.0f ) { if ( d->Vob ) d->Vob->VisualInfo->CreatePNAENInfo( ts->buffer.VT_DisplacementStrength > 0.0f ); // This only creates missing infos } +#endif } else if ( sender == d->RenderMode->GetSlider() ) { d->MeshView->SetRenderMode( (SV_GMeshInfoView::ERenderMode)(int)(sender->GetValue() + 0.5f) ); } +#if ENABLE_TESSELATION > 0 // Save changes d->Vob->VisualInfo->SaveMeshVisualInfo( d->Vob->VisualInfo->VisualName ); // Update everything ts->UpdateConstantbuffer(); +#endif d->MeshView->UpdateView(); } @@ -165,9 +175,15 @@ void D2DVobSettingsDialog::SetVobInfo( BaseVobInfo* vob ) { } } +#if ENABLE_TESSELATION > 0 RoundnessSetting->GetSlider()->SetValue( vob->VisualInfo->TesselationInfo.buffer.VT_Roundness ); TesselationFactorSetting->GetSlider()->SetValue( vob->VisualInfo->TesselationInfo.buffer.VT_TesselationFactor ); DisplacementStrengthSetting->GetSlider()->SetValue( vob->VisualInfo->TesselationInfo.buffer.VT_DisplacementStrength ); +#else + RoundnessSetting->GetSlider()->SetValue( 0.f ); + TesselationFactorSetting->GetSlider()->SetValue( 0.f ); + DisplacementStrengthSetting->GetSlider()->SetValue( 0.f ); +#endif Vob = vob; diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index ee9f3ecc..8cccc342 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -129,7 +129,12 @@ XRESULT D3D11GraphicsEngine::Init() { LogInfo() << "Initializing Device..."; // Create DXGI factory - LE( CreateDXGIFactory1( __uuidof(IDXGIFactory2), &DXGIFactory2 ) ); + hr = CreateDXGIFactory1( __uuidof(IDXGIFactory2), &DXGIFactory2 ); + if ( FAILED( hr ) ) { + LogErrorBox() << "CreateDXGIFactory1 failed with code: " << hr << "!\n" + "Minimum supported Operating System by GD3D11 is Windows 7 SP1 with Platform Update."; + exit( 2 ); + } bool haveAdapter = false; Microsoft::WRL::ComPtr DXGIFactory6; @@ -221,7 +226,7 @@ XRESULT D3D11GraphicsEngine::Init() { D3D11_SDK_VERSION, Device11.GetAddressOf(), &maxFeatureLevel, Context11.GetAddressOf() ); } if ( FAILED( hr ) ) { - LE( hr ); + LogErrorBox() << "D3D11CreateDevice failed with code: " << hr << "!"; exit( 2 ); } @@ -841,7 +846,10 @@ XRESULT D3D11GraphicsEngine::OnResize( INT2 newSize ) { PfxRenderer->OnResize( Resolution ); - GBuffer1_Normals_SpecIntens_SpecPower = std::make_unique( + GBuffer2_SpecIntens_SpecPower = std::make_unique( + GetDevice().Get(), Resolution.x, Resolution.y, DXGI_FORMAT_R16G16_FLOAT ); + + GBuffer1_Normals = std::make_unique( GetDevice().Get(), Resolution.x, Resolution.y, DXGI_FORMAT_R16G16B16A16_FLOAT ); GBuffer0_Diffuse = std::make_unique( @@ -1006,11 +1014,18 @@ XRESULT D3D11GraphicsEngine::OnBeginFrame() { SetActivePixelShader( "PS_Simple" ); SetActiveVertexShader( "VS_Ex" ); - PS_DiffuseNormalmappedFxMap = ShaderManager->GetPShader( "PS_DiffuseNormalmappedFxMap" ); - PS_DiffuseNormalmappedAlphatestFxMap = ShaderManager->GetPShader( "PS_DiffuseNormalmappedAlphatestFxMap" ); - PS_DiffuseNormalmapped = ShaderManager->GetPShader( "PS_DiffuseNormalmapped" ); + if ( Engine::GAPI->GetRendererState().RendererSettings.AllowNormalmaps ) { + PS_DiffuseNormalmappedFxMap = ShaderManager->GetPShader( "PS_DiffuseNormalmappedFxMap" ); + PS_DiffuseNormalmappedAlphatestFxMap = ShaderManager->GetPShader( "PS_DiffuseNormalmappedAlphatestFxMap" ); + PS_DiffuseNormalmapped = ShaderManager->GetPShader( "PS_DiffuseNormalmapped" ); + PS_DiffuseNormalmappedAlphatest = ShaderManager->GetPShader( "PS_DiffuseNormalmappedAlphaTest" ); + } else { + PS_DiffuseNormalmappedFxMap = ShaderManager->GetPShader( "PS_Diffuse" ); + PS_DiffuseNormalmappedAlphatestFxMap = ShaderManager->GetPShader( "PS_DiffuseAlphaTest" ); + PS_DiffuseNormalmapped = ShaderManager->GetPShader( "PS_Diffuse" ); + PS_DiffuseNormalmappedAlphatest = ShaderManager->GetPShader( "PS_DiffuseAlphaTest" ); + } PS_Diffuse = ShaderManager->GetPShader( "PS_Diffuse" ); - PS_DiffuseNormalmappedAlphatest = ShaderManager->GetPShader( "PS_DiffuseNormalmappedAlphaTest" ); PS_DiffuseAlphatest = ShaderManager->GetPShader( "PS_DiffuseAlphaTest" ); PS_Simple = ShaderManager->GetPShader( "PS_Simple" ); GS_Billboard = ShaderManager->GetGShader( "GS_Billboard" ); @@ -1033,7 +1048,8 @@ XRESULT D3D11GraphicsEngine::Clear( const float4& color ) { D3D11_CLEAR_DEPTH, 0, 0 ); GetContext()->ClearRenderTargetView( GBuffer0_Diffuse->GetRenderTargetView().Get(), (float*)&color ); - GetContext()->ClearRenderTargetView( GBuffer1_Normals_SpecIntens_SpecPower->GetRenderTargetView().Get(), (float*)&float4( 0, 0, 0, 0 ) ); + GetContext()->ClearRenderTargetView( GBuffer1_Normals->GetRenderTargetView().Get(), (float*)&float4( 0, 0, 0, 0 ) ); + GetContext()->ClearRenderTargetView( GBuffer2_SpecIntens_SpecPower->GetRenderTargetView().Get(), (float*)&float4( 0, 0, 0, 0 ) ); GetContext()->ClearRenderTargetView( HDRBackBuffer->GetRenderTargetView().Get(), (float*)&float4( 0, 0, 0, 0 ) ); return XR_SUCCESS; @@ -1238,7 +1254,7 @@ XRESULT D3D11GraphicsEngine::Present() { vp.TopLeftX = 0.0f; vp.TopLeftY = 0.0f; vp.MinDepth = 0.0f; - vp.MaxDepth = 0.0f; + vp.MaxDepth = 1.0f; vp.Width = static_cast(GetBackbufferResolution().x); vp.Height = static_cast(GetBackbufferResolution().y); @@ -1276,6 +1292,14 @@ XRESULT D3D11GraphicsEngine::Present() { UIView->Render( Engine::GAPI->GetFrameTimeSec() ); } + // Don't allow presenting from different thread than mainthread + // shouldn't happen but who knows + if ( Engine::GAPI->GetMainThreadID() != GetCurrentThreadId() ) { + GetContext()->Flush(); + PresentPending = false; + return XR_SUCCESS; + } + bool vsync = Engine::GAPI->GetRendererState().RendererSettings.EnableVSync; HRESULT hr; @@ -1892,8 +1916,9 @@ XRESULT D3D11GraphicsEngine::DrawSkeletalMesh( SkeletalVobInfo* vi, } } +#if ENABLE_TESSELATION > 0 const bool tesselationEnabled = Engine::GAPI->GetRendererState().RendererSettings.EnableTesselation; - +#endif if ( RenderingStage == DES_MAIN ) { if ( ActiveHDS ) { GetContext()->DSSetShader( nullptr, nullptr, 0 ); @@ -1915,11 +1940,14 @@ XRESULT D3D11GraphicsEngine::DrawSkeletalMesh( SkeletalVobInfo* vi, D3D11VertexBuffer* vb; D3D11VertexBuffer* ib; unsigned int numIndices; +#if ENABLE_TESSELATION > 0 if ( tesselationEnabled && !mesh->IndicesPNAEN.empty() ) { vb = mesh->MeshVertexBuffer; ib = mesh->MeshIndexBufferPNAEN; numIndices = mesh->IndicesPNAEN.size(); - } else { + } else +#endif + { vb = mesh->MeshVertexBuffer; ib = mesh->MeshIndexBuffer; numIndices = mesh->Indices.size(); @@ -2185,8 +2213,10 @@ XRESULT D3D11GraphicsEngine::OnStartWorldRendering() { // Disable here what we can't draw in feature level 10 compatibility Engine::GAPI->GetRendererState().RendererSettings.HbaoSettings.Enabled = false; Engine::GAPI->GetRendererState().RendererSettings.EnableSMAA = false; +#if ENABLE_TESSELATION > 0 Engine::GAPI->GetRendererState().RendererSettings.EnableTesselation = false; Engine::GAPI->GetRendererState().RendererSettings.AllowWorldMeshTesselation = false; +#endif } D3D11_VIEWPORT vp; @@ -2201,8 +2231,9 @@ XRESULT D3D11GraphicsEngine::OnStartWorldRendering() { ID3D11RenderTargetView* rtvs[] = { GBuffer0_Diffuse->GetRenderTargetView().Get(), - GBuffer1_Normals_SpecIntens_SpecPower->GetRenderTargetView().Get() }; - GetContext()->OMSetRenderTargets( 2, rtvs, DepthStencilBuffer->GetDepthStencilView().Get() ); + GBuffer1_Normals->GetRenderTargetView().Get(), + GBuffer2_SpecIntens_SpecPower->GetRenderTargetView().Get() }; + GetContext()->OMSetRenderTargets( 3, rtvs, DepthStencilBuffer->GetDepthStencilView().Get() ); Engine::GAPI->SetFarPlane( Engine::GAPI->GetRendererState().RendererSettings.SectionDrawRadius * WORLD_SECTION_SIZE ); @@ -2764,8 +2795,10 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) { if ( mesh.first.Info->MaterialType == MaterialInfo::MT_Water ) continue; // Don't pre-render water +#if ENABLE_TESSELATION > 0 if ( mesh.second->TesselationSettings.buffer.VT_TesselationFactor > 0.0f ) continue; // Don't pre-render tesselated surfaces +#endif DrawVertexBufferIndexedUINT( nullptr, nullptr, mesh.second->Indices.size(), mesh.second->BaseIndexLocation ); } @@ -2774,9 +2807,11 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) { SetActivePixelShader( "PS_Diffuse" ); ActivePS->Apply(); +#if ENABLE_TESSELATION > 0 bool tesselationEnabled = Engine::GAPI->GetRendererState().RendererSettings.EnableTesselation && Engine::GAPI->GetRendererState().RendererSettings.AllowWorldMeshTesselation; +#endif // Now draw the actual pixels zCTexture* bound = nullptr; @@ -2832,13 +2867,17 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) { boundInfo = info; } bound = mesh.first.Texture; + +#if ENABLE_TESSELATION > 0 // Bind normalmap to HDS if ( !mesh.second->IndicesPNAEN.empty() ) { GetContext()->DSSetShaderResources( 0, 1, boundNormalmap.GetAddressOf() ); GetContext()->HSSetShaderResources( 0, 1, boundNormalmap.GetAddressOf() ); } +#endif } +#if ENABLE_TESSELATION > 0 // Check for tesselated mesh if ( tesselationEnabled && !ActiveHDS && boundInfo->TextureTesselationSettings.buffer.VT_TesselationFactor > @@ -2874,17 +2913,21 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) { // Bind wrapped mesh again DrawVertexBufferIndexedUINT( meshInfo->MeshVertexBuffer, meshInfo->MeshIndexBuffer, 0, 0 ); } +#endif if ( Engine::GAPI->GetRendererState().RendererSettings.DrawWorldMesh > 2 ) { - if ( !ActiveHDS ) { - DrawVertexBufferIndexed( mesh.second->MeshVertexBuffer, - mesh.second->MeshIndexBuffer, - mesh.second->Indices.size() ); - } else { +#if ENABLE_TESSELATION > 0 + if ( ActiveHDS ) { // Draw from mesh info DrawVertexBufferIndexed( mesh.second->MeshVertexBuffer, mesh.second->MeshIndexBufferPNAEN, mesh.second->IndicesPNAEN.size() ); + } else +#endif + { + DrawVertexBufferIndexed( mesh.second->MeshVertexBuffer, + mesh.second->MeshIndexBuffer, + mesh.second->Indices.size() ); } } @@ -3868,8 +3911,10 @@ XRESULT D3D11GraphicsEngine::DrawVOBsInstanced() { SetupVS_ExMeshDrawCall(); SetupVS_ExConstantBuffer(); +#if ENABLE_TESSELATION > 0 bool tesselationEnabled = Engine::GAPI->GetRendererState().RendererSettings.EnableTesselation; +#endif static std::vector vobs; static std::vector lights; @@ -4043,9 +4088,11 @@ XRESULT D3D11GraphicsEngine::DrawVOBsInstanced() { // Bind both GetContext()->PSSetShaderResources( 0, 3, srv ); +#if ENABLE_TESSELATION > 0 // Set normal/displacement map GetContext()->DSSetShaderResources( 0, 1, &srv[1] ); GetContext()->HSSetShaderResources( 0, 1, &srv[1] ); +#endif // Force alphatest on vobs for now BindShaderForTexture( tx, true, 0 ); @@ -4056,6 +4103,7 @@ XRESULT D3D11GraphicsEngine::DrawVOBsInstanced() { } } +#if ENABLE_TESSELATION > 0 if ( tesselationEnabled && !mi->IndicesPNAEN.empty() && RenderingStage == DES_MAIN && staticMeshVisual.second->TesselationInfo.buffer.VT_TesselationFactor > 0.0f ) { @@ -4072,18 +4120,20 @@ XRESULT D3D11GraphicsEngine::DrawVOBsInstanced() { ActiveVS->Apply(); } - if ( !ActiveHDS ) { - // Draw batch - DrawInstanced( mi->MeshVertexBuffer, mi->MeshIndexBuffer, - mi->Indices.size(), DynamicInstancingBuffer.get(), - sizeof( VobInstanceInfo ), staticMeshVisual.second->Instances.size(), - sizeof( ExVertexStruct ), staticMeshVisual.second->StartInstanceNum ); - } else { + if ( ActiveHDS ) { // Draw batch tesselated DrawInstanced( mi->MeshVertexBuffer, mi->MeshIndexBufferPNAEN, mi->IndicesPNAEN.size(), DynamicInstancingBuffer.get(), sizeof( VobInstanceInfo ), staticMeshVisual.second->Instances.size(), sizeof( ExVertexStruct ), staticMeshVisual.second->StartInstanceNum ); + } else +#endif + { + // Draw batch + DrawInstanced( mi->MeshVertexBuffer, mi->MeshIndexBuffer, + mi->Indices.size(), DynamicInstancingBuffer.get(), + sizeof( VobInstanceInfo ), staticMeshVisual.second->Instances.size(), + sizeof( ExVertexStruct ), staticMeshVisual.second->StartInstanceNum ); } } } @@ -4770,7 +4820,8 @@ XRESULT D3D11GraphicsEngine::DrawLighting( std::vector& lights ) plcb.PL_ViewportSize = float2( static_cast(Resolution.x), static_cast(Resolution.y) ); GBuffer0_Diffuse->BindToPixelShader( GetContext().Get(), 0 ); - GBuffer1_Normals_SpecIntens_SpecPower->BindToPixelShader( GetContext().Get(), 1 ); + GBuffer1_Normals->BindToPixelShader( GetContext().Get(), 1 ); + GBuffer2_SpecIntens_SpecPower->BindToPixelShader( GetContext().Get(), 7 ); DepthStencilBufferCopy->BindToPixelShader( GetContext().Get(), 2 ); bool lastOutside = true; @@ -4981,6 +5032,7 @@ XRESULT D3D11GraphicsEngine::DrawLighting( std::vector& lights ) // Reset state Microsoft::WRL::ComPtr srv; GetContext()->PSSetShaderResources( 2, 1, srv.GetAddressOf() ); + GetContext()->PSSetShaderResources( 7, 1, srv.GetAddressOf() ); GetContext()->OMSetRenderTargets( 1, HDRBackBuffer->GetRenderTargetView().GetAddressOf(), DepthStencilBuffer->GetDepthStencilView().Get() ); @@ -5275,9 +5327,10 @@ void D3D11GraphicsEngine::DrawVobsList( const std::list& vobs, zCCamer /** Update clipping cursor onto window */ void D3D11GraphicsEngine::UpdateClipCursor( HWND hWnd ) { +#ifndef BUILD_SPACER_NET RECT rect; static RECT last_clipped_rect; - + // People use open settings window to navigate to other screens if ( m_isWindowActive && !HasSettingsWindow() ) { GetClientRect( hWnd, &rect ); @@ -5292,6 +5345,7 @@ void D3D11GraphicsEngine::UpdateClipCursor( HWND hWnd ) ZeroMemory( &last_clipped_rect, sizeof( RECT ) ); } } +#endif } /** Message-Callback for the main window */ @@ -5507,8 +5561,7 @@ void D3D11GraphicsEngine::OnUIEvent( EUIEvent uiEvent ) { } else if ( uiEvent == UI_ClosedSettings ) { // Settings can be closed in multiple ways UpdateClipCursor( OutputWindow ); - } - else if ( uiEvent == UI_OpenEditor ) { + } else if ( uiEvent == UI_OpenEditor ) { if ( UIView ) { // Show settings Engine::GAPI->GetRendererState().RendererSettings.EnableEditorPanel = @@ -5947,6 +6000,7 @@ void D3D11GraphicsEngine::EnsureTempVertexBufferSize( std::unique_ptr 0 /** Sets up everything for a PNAEN-Mesh */ void D3D11GraphicsEngine::Setup_PNAEN( EPNAENRenderMode mode ) { auto pnaen = ShaderManager->GetHDShader( "PNAEN_Tesselation" ); @@ -5987,6 +6041,7 @@ void D3D11GraphicsEngine::Setup_PNAEN( EPNAENRenderMode mode ) { GetContext()->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST ); } +#endif /** Draws particle meshes */ void D3D11GraphicsEngine::DrawFrameParticleMeshes( std::unordered_map& progMeshes ) { @@ -6098,7 +6153,7 @@ void D3D11GraphicsEngine::DrawFrameParticles( // Clear GBuffer0 to hold the refraction vectors since it's not needed anymore GetContext()->ClearRenderTargetView( GBuffer0_Diffuse->GetRenderTargetView().Get(), (float*)&float4( 0, 0, 0, 0 ) ); - GetContext()->ClearRenderTargetView( GBuffer1_Normals_SpecIntens_SpecPower->GetRenderTargetView().Get(), (float*)&float4( 0, 0, 0, 0 ) ); + GetContext()->ClearRenderTargetView( GBuffer1_Normals->GetRenderTargetView().Get(), (float*)&float4( 0, 0, 0, 0 ) ); RefractionInfoConstantBuffer ricb = {}; ricb.RI_Projection = Engine::GAPI->GetProjectionMatrix(); @@ -6137,7 +6192,7 @@ void D3D11GraphicsEngine::DrawFrameParticles( ID3D11RenderTargetView* rtv[] = { GBuffer0_Diffuse->GetRenderTargetView().Get(), - GBuffer1_Normals_SpecIntens_SpecPower->GetRenderTargetView().Get() }; + GBuffer1_Normals->GetRenderTargetView().Get() }; GetContext()->OMSetRenderTargets( 2, rtv, DepthStencilBuffer->GetDepthStencilView().Get() ); // Bind view/proj @@ -6228,7 +6283,7 @@ void D3D11GraphicsEngine::DrawFrameParticles( state.BlendState.SetDirty(); GBuffer0_Diffuse->BindToPixelShader( GetContext().Get(), 1 ); - GBuffer1_Normals_SpecIntens_SpecPower->BindToPixelShader( GetContext().Get(), 2 ); + GBuffer1_Normals->BindToPixelShader( GetContext().Get(), 2 ); // Copy scene behind the particle systems PfxRenderer->CopyTextureToRTV( @@ -6486,8 +6541,18 @@ void D3D11GraphicsEngine::DrawString( const std::string& str, float x, float y, SetActiveVertexShader( "VS_TransformedEx" ); SetActivePixelShader( "PS_FixedFunctionPipe" ); + GothicGraphicsState& graphicState = Engine::GAPI->GetRendererState().GraphicsState; + FixedFunctionStage::EColorOp copyColorOp = graphicState.FF_Stages[0].ColorOp; + FixedFunctionStage::EColorOp copyColorOp2 = graphicState.FF_Stages[1].ColorOp; + FixedFunctionStage::ETextureArg copyColorArg1 = graphicState.FF_Stages[0].ColorArg1; + FixedFunctionStage::ETextureArg copyColorArg2 = graphicState.FF_Stages[0].ColorArg2; + graphicState.FF_Stages[0].ColorOp = FixedFunctionStage::EColorOp::CO_MODULATE; + graphicState.FF_Stages[1].ColorOp = FixedFunctionStage::EColorOp::CO_DISABLE; + graphicState.FF_Stages[0].ColorArg1 = FixedFunctionStage::ETextureArg::TA_TEXTURE; + graphicState.FF_Stages[0].ColorArg2 = FixedFunctionStage::ETextureArg::TA_DIFFUSE; + // Bind the FF-Info to the first PS slot - ActivePS->GetConstantBuffer()[0]->UpdateBuffer( &Engine::GAPI->GetRendererState().GraphicsState ); + ActivePS->GetConstantBuffer()[0]->UpdateBuffer( &graphicState ); ActivePS->GetConstantBuffer()[0]->BindToPixelShader( 0 ); BindActiveVertexShader(); @@ -6523,19 +6588,6 @@ void D3D11GraphicsEngine::DrawString( const std::string& str, float x, float y, // Bind the texture. tx->Bind( 0 ); - // Set PS resources - MyDirectDrawSurface7* surface = tx->GetSurface(); - - ID3D11ShaderResourceView* srv[3] = { - // Get diffuse and normalmap - surface->GetEngineTexture()->GetShaderResourceView().Get(), - surface->GetNormalmap() ? surface->GetNormalmap()->GetShaderResourceView().Get() : NULL, - surface->GetFxMap() ? surface->GetFxMap()->GetShaderResourceView().Get() : NULL, - }; - - // Bind both - - GetContext()->PSSetShaderResources( 0, 3, srv ); if ( !Engine::GAPI->GetRendererState().BlendState.BlendEnabled ) { Engine::GAPI->GetRendererState().BlendState.SetAlphaBlending(); Engine::GAPI->GetRendererState().BlendState.SetDirty(); @@ -6557,4 +6609,9 @@ void D3D11GraphicsEngine::DrawString( const std::string& str, float x, float y, Engine::GAPI->GetRendererState().DepthState.SetDirty(); UpdateRenderStates(); + + graphicState.FF_Stages[0].ColorOp = copyColorOp; + graphicState.FF_Stages[1].ColorOp = copyColorOp2; + graphicState.FF_Stages[0].ColorArg1 = copyColorArg1; + graphicState.FF_Stages[0].ColorArg2 = copyColorArg2; } diff --git a/D3D11Engine/D3D11GraphicsEngine.h b/D3D11Engine/D3D11GraphicsEngine.h index 396c850e..6a6cba0f 100644 --- a/D3D11Engine/D3D11GraphicsEngine.h +++ b/D3D11Engine/D3D11GraphicsEngine.h @@ -136,6 +136,7 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase { void UpdateColorSpace_SwapChain3(); void UpdateColorSpace_SwapChain4(); +#if ENABLE_TESSELATION > 0 enum EPNAENRenderMode { PNAEN_Default, PNAEN_Instanced, @@ -144,6 +145,7 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase { /** Sets up everything for a PNAEN-Mesh */ void Setup_PNAEN( EPNAENRenderMode mode = PNAEN_Default ); +#endif /** Sets up texture with normalmap and fxmap for rendering */ bool BindTextureNRFX( zCTexture* tex, bool bindShader ); @@ -198,7 +200,7 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase { RenderToTextureBuffer& GetGBuffer0() { return *GBuffer0_Diffuse; } /** Returns the second GBuffer */ - RenderToTextureBuffer& GetGBuffer1() { return *GBuffer1_Normals_SpecIntens_SpecPower; } + RenderToTextureBuffer& GetGBuffer1() { return *GBuffer1_Normals; } /** Returns the HDRBackbuffer */ RenderToTextureBuffer& GetHDRBackBuffer() { return *HDRBackBuffer; } @@ -368,7 +370,8 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase { Microsoft::WRL::ComPtr BackbufferRTV; Microsoft::WRL::ComPtr BackbufferSRV; // Diffuse std::unique_ptr GBuffer0_Diffuse; - std::unique_ptr GBuffer1_Normals_SpecIntens_SpecPower; // Normals / SpecIntensity / SpecPower + std::unique_ptr GBuffer1_Normals; // Normals + std::unique_ptr GBuffer2_SpecIntens_SpecPower; // SpecIntensity / SpecPower std::unique_ptr DepthStencilBufferCopy; std::unique_ptr DummyShadowCubemapTexture; // PS-Stage needs to have a rendertarget bound to execute SV_Depth-Writes, as it seems. diff --git a/D3D11Engine/D3D11NVHBAO.cpp b/D3D11Engine/D3D11NVHBAO.cpp index ed477117..e3485265 100644 --- a/D3D11Engine/D3D11NVHBAO.cpp +++ b/D3D11Engine/D3D11NVHBAO.cpp @@ -50,6 +50,11 @@ XRESULT D3D11NVHBAO::Render( Microsoft::WRL::ComPtr pOut Input.DepthData.ProjectionMatrix.Layout = GFSDK_SSAO_COLUMN_MAJOR_ORDER; Input.DepthData.MetersToViewSpaceUnits = settings.MetersToViewSpaceUnits; + Input.NormalData.Enable = true; + Input.NormalData.pFullResNormalTextureSRV = engine->GetGBuffer1().GetShaderResView().Get(); + Input.NormalData.WorldToViewMatrix.Data = GFSDK_SSAO_Float4x4( (float*)&XMMatrixIdentity() ); // We already have them in view-space + Input.NormalData.WorldToViewMatrix.Layout = GFSDK_SSAO_COLUMN_MAJOR_ORDER; + GFSDK_SSAO_Parameters Params; Params.Radius = settings.Radius; Params.Bias = settings.Bias; @@ -72,4 +77,4 @@ XRESULT D3D11NVHBAO::Render( Microsoft::WRL::ComPtr pOut } return XR_SUCCESS; -} \ No newline at end of file +} diff --git a/D3D11Engine/D3D11PFX_SMAA.cpp b/D3D11Engine/D3D11PFX_SMAA.cpp index 8e0331bf..b9c9ed34 100644 --- a/D3D11Engine/D3D11PFX_SMAA.cpp +++ b/D3D11Engine/D3D11PFX_SMAA.cpp @@ -102,7 +102,7 @@ void D3D11PFX_SMAA::RenderPostFX(const Microsoft::WRL::ComPtrGetTempBuffer().GetSizeX(); vp.Height = (float)FxRenderer->GetTempBuffer().GetSizeY(); @@ -134,8 +134,6 @@ void D3D11PFX_SMAA::RenderPostFX(const Microsoft::WRL::ComPtrCopyTextureToRTV(renderTargetSRV, RTV, INT2(0, 0), true); - SMAAShader->GetVariableByName( "colorTexGamma" )->AsShaderResource()->SetResource( nullptr ); - engine->GetContext()->PSSetShaderResources( 0, 3, NoSRV ); /** Second pass - BlendingWeightCalculation */ @@ -146,37 +144,22 @@ void D3D11PFX_SMAA::RenderPostFX(const Microsoft::WRL::ComPtrGetPassByIndex( 0 )->Apply( 0, engine->GetContext().Get() ); FxRenderer->DrawFullScreenQuad(); - /** Copy back to main RTV */ - /*DXUTGetD3D11DeviceContext()->OMSetRenderTargets(1, OldRTV.GetAddressOf(), nullptr); - CopyShader->SetBackBufferVar(BlendTex->GetShaderResView()); - CmplxScreenQuad.SetShader(CopyShader); - CmplxScreenQuad.Render(6); - - goto end;*/ - - + engine->GetContext()->PSSetShaderResources( 0, 3, NoSRV ); /** Third pass - NeighborhoodBlending */ engine->GetContext()->OMSetRenderTargets( 1, TempRTV.GetRenderTargetView().GetAddressOf(), OldDSV.Get() ); - SMAAShader->GetVariableByName( "colorTex" )->AsShaderResource()->SetResource( renderTargetSRV.Get() ); SMAAShader->GetVariableByName( "blendTex" )->AsShaderResource()->SetResource( BlendTex->GetShaderResView().Get() ); NeighborhoodBlending->GetPassByIndex( 0 )->Apply( 0, engine->GetContext().Get() ); FxRenderer->DrawFullScreenQuad(); - SMAAShader->GetVariableByName( "colorTex" )->AsShaderResource()->SetResource( nullptr ); + engine->GetContext()->PSSetShaderResources( 0, 3, NoSRV ); /** Copy back to main RTV */ engine->GetContext()->OMSetRenderTargets( 1, OldRTV.GetAddressOf(), nullptr ); - /*engine->GetContext()->OMSetRenderTargets(1, OldRTV.GetAddressOf(), nullptr); - engine->DrawSRVToBackbuffer(TempRTV->GetShaderResView()); - goto end;*/ - - Microsoft::WRL::ComPtr srv = TempRTV.GetShaderResView().Get(); - engine->GetContext()->PSSetShaderResources( 0, 1, srv.GetAddressOf() ); - + engine->GetContext()->PSSetShaderResources( 0, 1, TempRTV.GetShaderResView().GetAddressOf() ); if ( Engine::GAPI->GetRendererState().RendererSettings.SharpenFactor > 0.0f ) { auto sharpenPS = engine->GetShaderManager().GetPShader( "PS_PFX_Sharpen" ); diff --git a/D3D11Engine/D3D11PfxRenderer.cpp b/D3D11Engine/D3D11PfxRenderer.cpp index a07865c4..fd5f3080 100644 --- a/D3D11Engine/D3D11PfxRenderer.cpp +++ b/D3D11Engine/D3D11PfxRenderer.cpp @@ -117,7 +117,7 @@ XRESULT D3D11PfxRenderer::CopyTextureToRTV( const Microsoft::WRL::ComPtr 0 Shaders.push_back( ShaderInfo( "VS_PNAEN", "VS_PNAEN.hlsl", "v", 1 ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerFrame ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerInstance ) ); @@ -50,6 +51,7 @@ XRESULT D3D11ShaderManager::Init() { Shaders.push_back( ShaderInfo( "VS_PNAEN_Instanced", "VS_PNAEN_Instanced.hlsl", "v", 10 ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerFrame ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerInstance ) ); +#endif Shaders.push_back( ShaderInfo( "VS_Decal", "VS_Decal.hlsl", "v", 1 ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerFrame ) ); @@ -101,11 +103,12 @@ XRESULT D3D11ShaderManager::Init() { Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerInstanceSkeletal ) ); Shaders.back().cBufferSizes.push_back( NUM_MAX_BONES * sizeof( DirectX::XMFLOAT4X4 ) ); - +#if ENABLE_TESSELATION > 0 Shaders.push_back( ShaderInfo( "VS_PNAEN_Skeletal", "VS_PNAEN_Skeletal.hlsl", "v", 3 ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerFrame ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerInstanceSkeletal ) ); Shaders.back().cBufferSizes.push_back( NUM_MAX_BONES * sizeof( DirectX::XMFLOAT4X4 ) ); +#endif Shaders.push_back( ShaderInfo( "VS_TransformedEx", "VS_TransformedEx.hlsl", "v", 1 ) ); Shaders.back().cBufferSizes.push_back( 2 * sizeof( float2 ) ); @@ -464,11 +467,10 @@ XRESULT D3D11ShaderManager::Init() { Shaders.back().cBufferSizes.push_back( sizeof( DefaultHullShaderConstantBuffer ) ); Shaders.back().cBufferSizes.push_back( sizeof( OceanSettingsConstantBuffer ) ); +#if ENABLE_TESSELATION > 0 Shaders.push_back( ShaderInfo( "PNAEN_Tesselation", "PNAEN_Tesselation.hlsl", "hd" ) ); Shaders.back().cBufferSizes.push_back( sizeof( PNAENConstantBuffer ) ); - - Shaders.push_back( ShaderInfo( "Water_Tesselation", "Water_Tesselation.hlsl", "hd" ) ); - Shaders.back().cBufferSizes.push_back( sizeof( VisualTesselationSettings::Buffer ) ); +#endif } return XR_SUCCESS; diff --git a/D3D11Engine/GothicAPI.cpp b/D3D11Engine/GothicAPI.cpp index 6b6d09ee..79a783a1 100644 --- a/D3D11Engine/GothicAPI.cpp +++ b/D3D11Engine/GothicAPI.cpp @@ -67,7 +67,9 @@ void MaterialInfo::WriteToFile( const std::string& name ) { // Then the data fwrite( &buffer, sizeof( MaterialInfo::Buffer ), 1, f ); +#if ENABLE_TESSELATION > 0 fwrite( &TextureTesselationSettings.buffer, sizeof( VisualTesselationSettings::Buffer ), 1, f ); +#endif fclose( f ); } @@ -79,7 +81,11 @@ void MaterialInfo::LoadFromFile( const std::string& name ) { if ( !f ) return; +#if ENABLE_TESSELATION > 0 char ReadBuffer[sizeof( int ) + sizeof( MaterialInfo::Buffer ) + sizeof( VisualTesselationSettings::Buffer )]; +#else + char ReadBuffer[sizeof( int ) + sizeof( MaterialInfo::Buffer )]; +#endif fread( ReadBuffer, 1, sizeof( ReadBuffer ), f ); // Write the version first @@ -96,16 +102,20 @@ void MaterialInfo::LoadFromFile( const std::string& name ) { } } +#if ENABLE_TESSELATION > 0 if ( version >= 4 ) { memcpy( &TextureTesselationSettings.buffer, ReadBuffer + sizeof( int ) + sizeof( MaterialInfo::Buffer ), sizeof( VisualTesselationSettings::Buffer ) ); } +#endif fclose( f ); buffer.Color = float4( 1, 1, 1, 1 ); UpdateConstantbuffer(); +#if ENABLE_TESSELATION > 0 TextureTesselationSettings.UpdateConstantbuffer(); +#endif } /** creates/updates the constantbuffer */ @@ -177,6 +187,9 @@ bool GetPrivateProfileBoolA( /** Called when the game starts */ void GothicAPI::OnGameStart() { + // Get threadid of main thread here because DllMain can be called from different thread + MainThreadID = GetCurrentThreadId(); + LoadFixBinkValue(); LoadMenuSettings( MENU_SETTINGS_FILE ); @@ -284,15 +297,15 @@ void GothicAPI::OnWorldUpdate() { if ( !GMPModeActive ) { if ( IsCameraIndoor() ) { // Set mode to 2, which means we are indoors, but can see the outside - if ( zCSoundSystem::GetSoundSystem() ) - zCSoundSystem::GetSoundSystem()->SetGlobalReverbPreset( 2, 0.6f ); + if ( zCSoundSystem* sndSystem = zCSoundSystem::GetSoundSystem() ) + sndSystem->SetGlobalReverbPreset( 2, 0.6f ); if ( world && world->GetSkyControllerOutdoor() ) world->GetSkyControllerOutdoor()->SetCameraLocationHint( 1 ); } else { // Set mode to 0, which is the default - if ( zCSoundSystem::GetSoundSystem() ) - zCSoundSystem::GetSoundSystem()->SetGlobalReverbPreset( 0, 0.0f ); + if ( zCSoundSystem* sndSystem = zCSoundSystem::GetSoundSystem() ) + sndSystem->SetGlobalReverbPreset( 0, 0.0f ); if ( world && world->GetSkyControllerOutdoor() ) world->GetSkyControllerOutdoor()->SetCameraLocationHint( 0 ); @@ -300,25 +313,50 @@ void GothicAPI::OnWorldUpdate() { } // Do rain-effects - if ( world && world->GetSkyControllerOutdoor() && _canRain ) { - if( !RendererState.RendererSettings.EnableRain ) { + zCSkyController_Outdoor* skyController; + if ( world && (skyController = world->GetSkyControllerOutdoor()) != nullptr && _canRain ) { + bool outdoor = (LoadedWorldInfo->BspTree->GetBspTreeMode() == zBSP_MODE_OUTDOOR); + if ( RendererState.RendererSettings.AtmosphericScattering && outdoor ) { + float lastMasterTime = skyController->GetLastMasterTime(); + float masterTime = skyController->GetMasterTime(); + if ( (lastMasterTime - masterTime) > 0.95f && masterTime < 0.02f ) { +#ifndef BUILD_GOTHIC_1_08k + float timeStartRain = std::min( float( rand() ) / float( RAND_MAX ), 0.958f ); + float timeStopRain = std::min( timeStartRain + 0.042f + ( float( rand() ) / float( RAND_MAX ) * 0.06f ), 1.0f ); +#else + float timeStartRain = std::min( float( rand() ) / float( RAND_MAX ), 0.96f ); + float timeStopRain = std::min( timeStartRain + 0.04f + ( float( rand() ) / float( RAND_MAX ) * 0.04f ), 1.0f ); +#endif + int renderLightning = 0; + if ( skyController->GetRainingCounter() > 3 && ( float( rand() ) / float( RAND_MAX ) ) > 0.6f ) + renderLightning = 1; + + skyController->SetTimeStartRain( timeStartRain ); + skyController->SetTimeStopRain( timeStopRain ); + skyController->SetRenderLighting( renderLightning ); + } + + skyController->SetLastMasterTime( masterTime ); + } + + if( !RendererState.RendererSettings.EnableRain || !outdoor ) { #ifdef BUILD_GOTHIC_1_08k #ifdef BUILD_1_12F int skyEffects = *reinterpret_cast(0x887EDC); *reinterpret_cast(0x887EDC) = 0; - world->GetSkyControllerOutdoor()->ProcessRainFX(); + skyController->ProcessRainFX(); *reinterpret_cast(0x887EDC) = skyEffects; #else int skyEffects = *reinterpret_cast(0x8422A0); *reinterpret_cast(0x8422A0) = 0; - world->GetSkyControllerOutdoor()->ProcessRainFX(); + skyController->ProcessRainFX(); *reinterpret_cast(0x8422A0) = skyEffects; #endif #endif #ifdef BUILD_GOTHIC_2_6_fix int skyEffects = *reinterpret_cast(0x8A5DB0); *reinterpret_cast(0x8A5DB0) = 0; - world->GetSkyControllerOutdoor()->ProcessRainFX(); + skyController->ProcessRainFX(); *reinterpret_cast(0x8A5DB0) = skyEffects; #endif } else { @@ -326,25 +364,26 @@ void GothicAPI::OnWorldUpdate() { #ifdef BUILD_1_12F int skyEffects = *reinterpret_cast(0x887EDC); *reinterpret_cast(0x887EDC) = 1; - world->GetSkyControllerOutdoor()->ProcessRainFX(); + skyController->ProcessRainFX(); *reinterpret_cast(0x887EDC) = skyEffects; #else int skyEffects = *reinterpret_cast(0x8422A0); *reinterpret_cast(0x8422A0) = 1; - world->GetSkyControllerOutdoor()->ProcessRainFX(); + skyController->ProcessRainFX(); *reinterpret_cast(0x8422A0) = skyEffects; #endif #endif #ifdef BUILD_GOTHIC_2_6_fix int skyEffects = *reinterpret_cast(0x8A5DB0); *reinterpret_cast(0x8A5DB0) = 1; - world->GetSkyControllerOutdoor()->ProcessRainFX(); + skyController->ProcessRainFX(); *reinterpret_cast(0x8A5DB0) = skyEffects; #endif } } if ( !_canRain ) { + srand( time( nullptr ) ); _canRain = true; } @@ -628,7 +667,7 @@ void GothicAPI::OnGeometryLoaded( zCPolygon** polys, unsigned int numPolygons ) #endif LogInfo() << "Done extracting world!"; - +#if ENABLE_TESSELATION > 0 // Apply tesselation for ( auto const& it : LoadedMaterials ) { MaterialInfo* info = GetMaterialInfoFrom( it->GetTexture() ); @@ -636,6 +675,7 @@ void GothicAPI::OnGeometryLoaded( zCPolygon** polys, unsigned int numPolygons ) ApplyTesselationSettingsForAllMeshPartsUsing( info, info->TextureTesselationSettings.buffer.VT_TesselationFactor > 1.0f ? 2 : 1 ); } } +#endif } /** Called when the game is about to load a new level */ @@ -1341,8 +1381,10 @@ void GothicAPI::OnVisualDeleted( zCVisual* visual ) { }*/ } if ( list.size() > 0 ) { +#ifndef PUBLIC_RELEASE if ( RendererState.RendererSettings.EnableDebugLog ) LogInfo() << std::string( className ) << " had " + std::to_string( list.size() ) << " vobs"; +#endif VobsByVisual[visual].clear(); VobsByVisual.erase( visual ); @@ -3584,8 +3626,10 @@ void GothicAPI::LoadCustomZENResources() { // Load vegetation LoadVegetation( zen + ".veg" ); +#if ENABLE_TESSELATION > 0 // Load world mesh information LoadSectionInfos(); +#endif } /** Saves resources created for this .ZEN */ @@ -3618,8 +3662,10 @@ void GothicAPI::SaveCustomZENResources() { // Save vegetation SaveVegetation( zen + ".veg" ); +#if ENABLE_TESSELATION > 0 // Save world mesh information SaveSectionInfos(); +#endif } /** Applys the suppressed textures */ @@ -3927,8 +3973,10 @@ XRESULT GothicAPI::SaveMenuSettings( const std::string& file ) { WritePrivateProfileStringA( "HBAO", "SsaoBlurRadius", std::to_string( s.HbaoSettings.SsaoBlurRadius ).c_str(), ini.c_str() ); WritePrivateProfileStringA( "HBAO", "SsaoStepCount", std::to_string( s.HbaoSettings.SsaoStepCount ).c_str(), ini.c_str() ); +#if ENABLE_TESSELATION > 0 WritePrivateProfileStringA( "Tesselation", "EnableTesselation", std::to_string( s.EnableTesselation ? TRUE : FALSE ).c_str(), ini.c_str() ); WritePrivateProfileStringA( "Tesselation", "AllowWorldMeshTesselation", std::to_string( s.AllowWorldMeshTesselation ? TRUE : FALSE ).c_str(), ini.c_str() ); +#endif WritePrivateProfileStringA( "FontRendering", "Enable", std::to_string( s.EnableCustomFontRendering ? TRUE : FALSE ).c_str(), ini.c_str() ); @@ -4020,8 +4068,10 @@ XRESULT GothicAPI::LoadMenuSettings( const std::string& file ) { s.EnableSMAA = GetPrivateProfileBoolA( "SMAA", "Enabled", false, ini ); s.SharpenFactor = GetPrivateProfileFloatA( "SMAA", "SharpenFactor", 0.30f, ini ); +#if ENABLE_TESSELATION > 0 s.AllowWorldMeshTesselation = GetPrivateProfileBoolA( "Tesselation", "AllowWorldMeshTesselation", false, ini ); s.EnableTesselation = GetPrivateProfileBoolA( "Tesselation", "EnableTesselation", false, ini ); +#endif HBAOSettings defaultHBAOSettings; s.HbaoSettings.Enabled = GetPrivateProfileBoolA( "HBAO", "Enabled", defaultHBAOSettings.Enabled, ini ); @@ -4279,6 +4329,7 @@ bool GothicAPI::IsUnderWater() { return false; } +#if ENABLE_TESSELATION > 0 /** Saves all sections information */ void GothicAPI::SaveSectionInfos() { for ( auto&& itx : Engine::GAPI->GetWorldSections() ) { @@ -4300,6 +4351,7 @@ void GothicAPI::LoadSectionInfos() { } } } +#endif /** Returns if the given vob is registered in the world */ SkeletalVobInfo* GothicAPI::GetSkeletalVobByVob( zCVob* vob ) { @@ -4551,6 +4603,7 @@ void GothicAPI::PrintModInfo() { PrintMessageTimed( INT2( 5, 180 ), "Device: " + gpu ); } +#if ENABLE_TESSELATION > 0 /** Applies tesselation-settings for all mesh-parts using the given info */ void GothicAPI::ApplyTesselationSettingsForAllMeshPartsUsing( MaterialInfo* info, int amount ) { for ( std::map>::iterator itx = Engine::GAPI->GetWorldSections().begin(); itx != Engine::GAPI->GetWorldSections().end(); itx++ ) { @@ -4567,6 +4620,7 @@ void GothicAPI::ApplyTesselationSettingsForAllMeshPartsUsing( MaterialInfo* info } } } +#endif /** Returns the current weight of the rain-fx. The bigger value of ours and gothics is returned. */ float GothicAPI::GetRainFXWeight() { diff --git a/D3D11Engine/GothicAPI.h b/D3D11Engine/GothicAPI.h index 77baf8a8..60c82177 100644 --- a/D3D11Engine/GothicAPI.h +++ b/D3D11Engine/GothicAPI.h @@ -132,8 +132,10 @@ struct MaterialInfo { EMaterialType MaterialType; Buffer buffer; +#if ENABLE_TESSELATION > 0 /** Base tesselationsettings for this texture. Can be overwritten by ZEN-Resources */ VisualTesselationSettings TextureTesselationSettings; +#endif }; struct ParticleFrameData { @@ -331,11 +333,13 @@ class GothicAPI { /** Removes the given quadmark */ void RemoveQuadMark( zCQuadMark* mark ); +#if ENABLE_TESSELATION > 0 /** Saves all sections information */ void SaveSectionInfos(); /** Loads all sections information */ void LoadSectionInfos(); +#endif /** Returns wether the camera is underwater or not */ bool IsUnderWater(); @@ -389,8 +393,10 @@ class GothicAPI { /** Traces a visual info. Returns -1 if not hit, distance otherwise */ float TraceVisualInfo( const DirectX::XMFLOAT3& origin, const DirectX::XMFLOAT3& dir, BaseVisualInfo* visual, zCMaterial** hitMaterial = nullptr ); +#if ENABLE_TESSELATION > 0 /** Applies tesselation-settings for all mesh-parts using the given info */ void ApplyTesselationSettingsForAllMeshPartsUsing( MaterialInfo* info, int amount = 1 ); +#endif /** Returns the GSky-Object */ GSky* GetSky() const; diff --git a/D3D11Engine/GothicGraphicsState.h b/D3D11Engine/GothicGraphicsState.h index 7686c518..3db1e4a5 100644 --- a/D3D11Engine/GothicGraphicsState.h +++ b/D3D11Engine/GothicGraphicsState.h @@ -64,6 +64,11 @@ struct GothicGraphicsState { FF_AlphaRef = 0.5f; FF_GSwitches = 0; + + FF_Stages[0].ColorOp = FixedFunctionStage::EColorOp::CO_MODULATE; + FF_Stages[1].ColorOp = FixedFunctionStage::EColorOp::CO_DISABLE; + FF_Stages[0].ColorArg1 = FixedFunctionStage::ETextureArg::TA_TEXTURE; + FF_Stages[0].ColorArg2 = FixedFunctionStage::ETextureArg::TA_DIFFUSE; } /** Sets one of the GraphicsFlags */ @@ -596,9 +601,11 @@ struct GothicRendererSettings { SortRenderQueue = true; DrawThreaded = true; +#if ENABLE_TESSELATION > 0 EnableTesselation = false; AllowWorldMeshTesselation = false; TesselationFrustumCulling = true; +#endif EnablePointlightShadows = PLS_UPDATE_DYNAMIC; MinLightShadowUpdateRange = 300.0f; PartialDynamicShadowUpdates = true; @@ -697,9 +704,11 @@ struct GothicRendererSettings { E_HDRToneMap HDRToneMap; bool EnableVSync; bool EnableSMAA; +#if ENABLE_TESSELATION > 0 bool EnableTesselation; bool AllowWorldMeshTesselation; bool TesselationFrustumCulling; +#endif bool FastShadows; bool ReplaceSunDirection; bool AtmosphericScattering; diff --git a/D3D11Engine/GothicMemoryLocations1_08k.h b/D3D11Engine/GothicMemoryLocations1_08k.h index 2da2e10a..14691469 100644 --- a/D3D11Engine/GothicMemoryLocations1_08k.h +++ b/D3D11Engine/GothicMemoryLocations1_08k.h @@ -87,6 +87,7 @@ struct GothicMemoryLocations { //static const unsigned int Offset_Sun = 0x5F4; // First of the two planets static const unsigned int Offset_MasterTime = 0x6C; + static const unsigned int Offset_LastMasterTime = 0x70; static const unsigned int Offset_MasterState = 0x74; /*static const unsigned int Offset_SkyLayer1 = 0x5A8; static const unsigned int Offset_SkyLayer2 = 0x5C4; @@ -111,6 +112,8 @@ struct GothicMemoryLocations { static const unsigned int ProcessRainFX = 0x005C0DC0; static const unsigned int Offset_OutdoorRainFXWeight = 0x66C; + static const unsigned int Offset_TimeStartRain = 0x678; + static const unsigned int Offset_TimeStopRain = 0x67C; }; struct zCSkyController { diff --git a/D3D11Engine/GothicMemoryLocations1_12f.h b/D3D11Engine/GothicMemoryLocations1_12f.h index 35517e74..b5ad0c14 100644 --- a/D3D11Engine/GothicMemoryLocations1_12f.h +++ b/D3D11Engine/GothicMemoryLocations1_12f.h @@ -82,6 +82,7 @@ struct GothicMemoryLocations { static const unsigned int OBJ_ActivezCSkyController = 0x0099AC8C; static const unsigned int Offset_MasterTime = 0x6C; + static const unsigned int Offset_LastMasterTime = 0x70; static const unsigned int Offset_MasterState = 0x74; static const unsigned int GetUnderwaterFX = 0x5D8600; @@ -98,6 +99,8 @@ struct GothicMemoryLocations { static const unsigned int ProcessRainFX = 0x005DECA0; static const unsigned int Offset_OutdoorRainFXWeight = 0x66C; + static const unsigned int Offset_TimeStartRain = 0x678; + static const unsigned int Offset_TimeStopRain = 0x67C; }; struct zCSkyController { diff --git a/D3D11Engine/GothicMemoryLocations2_6_fix.h b/D3D11Engine/GothicMemoryLocations2_6_fix.h index fa0c231c..55c87686 100644 --- a/D3D11Engine/GothicMemoryLocations2_6_fix.h +++ b/D3D11Engine/GothicMemoryLocations2_6_fix.h @@ -124,6 +124,7 @@ struct GothicMemoryLocations { static const unsigned int Offset_Sun = 0x5F4; // First of the two planets static const unsigned int Offset_MasterTime = 0x80; + static const unsigned int Offset_LastMasterTime = 0x84; static const unsigned int Offset_MasterState = 0x88; static const unsigned int Offset_SkyLayer1 = 0x5A8; static const unsigned int Offset_SkyLayer2 = 0x5C4; @@ -147,6 +148,10 @@ struct GothicMemoryLocations { static const unsigned int ProcessRainFX = 0x005EAF30; static const unsigned int Offset_OutdoorRainFXWeight = 0x69C; + static const unsigned int Offset_TimeStartRain = 0x6A8; + static const unsigned int Offset_TimeStopRain = 0x6AC; + static const unsigned int Offset_RenderLightning = 0x6B0; + static const unsigned int Offset_RainingCounter = 0x6B8; }; struct zCSkyController { diff --git a/D3D11Engine/HookedFunctions.cpp b/D3D11Engine/HookedFunctions.cpp index b2a95282..102cd19a 100644 --- a/D3D11Engine/HookedFunctions.cpp +++ b/D3D11Engine/HookedFunctions.cpp @@ -32,10 +32,19 @@ #include "StackWalker.h" +bool IsRunningUnderUnion = false; + /** Init all hooks here */ void HookedFunctionInfo::InitHooks() { LogInfo() << "Initializing hooks"; + HMODULE shw32dll = GetModuleHandleA("shw32.dll"); + if ( shw32dll ) { + if ( GetProcAddress( shw32dll, "InitPatch" ) ) { + IsRunningUnderUnion = true; + } + } + oCGame::Hook(); zCBspTree::Hook(); zCWorld::Hook(); @@ -94,11 +103,11 @@ void HookedFunctionInfo::InitHooks() { PatchAddr( 0x007A4B08, "\xB8\x00\x00\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90\x90" ); LogInfo() << "Patching: Show correct savegame thumbnail"; - PatchAddr( 0x0042B4A7, "\x8B\xF8\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" );// - PatchAddr( 0x00438057, "\x89\x6C\x24\x10\xEB\x21" );// - PatchAddr( 0x004381D6, "\xEB\x07" );// - PatchAddr( 0x004381E1, "\x55" );// - PatchAddr( 0x00438218, "\xEB\x15" );// + PatchAddr( 0x0042B4A7, "\x8B\xF8\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" ); + PatchAddr( 0x00438057, "\x89\x6C\x24\x10\xEB\x21" ); + PatchAddr( 0x004381D6, "\xEB\x07" ); + PatchAddr( 0x004381E1, "\x55" ); + PatchAddr( 0x00438218, "\xEB\x15" ); #else LogInfo() << "Patching: BroadCast fix"; { @@ -186,6 +195,20 @@ void HookedFunctionInfo::InitHooks() { PatchAddr( 0x004342AA, "\xEB\x07" ); PatchAddr( 0x004342B5, "\x55" ); PatchAddr( 0x004342E0, "\xEB\x15" ); + + if ( !IsRunningUnderUnion ) { + LogInfo() << "Patching: Fix zFILE_VDFS class \"B: VFILE:\" error message due to LAAHack(4GB patch)"; + PatchAddr( 0x004451CF, "\xE9\xCF\x7E\x0A\x00\x90\x0F\x85\xFF\x00\x00\x00" ); + PatchAddr( 0x004ED0A3, "\x83\xBE\xFC\x29\x00\x00\xFF\xE9\x26\x81\xF5\xFF" ); + PatchAddr( 0x0044572C, "\x83\xBE\xFC\x29\x00\x00\xFF\x74\x3F\x90" ); + PatchAddr( 0x0044542B, "\x83\xBE\xFC\x29\x00\x00\xFF\x0F\x84\xBF\x02\x00\x00\x90" ); + PatchAddr( 0x004453E9, "\x83\xB9\xFC\x29\x00\x00\xFF\x74\x08\x90" ); + PatchAddr( 0x0044538C, "\x83\xBE\xFC\x29\x00\x00\xFF\x74\x3F\x90" ); + PatchAddr( 0x00445321, "\x83\xBE\xFC\x29\x00\x00\xFF\x74\x41\x90" ); + PatchAddr( 0x00444F70, "\x33\xC0\x83\xB9\xFC\x29\x00\x00\xFF\x0F\x95\xC0\x90" ); + PatchAddr( 0x004450CE, "\x83\xBE\xFC\x29\x00\x00\xFF\xEB\xAC\x90\x90\x90" ); + PatchAddr( 0x00445083, "\x0F\x84\xD6\x00\x00\x00\xEB\x4F" ); + } #endif #endif @@ -295,6 +318,22 @@ void HookedFunctionInfo::InitHooks() { PatchAddr( 0x0043728E, "\x55" ); PatchAddr( 0x004372B9, "\xEB\x15" ); + if ( !IsRunningUnderUnion ) { + LogInfo() << "Patching: Fix zFILE_VDFS class \"B: VFILE:\" error message due to LAAHack(4GB patch)"; + PatchAddr( 0x0044925F, "\xE9\x70\x8D\xFB\xFF\x90\x0F\x85\xFF\x00\x00\x00" ); + PatchAddr( 0x00401FD4, "\x83\xBE\xFC\x29\x00\x00\xFF\xE9\x85\x72\x04\x00" ); + PatchAddr( 0x00449A5C, "\x83\xBE\xFC\x29\x00\x00\xFF\x74\x3F\x90" ); + PatchAddr( 0x004494BB, "\x83\xBE\xFC\x29\x00\x00\xFF\x0F\x84\x7B\x03\x00\x00\x90" ); + PatchAddr( 0x00449479, "\x83\xB9\xFC\x29\x00\x00\xFF\x74\x08\x90" ); + PatchAddr( 0x0044941C, "\x83\xBE\xFC\x29\x00\x00\xFF\x74\x3F\x90" ); + PatchAddr( 0x004493B1, "\x83\xBE\xFC\x29\x00\x00\xFF\x74\x41\x90" ); + PatchAddr( 0x00449000, "\x33\xC0\x83\xB9\xFC\x29\x00\x00\xFF\x0F\x95\xC0\x90" ); + PatchAddr( 0x0044989F, "\x83\xBE\xFC\x29\x00\x00\xFF\xE9\xC9\x87\xFB\xFF" ); + PatchAddr( 0x00402074, "\x0F\x84\xAC\x79\x04\x00\xE9\x2C\x78\x04\x00" ); + PatchAddr( 0x0044915E, "\x83\xBE\xFC\x29\x00\x00\xFF\xEB\xAF\x90\x90\x90" ); + PatchAddr( 0x00449116, "\x0F\x84\xD3\x00\x00\x00\xEB\x4C" ); + } + // HACK Workaround to fix debuglines in godmode LogInfo() << "Patching: Godmode Debuglines"; // oCMagFrontier::GetDistanceNewWorld diff --git a/D3D11Engine/MeshModifier.cpp b/D3D11Engine/MeshModifier.cpp index 2e36852e..bfdb5deb 100644 --- a/D3D11Engine/MeshModifier.cpp +++ b/D3D11Engine/MeshModifier.cpp @@ -295,6 +295,7 @@ struct PNAENKeyHasher { }*/ }; +#if ENABLE_TESSELATION > 0 void MeshModifier::ComputePNAENIndices( const std::vector& inVertices, const std::vector& inIndices, std::vector& outIndices ) { std::vector ix; std::vector out; @@ -393,6 +394,7 @@ void MeshModifier::ComputePNAENIndices( const std::vector& inVer } } } +#endif // Helper struct which defines == for ExVertexStruct struct Vertex { @@ -474,6 +476,7 @@ struct Float3KeyHasher { } }; +#if ENABLE_TESSELATION > 0 void MeshModifier::ComputePNAEN18Indices( std::vector& inVertices, const std::vector& inIndices, std::vector& outIndices, bool detectBorders, bool softNormals ) { std::vector ix; std::vector out; @@ -715,7 +718,7 @@ void MeshModifier::ComputePNAEN18Indices( std::vector& inVertice } } } - +#endif bool TexcoordSame( float2 a, float2 b ) { if ( (abs( a.x - b.x ) > 0.001f && @@ -784,4 +787,4 @@ void MeshModifier::FillIndexArrayFor( unsigned int numVertices, std::vector& inVertices, const std::vector& inIndices, std::vector& outVertices, std::vector& outIndices ); +#if ENABLE_TESSELATION > 0 /** Computes PNAEN-Indices for the given mesh */ static void ComputePNAENIndices( const std::vector& inVertices, const std::vector& inIndices, std::vector& outIndices ); static void ComputePNAENIndices( const std::vector& inVertices, const std::vector& inIndices, std::vector& outIndices ); static void ComputePNAEN18Indices( std::vector& inVertices, const std::vector& inIndices, std::vector& outIndices, bool detectBorders = true, bool softNormals = false ); static void ComputePNAEN18Indices( std::vector& inVertices, const std::vector& inIndices, std::vector& outIndices, bool detectBorders = true, bool softNormals = false ); +#endif /** Fills an index array for a non-indexed mesh */ static void FillIndexArrayFor( unsigned int numVertices, std::vector& outIndices ); diff --git a/D3D11Engine/SV_GMeshInfoView.cpp b/D3D11Engine/SV_GMeshInfoView.cpp index 63f9f27e..4b6896a0 100644 --- a/D3D11Engine/SV_GMeshInfoView.cpp +++ b/D3D11Engine/SV_GMeshInfoView.cpp @@ -177,12 +177,15 @@ void SV_GMeshInfoView::DrawMeshes() { g->SetupVS_ExConstantBuffer(); g->SetupVS_ExPerInstanceConstantBuffer(); +#if ENABLE_TESSELATION > 0 VisualTesselationSettings* ts = nullptr; if ( VisualInfo ) ts = &VisualInfo->TesselationInfo; +#endif // Draw each texture for ( auto it = Meshes.cbegin(); it != Meshes.cend(); ++it ) { +#if ENABLE_TESSELATION > 0 // Set up tesselation if wanted if ( ts && !it->second->IndicesPNAEN.empty() && ts->buffer.VT_TesselationFactor > 0.0f ) { g->Setup_PNAEN( D3D11GraphicsEngine::PNAEN_Default ); @@ -194,7 +197,9 @@ void SV_GMeshInfoView::DrawMeshes() { it->first->Bind( 0 ); g->DrawVertexBufferIndexed( it->second->MeshVertexBuffer, it->second->MeshIndexBufferPNAEN, it->second->IndicesPNAEN.size() ); } - } else if ( VisualInfo ) { + } else if ( VisualInfo ) +#endif + { g->GetContext()->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); g->GetContext()->DSSetShader( nullptr, nullptr, 0 ); g->GetContext()->HSSetShader( nullptr, nullptr, 0 ); @@ -286,4 +291,4 @@ void SV_GMeshInfoView::GetObjectOrientation( float& yaw, float& pitch, float& di yaw = ObjectYaw; pitch = ObjectPitch; distance = ObjectDistance; -} \ No newline at end of file +} diff --git a/D3D11Engine/Shaders/DS_Defines.h b/D3D11Engine/Shaders/DS_Defines.h index 65c46398..34a95235 100644 --- a/D3D11Engine/Shaders/DS_Defines.h +++ b/D3D11Engine/Shaders/DS_Defines.h @@ -1,7 +1,8 @@ struct DEFERRED_PS_OUTPUT { float4 vDiffuse : SV_TARGET0; - float4 vNrm_SI_SP : SV_TARGET1; + float4 vNrm : SV_TARGET1; + float2 vSI_SP : SV_TARGET2; }; struct DEFERRED_PS_OUTPUT_ALPHA_TO_COVERAGE diff --git a/D3D11Engine/Shaders/PS_AtmosphereGround.hlsl b/D3D11Engine/Shaders/PS_AtmosphereGround.hlsl index b155a2fd..ce5bda2b 100644 --- a/D3D11Engine/Shaders/PS_AtmosphereGround.hlsl +++ b/D3D11Engine/Shaders/PS_AtmosphereGround.hlsl @@ -81,9 +81,11 @@ DEFERRED_PS_OUTPUT PSMain( PS_INPUT Input ) : SV_TARGET DEFERRED_PS_OUTPUT output; output.vDiffuse = float4(color.rgb, Input.vDiffuse.y); - output.vNrm_SI_SP.xy = EncodeNormal(nrm); - output.vNrm_SI_SP.z = MI_SpecularIntensity; - output.vNrm_SI_SP.w = MI_SpecularPower; + output.vNrm.xyz = nrm; + output.vNrm.w = 1.0f; + + output.vSI_SP.x = MI_SpecularIntensity; + output.vSI_SP.y = MI_SpecularPower; return output; } diff --git a/D3D11Engine/Shaders/PS_DS_AtmosphericScattering.hlsl b/D3D11Engine/Shaders/PS_DS_AtmosphericScattering.hlsl index 8a0986dc..58488883 100644 --- a/D3D11Engine/Shaders/PS_DS_AtmosphericScattering.hlsl +++ b/D3D11Engine/Shaders/PS_DS_AtmosphericScattering.hlsl @@ -36,13 +36,13 @@ SamplerState SS_Linear : register( s0 ); SamplerState SS_samMirror : register( s1 ); SamplerComparisonState SS_Comp : register( s2 ); Texture2D TX_Diffuse : register( t0 ); -Texture2D TX_Nrm_SI_SP : register( t1 ); +Texture2D TX_Nrm : register( t1 ); Texture2D TX_Depth : register( t2 ); Texture2D TX_Shadowmap : register( t3 ); Texture2D TX_RainShadowmap : register( t4 ); TextureCube TX_ReflectionCube : register( t5 ); Texture2D TX_Distortion : register( t6 ); - +Texture2D TX_SI_SP : register( t7 ); //-------------------------------------------------------------------------------------- // Input / Output structures @@ -303,18 +303,19 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET float vertLighting = diffuse.a; // Get the second GBuffer - float4 gb2 = TX_Nrm_SI_SP.Sample(SS_Linear, uv); + float4 gb2 = TX_Nrm.Sample(SS_Linear, uv); // If we dont have a normal, just return the diffuse color - if(abs(gb2.x + gb2.y) < 0.001f) + if(gb2.w < 0.001f) return float4(diffuse.rgb, 1); // Decode the view-space normal back - float3 normal = normalize(DecodeNormal(gb2.xy)); + float3 normal = normalize(gb2.xyz); // Get specular parameters - float specIntensity = gb2.z; - float specPower = gb2.w; + float4 gb3 = TX_SI_SP.Sample(SS_Linear, uv); + float specIntensity = gb3.x; + float specPower = gb3.y; // Reconstruct VS World Position from depth float expDepth = TX_Depth.Sample(SS_Linear, uv).r; @@ -362,7 +363,7 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET #endif // Compute specular lighting - float3 H = normalize(SQ_LightDirectionVS + V ); + float3 H = normalize(SQ_LightDirectionVS + V); float spec = CalcBlinnPhongLighting(normal, H); float specMod = pow(dot(float3(0.333f,0.333f,0.333f), diffuse.rgb), 2); @@ -396,7 +397,6 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET // Run scattering litPixel = ApplyAtmosphericScatteringGround(wsPosition, litPixel.rgb); - // Fix indoor stuff //litPixel = lerp(diffuse * vertLighting, litPixel, vertLighting < 0.9f ? 0 : 1); diff --git a/D3D11Engine/Shaders/PS_DS_PointLight.hlsl b/D3D11Engine/Shaders/PS_DS_PointLight.hlsl index 72622f4d..2fab7758 100644 --- a/D3D11Engine/Shaders/PS_DS_PointLight.hlsl +++ b/D3D11Engine/Shaders/PS_DS_PointLight.hlsl @@ -29,8 +29,9 @@ cbuffer DS_PointLightConstantBuffer : register( b0 ) SamplerState SS_Linear : register( s0 ); SamplerState SS_samMirror : register( s1 ); Texture2D TX_Diffuse : register( t0 ); -Texture2D TX_Nrm_SI_SP : register( t1 ); +Texture2D TX_Nrm : register( t1 ); Texture2D TX_Depth : register( t2 ); +Texture2D TX_SI_SP : register( t7 ); //-------------------------------------------------------------------------------------- // Input / Output structures @@ -103,14 +104,15 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET float4 diffuse = TX_Diffuse.Sample(SS_Linear, uv); // Get the second GBuffer - float4 gb2 = TX_Nrm_SI_SP.Sample(SS_Linear, uv); + float4 gb2 = TX_Nrm.Sample(SS_Linear, uv); // Decode the view-space normal back - float3 normal = normalize(DecodeNormal(gb2.xy)); + float3 normal = normalize(gb2.xyz); // Get specular parameters - float specIntensity = gb2.z; - float specPower = gb2.w; + float4 gb3 = TX_SI_SP.Sample(SS_Linear, uv); + float specIntensity = gb3.x; + float specPower = gb3.y; // Reconstruct VS World Position from depth float expDepth = TX_Depth.Sample(SS_Linear, uv).r; diff --git a/D3D11Engine/Shaders/PS_DS_PointLightDynShadow.hlsl b/D3D11Engine/Shaders/PS_DS_PointLightDynShadow.hlsl index 342b5376..de85d5a3 100644 --- a/D3D11Engine/Shaders/PS_DS_PointLightDynShadow.hlsl +++ b/D3D11Engine/Shaders/PS_DS_PointLightDynShadow.hlsl @@ -71,9 +71,10 @@ SamplerState SS_Linear : register( s0 ); SamplerState SS_samMirror : register( s1 ); SamplerComparisonState SS_Comp : register( s2 ); Texture2D TX_Diffuse : register( t0 ); -Texture2D TX_Nrm_SI_SP : register( t1 ); +Texture2D TX_Nrm : register( t1 ); Texture2D TX_Depth : register( t2 ); TextureCube TX_ShadowCube : register( t3 ); +Texture2D TX_SI_SP : register( t7 ); //-------------------------------------------------------------------------------------- // Input / Output structures @@ -145,14 +146,15 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET float4 diffuse = TX_Diffuse.Sample(SS_Linear, uv); // Get the second GBuffer - float4 gb2 = TX_Nrm_SI_SP.Sample(SS_Linear, uv); + float4 gb2 = TX_Nrm.Sample(SS_Linear, uv); // Decode the view-space normal back - float3 normal = normalize(DecodeNormal(gb2.xy)); + float3 normal = normalize(gb2.xyz); // Get specular parameters - float specIntensity = gb2.z; - float specPower = gb2.w; + float4 gb3 = TX_SI_SP.Sample(SS_Linear, uv); + float specIntensity = gb3.x; + float specPower = gb3.y; // Reconstruct VS World Position from depth float expDepth = TX_Depth.Sample(SS_Linear, uv).r; diff --git a/D3D11Engine/Shaders/PS_DS_SimpleSunlight.hlsl b/D3D11Engine/Shaders/PS_DS_SimpleSunlight.hlsl index d51575ce..7f3762e7 100644 --- a/D3D11Engine/Shaders/PS_DS_SimpleSunlight.hlsl +++ b/D3D11Engine/Shaders/PS_DS_SimpleSunlight.hlsl @@ -29,10 +29,10 @@ SamplerState SS_Linear : register( s0 ); SamplerState SS_samMirror : register( s1 ); SamplerComparisonState SS_Comp : register( s2 ); Texture2D TX_Diffuse : register( t0 ); -Texture2D TX_Nrm_SI_SP : register( t1 ); +Texture2D TX_Nrm : register( t1 ); Texture2D TX_Depth : register( t2 ); Texture2D TX_Shadowmap : register( t3 ); - +Texture2D TX_SI_SP : register( t7 ); @@ -80,15 +80,15 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET float vertLighting = diffuse.a; // Get the second GBuffer - float4 gb2 = TX_Nrm_SI_SP.Sample(SS_Linear, uv); + float4 gb2 = TX_Nrm.Sample(SS_Linear, uv); // Decode the view-space normal back - float3 normal = DecodeNormal(gb2.xy); - normal = normalize(normal); + float3 normal = normalize(gb2.xyz); // Get specular parameters - float specIntensity = gb2.z; - float specPower = gb2.w; + float4 gb3 = TX_SI_SP.Sample(SS_Linear, uv); + float specIntensity = gb3.x; + float specPower = gb3.y; // Reconstruct VS World Position from depth float expDepth = TX_Depth.Sample(SS_Linear, uv).r; diff --git a/D3D11Engine/Shaders/PS_Diffuse.hlsl b/D3D11Engine/Shaders/PS_Diffuse.hlsl index 941a7416..f50f5c9e 100644 --- a/D3D11Engine/Shaders/PS_Diffuse.hlsl +++ b/D3D11Engine/Shaders/PS_Diffuse.hlsl @@ -52,7 +52,6 @@ DEFERRED_PS_OUTPUT PSMain( PS_INPUT Input ) : SV_TARGET { float4 color = TX_Texture0.Sample(SS_Linear, Input.vTexcoord); - // Do alphatest if wanted #if ALPHATEST == 1 ClipDistanceEffect(length(Input.vViewPosition), DIST_DrawDistance, color.r * 2 - 1, 500.0f); @@ -60,31 +59,31 @@ DEFERRED_PS_OUTPUT PSMain( PS_INPUT Input ) : SV_TARGET // WorldMesh can always do the alphatest DoAlphaTest(color.a); #endif - - - + // Apply normalmapping if wanted #if NORMALMAPPING == 1 float3 nrm = perturb_normal(Input.vNormalVS, Input.vViewPosition, TX_Texture1, Input.vTexcoord, SS_Linear, MI_NormalmapStrength); #else float3 nrm = normalize(Input.vNormalVS); #endif - + float4 fx; #if FXMAP == 1 fx = TX_Texture2.Sample(SS_Linear, Input.vTexcoord); #else fx = 1.0f; #endif - + DEFERRED_PS_OUTPUT output; output.vDiffuse = float4(color.rgb, Input.vDiffuse.y); //output.vDiffuse = float4(Input.vTexcoord2, 0, 1); //output.vDiffuse = float4(Input.vNormalVS, 1); - output.vNrm_SI_SP.xy = EncodeNormal(nrm); - output.vNrm_SI_SP.z = MI_SpecularIntensity * fx.r; - output.vNrm_SI_SP.w = MI_SpecularPower * fx.g; + output.vNrm.xyz = nrm; + output.vNrm.w = 1.0f; + + output.vSI_SP.x = MI_SpecularIntensity * fx.r; + output.vSI_SP.y = MI_SpecularPower * fx.g; return output; } diff --git a/D3D11Engine/Shaders/PS_Grass.hlsl b/D3D11Engine/Shaders/PS_Grass.hlsl index bfc8d4b1..60948764 100644 --- a/D3D11Engine/Shaders/PS_Grass.hlsl +++ b/D3D11Engine/Shaders/PS_Grass.hlsl @@ -47,9 +47,10 @@ DEFERRED_PS_OUTPUT PSMain( PS_INPUT Input ) : SV_TARGET DEFERRED_PS_OUTPUT output; output.vDiffuse = float4(color.rgb, 1); - - output.vNrm_SI_SP.xy = EncodeNormal(normalize(Input.vNormalVS)); - output.vNrm_SI_SP.z = 0; - output.vNrm_SI_SP.w = 0; + + output.vNrm.xyz = normalize(Input.vNormalVS); + output.vNrm.w = 1.0f; + + output.vSI_SP.xy = 0; return output; } diff --git a/D3D11Engine/Shaders/PS_LPP_SunLight.hlsl b/D3D11Engine/Shaders/PS_LPP_SunLight.hlsl index ada37e19..2acb7232 100644 --- a/D3D11Engine/Shaders/PS_LPP_SunLight.hlsl +++ b/D3D11Engine/Shaders/PS_LPP_SunLight.hlsl @@ -57,8 +57,7 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET float4 gb2 = TX_Nrm_SI_SP.Sample(SS_Linear, uv); // Decode the view-space normal back - float3 normal = DecodeNormal(gb2.xy); - normal = normalize(normal); + float3 normal = normalize(gb2.xyz); // Get specular parameters float specIntensity = gb2.z; diff --git a/D3D11Engine/Shaders/PS_Ocean.hlsl b/D3D11Engine/Shaders/PS_Ocean.hlsl index b7db378a..09c8c61f 100644 --- a/D3D11Engine/Shaders/PS_Ocean.hlsl +++ b/D3D11Engine/Shaders/PS_Ocean.hlsl @@ -176,8 +176,10 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET DEFERRED_PS_OUTPUT output; output.vDiffuse = float4(color.rgb, 1.0f); - output.vNrm_SI_SP.xy = 0.0f;//EncodeNormal(normalize(Input.vNormalVS)); - output.vNrm_SI_SP.z = 1.0f; - output.vNrm_SI_SP.w = OS_SpecularPower; + output.vNrm.xyz = 0.0f;//normalize(Input.vNormalVS); + output.vNrm.w = 1.0f; + + output.vSI_SP.x = 1.0f; + output.vSI_SP.y = OS_SpecularPower; return output;*/ } diff --git a/D3D11Engine/Shaders/PS_PFX_ApplyWettness.hlsl b/D3D11Engine/Shaders/PS_PFX_ApplyWettness.hlsl index cdfedb6c..519ad3b0 100644 --- a/D3D11Engine/Shaders/PS_PFX_ApplyWettness.hlsl +++ b/D3D11Engine/Shaders/PS_PFX_ApplyWettness.hlsl @@ -55,7 +55,7 @@ float4 PSMain( PS_INPUT Input ) : SV_TARGET float3 V = normalize(-vsPosition); // Decode the view-space normal back - float3 normal = normalize(DecodeNormal(gb2.xy)); + float3 normal = normalize(gb2.xyz); float fresnel = pow(1.0f - max(0.0f, dot(normal, V)), 10.0f); litPixel += lerp(fresnel * litPixel * 0.5f, 0.0f, sun); diff --git a/D3D11Engine/Shaders/PS_PFX_GodRayMask.hlsl b/D3D11Engine/Shaders/PS_PFX_GodRayMask.hlsl index 4e144ea4..864876a6 100644 --- a/D3D11Engine/Shaders/PS_PFX_GodRayMask.hlsl +++ b/D3D11Engine/Shaders/PS_PFX_GodRayMask.hlsl @@ -26,9 +26,9 @@ struct PS_INPUT float4 PSMain( PS_INPUT Input ) : SV_TARGET { float4 color = TX_Texture0.Sample(SS_Linear, Input.vTexcoord); - float2 gb2 = TX_Texture1.Sample(SS_Linear, Input.vTexcoord); // If this has the length of 0 (normals), it's part of the sky + float4 gb2 = TX_Texture1.Sample(SS_Linear, Input.vTexcoord); - if(abs(gb2.x + gb2.y) < 0.001f) + if(gb2.w < 0.001f) return color; return float4(0,0,0,0); diff --git a/D3D11Engine/Shaders/PS_World.hlsl b/D3D11Engine/Shaders/PS_World.hlsl index fee7840a..3e4718f5 100644 --- a/D3D11Engine/Shaders/PS_World.hlsl +++ b/D3D11Engine/Shaders/PS_World.hlsl @@ -58,14 +58,14 @@ DEFERRED_PS_OUTPUT PSMain( PS_INPUT Input ) : SV_TARGET // WorldMesh can always do the alphatest DoAlphaTest(color.a); - - + DEFERRED_PS_OUTPUT output; output.vDiffuse = float4(color.rgb, Input.vDiffuse.y); - + + output.vNrm.xyz = normalize(Input.vNormalVS); + output.vNrm.w = 1.0f; - output.vNrm_SI_SP.xy = EncodeNormal(normalize(Input.vNormalVS)); - output.vNrm_SI_SP.z = MI_SpecularIntensity; - output.vNrm_SI_SP.w = MI_SpecularPower; + output.vSI_SP.x = MI_SpecularIntensity; + output.vSI_SP.y = MI_SpecularPower; return output; } diff --git a/D3D11Engine/Shaders/PS_WorldPOM.hlsl b/D3D11Engine/Shaders/PS_WorldPOM.hlsl index 217e00d0..62d2ce5b 100644 --- a/D3D11Engine/Shaders/PS_WorldPOM.hlsl +++ b/D3D11Engine/Shaders/PS_WorldPOM.hlsl @@ -285,9 +285,11 @@ DEFERRED_PS_OUTPUT PSMain( PS_INPUT Input ) : SV_TARGET DEFERRED_PS_OUTPUT output; output.vDiffuse = float4(color.rgb, Input.vDiffuse.y * OS_AmbientColor.y); - output.vNrm_SI_SP.xy = EncodeNormal(nrm); - output.vNrm_SI_SP.z = MI_SpecularIntensity; - output.vNrm_SI_SP.w = MI_SpecularPower; + output.vNrm.xyz = nrm; + output.vNrm.w = 1.0f; + + output.vSI_SP.x = MI_SpecularIntensity; + output.vSI_SP.y = MI_SpecularPower; return output; } diff --git a/D3D11Engine/Shaders/PS_WorldTriplanar.hlsl b/D3D11Engine/Shaders/PS_WorldTriplanar.hlsl index ef00276a..4fd44b9a 100644 --- a/D3D11Engine/Shaders/PS_WorldTriplanar.hlsl +++ b/D3D11Engine/Shaders/PS_WorldTriplanar.hlsl @@ -75,8 +75,10 @@ DEFERRED_PS_OUTPUT PSMain( PS_INPUT Input ) : SV_TARGET output.vDiffuse = float4(tex, Input.vDiffuse.y); //output.vDiffuse = 1.0f; //output.vDiffuse.rgb = bump; - output.vNrm_SI_SP.xy = EncodeNormal(normalize(bump)); - output.vNrm_SI_SP.z = MI_SpecularIntensity; - output.vNrm_SI_SP.w = MI_SpecularPower; + output.vNrm.xyz = normalize(bump); + output.vNrm.w = 1.0f; + + output.vSI_SP.x = MI_SpecularIntensity; + output.vSI_SP.y = MI_SpecularPower; return output; } diff --git a/D3D11Engine/WorldConverter.cpp b/D3D11Engine/WorldConverter.cpp index f9beeb6a..4b347857 100644 --- a/D3D11Engine/WorldConverter.cpp +++ b/D3D11Engine/WorldConverter.cpp @@ -331,198 +331,6 @@ XRESULT WorldConverter::LoadWorldMeshFromFile( const std::string& file, std::map return XR_SUCCESS; } -/** Converts the worldmesh into a PNAEN-buffer */ -HRESULT WorldConverter::ConvertWorldMeshPNAEN( zCPolygon** polys, unsigned int numPolygons, std::map>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh ) { - // Go through every polygon and put it into it's section - for ( unsigned int i = 0; i < numPolygons; i++ ) { - zCPolygon* poly = polys[i]; - - // Check if we even need this polygon - if ( poly->GetPolyFlags()->GhostOccluder || - poly->GetPolyFlags()->PortalPoly ) - continue; - - // Use the section of the first point for the whole polygon - INT2 section = GetSectionOfPos( *poly->getVertices()[0]->Position.toXMFLOAT3() ); - (*outSections)[section.x][section.y].WorldCoordinates = section; - - XMFLOAT3& bbmin = (*outSections)[section.x][section.y].BoundingBox.Min; - XMFLOAT3& bbmax = (*outSections)[section.x][section.y].BoundingBox.Max; - - DWORD sectionColor = float4( (section.x % 2) + 0.5f, (section.x % 2) + 0.5f, 1, 1 ).ToDWORD(); - - if ( poly->GetNumPolyVertices() < 3 ) { - LogWarn() << "Poly with less than 3 vertices!"; - } - - // Extract poly vertices - std::vector polyVertices; - for ( int v = 0; v < poly->GetNumPolyVertices(); v++ ) { - ExVertexStruct t; - t.Position = poly->getVertices()[v]->Position; - t.TexCoord = poly->getFeatures()[v]->texCoord; - t.Normal = poly->getFeatures()[v]->normal; - t.Color = poly->getFeatures()[v]->lightStatic; - - // Check bounding box - bbmin.x = bbmin.x > poly->getVertices()[v]->Position.x ? poly->getVertices()[v]->Position.x : bbmin.x; - bbmin.y = bbmin.y > poly->getVertices()[v]->Position.y ? poly->getVertices()[v]->Position.y : bbmin.y; - bbmin.z = bbmin.z > poly->getVertices()[v]->Position.z ? poly->getVertices()[v]->Position.z : bbmin.z; - - bbmax.x = bbmax.x < poly->getVertices()[v]->Position.x ? poly->getVertices()[v]->Position.x : bbmax.x; - bbmax.y = bbmax.y < poly->getVertices()[v]->Position.y ? poly->getVertices()[v]->Position.y : bbmax.y; - bbmax.z = bbmax.z < poly->getVertices()[v]->Position.z ? poly->getVertices()[v]->Position.z : bbmax.z; - - if ( poly->GetLightmap() ) { - t.TexCoord2 = poly->GetLightmap()->GetLightmapUV( *t.Position.toXMFLOAT3() ); - t.Color = DEFAULT_LIGHTMAP_POLY_COLOR; - } else { - t.Color = 0xFFFFFFFF; - t.TexCoord2.x = 0.0f; - t.TexCoord2.y = 0.0f; - - if ( poly->GetMaterial() && poly->GetMaterial()->GetMatGroup() == zMAT_GROUP_WATER ) { - t.Normal = float3( 0, 1, 0 ); // Get rid of ugly shadows on water - // Static light generated for water sucks and we can't use it to block the sun specular lighting - // so we'll limit ourselves to only block it in indoor locations - t.Color = 0xFFFFFFFF; - } - } - - polyVertices.emplace_back( t ); - } - - // Use the map to put the polygon to those using the same material - - zCMaterial* mat = poly->GetMaterial(); - MeshKey key; - key.Texture = mat != nullptr ? mat->GetTextureSingle() : nullptr; - key.Material = mat; - - //key.Lightmap = poly->GetLightmap(); - - if ( (*outSections)[section.x][section.y].WorldMeshes.count( key ) == 0 ) { - key.Info = Engine::GAPI->GetMaterialInfoFrom( key.Texture ); - (*outSections)[section.x][section.y].WorldMeshes[key] = new WorldMeshInfo; - } - - //std::vector TriangleVertices; - std::vector finalVertices; - TriangleFanToList( &polyVertices[0], polyVertices.size(), &finalVertices ); - - //if (mat && mat->GetTexture()) - // LogInfo() << "Got texture name: " << mat->GetTexture()->GetName(); - - if ( poly->GetMaterial() && poly->GetMaterial()->GetMatGroup() == zMAT_GROUP_WATER ) { - // Give water surfaces a water-shader - MaterialInfo* polyInfo = Engine::GAPI->GetMaterialInfoFrom( poly->GetMaterial()->GetTextureSingle() ); - if ( polyInfo ) { - polyInfo->PixelShader = "PS_Water"; - polyInfo->MaterialType = MaterialInfo::MT_Water; - } - } - - for ( unsigned int v = 0; v < finalVertices.size(); v++ ) - (*outSections)[section.x][section.y].WorldMeshes[key]->Vertices.emplace_back( finalVertices[v] ); - } - - XMVECTOR avgSections = XMVectorZero(); - int numSections = 0; - - std::list*> vertexBuffers; - std::list*> indexBuffers; - - // Create the vertexbuffers for every material - for ( auto const& itx : *outSections ) { - for ( auto const& ity : itx.second ) { - numSections++; - avgSections += XMVectorSet( (float)itx.first, (float)ity.first, 0, 0 ); - - for ( auto const& it : ity.second.WorldMeshes ) { - std::vector indexedVertices; - std::vector indices; - IndexVertices( &it.second->Vertices[0], it.second->Vertices.size(), indexedVertices, indices ); - - // Generate normals - GenerateVertexNormals( it.second->Vertices, it.second->Indices ); - - std::vector indicesPNAEN; // Use PNAEN to detect the borders of the mesh - MeshModifier::ComputePNAEN18Indices( indexedVertices, indices, indicesPNAEN ); - - it.second->Vertices = indexedVertices; - it.second->Indices = indicesPNAEN; - - // Create the buffers - Engine::GraphicsEngine->CreateVertexBuffer( &it.second->MeshVertexBuffer ); - Engine::GraphicsEngine->CreateVertexBuffer( &it.second->MeshIndexBuffer ); - - // Init and fill them - it.second->MeshVertexBuffer->Init( &it.second->Vertices[0], it.second->Vertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - it.second->MeshIndexBuffer->Init( &it.second->Indices[0], it.second->Indices.size() * sizeof( VERTEX_INDEX ), D3D11VertexBuffer::B_INDEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - - // Remember them, to wrap then up later - vertexBuffers.emplace_back( &it.second->Vertices ); - indexBuffers.emplace_back( &it.second->Indices ); - } - } - } - - std::vector wrappedVertices; - std::vector wrappedIndicesSimple; - std::vector wrappedIndicesPNAEN; - std::vector offsets; - - // Calculate fat vertexbuffer - WorldConverter::WrapVertexBuffers( vertexBuffers, indexBuffers, wrappedVertices, wrappedIndicesSimple, offsets ); - - for ( unsigned int i = 0; i < offsets.size(); i++ ) { - offsets[i] *= 6; - } - - // Run PNAEN on that - MeshModifier::ComputePNAEN18Indices( wrappedVertices, wrappedIndicesSimple, wrappedIndicesPNAEN, false ); - - // Generate smooth normals - //MeshModifier::ComputeSmoothNormals(wrappedVertices); - - // Propergate the offsets - int i = 0; - for ( auto const& itx : *outSections ) { - for ( auto const& ity : itx.second ) { - for ( auto const& it : ity.second.WorldMeshes ) { - MaterialInfo* info = Engine::GAPI->GetMaterialInfoFrom( it.first.Texture ); - info->TesselationShaderPair = "PNAEN_Tesselation"; - - it.second->BaseIndexLocation = offsets[i]; - - i++; - } - } - } - - // Create the buffers for wrapped mesh - MeshInfo* wmi = new MeshInfo; - Engine::GraphicsEngine->CreateVertexBuffer( &wmi->MeshVertexBuffer ); - Engine::GraphicsEngine->CreateVertexBuffer( &wmi->MeshIndexBuffer ); - - // Init and fill them - wmi->MeshVertexBuffer->Init( &wrappedVertices[0], wrappedVertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - wmi->MeshIndexBuffer->Init( &wrappedIndicesPNAEN[0], wrappedIndicesPNAEN.size() * sizeof( unsigned int ), D3D11VertexBuffer::B_INDEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - - *outWrappedMesh = wmi; - - // Calculate the approx midpoint of the world - avgSections /= (float)numSections; - - if ( info ) { - XMStoreFloat2( &info->MidPoint, avgSections * WORLD_SECTION_SIZE ); - info->LowestVertex = 0; - info->HighestVertex = 0; - } - - return XR_SUCCESS; -} - bool AdditionalCheckWaterFall(zCTexture* texture) { std::string textureName = texture->GetNameWithoutExt(); @@ -1059,9 +867,9 @@ void WorldConverter::ExtractSkeletalMeshFromVob( zCModel* model, SkeletalMeshVis } } - static int s_NoMeshesNum = 0; - skeletalMeshInfo->VisualName = model->GetVisualName(); + +#if ENABLE_TESSELATION > 0 // Try to load saved settings for this mesh skeletalMeshInfo->LoadMeshVisualInfo( skeletalMeshInfo->VisualName ); @@ -1070,6 +878,7 @@ void WorldConverter::ExtractSkeletalMeshFromVob( zCModel* model, SkeletalMeshVis && Engine::GAPI->GetRendererState().RendererSettings.AllowWorldMeshTesselation ) // TODO: PNAEN for skeletals causes huge lags in the game and is barely // noticable anyways. Disable for now. skeletalMeshInfo->CreatePNAENInfo( skeletalMeshInfo->TesselationInfo.buffer.VT_DisplacementStrength > 0.0f ); +#endif } /** Extracts a zCProgMeshProto from a zCModel */ @@ -1227,13 +1036,14 @@ void WorldConverter::ExtractProgMeshProtoFromModel( zCModel* model, MeshVisualIn meshInfo->Visual = model; meshInfo->VisualName = visualName; +#if ENABLE_TESSELATION > 0 // Try to load saved settings for this mesh meshInfo->LoadMeshVisualInfo( meshInfo->VisualName ); // Create additional information if ( meshInfo->TesselationInfo.buffer.VT_TesselationFactor > 0.0f ) meshInfo->CreatePNAENInfo( meshInfo->TesselationInfo.buffer.VT_DisplacementStrength > 0.0f ); - +#endif mds.Delete(); } @@ -1329,132 +1139,6 @@ void WorldConverter::ExtractNodeVisual( int index, zCModelNodeInst* node, std::m } } -/** Extracts a 3DS-Mesh from a zCVisual */ -void WorldConverter::Extract3DSMeshFromVisual2PNAEN( zCProgMeshProto* visual, MeshVisualInfo* meshInfo ) { - XMFLOAT3 bbmin = XMFLOAT3( FLT_MAX, FLT_MAX, FLT_MAX ); - XMFLOAT3 bbmax = XMFLOAT3( -FLT_MAX, -FLT_MAX, -FLT_MAX ); - - XMFLOAT3* posList = (XMFLOAT3*)visual->GetPositionList()->Array; - - std::list*> vertexBuffers; - std::list*> indexBuffers; - std::list meshInfos; - - // Construct unindexed mesh - for ( int i = 0; i < visual->GetNumSubmeshes(); i++ ) { - std::vector vertices; - std::vector indices; - - // Get vertices - for ( int t = 0; t < visual->GetSubmeshes()[i].TriList.NumInArray; t++ ) { - indices.emplace_back( visual->GetSubmeshes()[i].TriList.Array[t].wedge[2] ); - indices.emplace_back( visual->GetSubmeshes()[i].TriList.Array[t].wedge[1] ); - indices.emplace_back( visual->GetSubmeshes()[i].TriList.Array[t].wedge[0] ); - } - - for ( int v = 0; v < visual->GetSubmeshes()[i].WedgeList.NumInArray; v++ ) { - ExVertexStruct vx; - vx.Position = posList[visual->GetSubmeshes()[i].WedgeList.Array[v].position]; - vx.TexCoord = visual->GetSubmeshes()[i].WedgeList.Array[v].texUV; - vx.Color = 0xFFFFFFFF; - vx.Normal = visual->GetSubmeshes()[i].WedgeList.Array[v].normal; - - vertices.emplace_back( vx ); - - // Check bounding box - bbmin.x = bbmin.x > vx.Position.x ? vx.Position.x : bbmin.x; - bbmin.y = bbmin.y > vx.Position.y ? vx.Position.y : bbmin.y; - bbmin.z = bbmin.z > vx.Position.z ? vx.Position.z : bbmin.z; - - bbmax.x = bbmax.x < vx.Position.x ? vx.Position.x : bbmax.x; - bbmax.y = bbmax.y < vx.Position.y ? vx.Position.y : bbmax.y; - bbmax.z = bbmax.z < vx.Position.z ? vx.Position.z : bbmax.z; - } - - // Create the buffers and sort the mesh into the structure - MeshInfo* mi = new MeshInfo; - - // Create the indexed mesh - std::vector ixVertices; - std::vector ixIndices; - - if ( vertices.empty() ) - return; - - // ** PNAEN ** - MeshModifier::ComputePNAEN18Indices( vertices, indices, mi->Indices ); - mi->Vertices = vertices; - - - // Create the buffers - Engine::GraphicsEngine->CreateVertexBuffer( &mi->MeshVertexBuffer ); - Engine::GraphicsEngine->CreateVertexBuffer( &mi->MeshIndexBuffer ); - - // Init and fill it - mi->MeshVertexBuffer->Init( &mi->Vertices[0], mi->Vertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - mi->MeshIndexBuffer->Init( &mi->Indices[0], mi->Indices.size() * sizeof( VERTEX_INDEX ), D3D11VertexBuffer::B_INDEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - - Engine::GAPI->GetRendererState().RendererInfo.VOBVerticesDataSize += mi->Vertices.size() * sizeof( ExVertexStruct ); - Engine::GAPI->GetRendererState().RendererInfo.VOBVerticesDataSize += mi->Indices.size() * sizeof( VERTEX_INDEX ); - - zCMaterial* mat = visual->GetSubmesh( i )->Material; - meshInfo->Meshes[mat].emplace_back( mi ); - - MeshKey key; - key.Material = mat; - key.Texture = mat->GetTextureSingle(); - key.Info = Engine::GAPI->GetMaterialInfoFrom( key.Texture ); - - // ** PNAEN ** - key.Info->TesselationShaderPair = "PNAEN_Tesselation"; - - meshInfo->MeshesByTexture[key].emplace_back( mi ); - - vertexBuffers.emplace_back( &mi->Vertices ); - indexBuffers.emplace_back( &mi->Indices ); - meshInfos.emplace_back( mi ); - } - - std::vector wrappedVertices; - std::vector wrappedIndices; - std::vector wrappedIndicesPNAEN; - std::vector offsets; - - // Calculate fat vertexbuffer - WorldConverter::WrapVertexBuffers( vertexBuffers, indexBuffers, wrappedVertices, wrappedIndices, offsets ); - - MeshModifier::ComputePNAEN18Indices( wrappedVertices, wrappedIndices, wrappedIndicesPNAEN ); - - // Propergate the offsets - int i = 0; - for ( auto const& it : meshInfos ) { - it->BaseIndexLocation = offsets[i] * 6; - - i++; - } - - MeshInfo* wmi = new MeshInfo; - Engine::GraphicsEngine->CreateVertexBuffer( &wmi->MeshVertexBuffer ); - Engine::GraphicsEngine->CreateVertexBuffer( &wmi->MeshIndexBuffer ); - - - - // Init and fill them - wmi->MeshVertexBuffer->Init( &wrappedVertices[0], wrappedVertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - wmi->MeshIndexBuffer->Init( &wrappedIndicesPNAEN[0], wrappedIndicesPNAEN.size() * sizeof( unsigned int ), D3D11VertexBuffer::B_INDEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); - - meshInfo->FullMesh = wmi; - - - - meshInfo->BBox.Min = bbmin; - meshInfo->BBox.Max = bbmax; - XMStoreFloat( &meshInfo->MeshSize, XMVector3Length( XMLoadFloat3( &bbmin ) - XMLoadFloat3( &bbmax ) ) ); - XMStoreFloat3( &meshInfo->MidPoint, 0.5f * (XMLoadFloat3( &bbmin ) + XMLoadFloat3( &bbmax )) ); - - meshInfo->Visual = visual; -} - /** Updates a Morph-Mesh visual */ void WorldConverter::UpdateMorphMeshVisual( void* v, MeshVisualInfo* meshInfo ) { zCMorphMesh* visual = (zCMorphMesh*)v; @@ -1567,7 +1251,7 @@ void WorldConverter::Extract3DSMeshFromVisual2( zCProgMeshProto* visual, MeshVis mi->MeshVertexBuffer->Init( &mi->Vertices[0], mi->Vertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_DYNAMIC, D3D11VertexBuffer::CA_WRITE ); } else { // Optimize faces - mi->MeshVertexBuffer->OptimizeFaces( &mi->Indices[0], + mi->MeshVertexBuffer->OptimizeFaces(&mi->Indices[0], (byte*)&mi->Vertices[0], mi->Indices.size(), mi->Vertices.size(), @@ -1638,18 +1322,18 @@ void WorldConverter::Extract3DSMeshFromVisual2( zCProgMeshProto* visual, MeshVis meshInfo->Visual = visual; meshInfo->VisualName = visual->GetObjectName(); +#if ENABLE_TESSELATION > 0 // Try to load saved settings for this mesh meshInfo->LoadMeshVisualInfo( meshInfo->VisualName ); // Create additional information if ( meshInfo->TesselationInfo.buffer.VT_TesselationFactor > 0.0f ) meshInfo->CreatePNAENInfo( meshInfo->TesselationInfo.buffer.VT_DisplacementStrength > 0.0f ); +#endif } - const float eps = 0.001f; - struct CmpClass // class comparing vertices in the set { bool operator() ( const std::pair& p1, const std::pair& p2 ) const { @@ -1664,8 +1348,6 @@ struct CmpClass // class comparing vertices in the set } }; - - /** Indexes the given vertex array */ void WorldConverter::IndexVertices( ExVertexStruct* input, unsigned int numInputVertices, std::vector& outVertices, std::vector& outIndices ) { std::set, CmpClass> vertices; @@ -1777,6 +1459,7 @@ void WorldConverter::GenerateVertexNormals( std::vector& vertice } } +#if ENABLE_TESSELATION > 0 ExVertexStruct TessTriLerpVertex( ExVertexStruct& a, ExVertexStruct& b, float w ) { ExVertexStruct v; FXMVECTOR XMV_w = XMVectorSet( w, w, w, 0 ); @@ -1828,6 +1511,7 @@ void WorldConverter::TesselateTriangle( ExVertexStruct* tri, std::vector& vertices, std::vector& indices ) { @@ -1950,6 +1634,7 @@ void WorldConverter::UpdateQuadMarkInfo( QuadMarkInfo* info, zCQuadMark* mark, c info->Position = position; } +#if ENABLE_TESSELATION > 0 /** Turns a MeshInfo into PNAEN */ void WorldConverter::CreatePNAENInfoFor( MeshInfo* mesh, bool softNormals ) { delete mesh->MeshIndexBufferPNAEN; @@ -1965,7 +1650,6 @@ void WorldConverter::CreatePNAENInfoFor( MeshInfo* mesh, bool softNormals ) { mesh->MeshVertexBuffer->Init( &mesh->VerticesPNAEN[0], mesh->VerticesPNAEN.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); } - void WorldConverter::CreatePNAENInfoFor( WorldMeshInfo* mesh, bool softNormals ) { delete mesh->MeshIndexBufferPNAEN; Engine::GraphicsEngine->CreateVertexBuffer( &mesh->MeshIndexBufferPNAEN ); @@ -2011,6 +1695,7 @@ void WorldConverter::CreatePNAENInfoFor( SkeletalMeshInfo* mesh, MeshInfo* bindP mesh->MeshVertexBuffer->Init( &mesh->Vertices[0], mesh->Vertices.size() * sizeof( ExSkelVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); bindPoseMesh->MeshVertexBuffer->Init( &bindPoseMesh->VerticesPNAEN[0], bindPoseMesh->VerticesPNAEN.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE ); } +#endif /** Converts ExVertexStruct into a zCPolygon*-Attay */ void WorldConverter::ConvertExVerticesTozCPolygons( const std::vector& vertices, const std::vector& indices, zCMaterial* material, std::vector& polyArray ) { @@ -2051,6 +1736,7 @@ void WorldConverter::ConvertExVerticesTozCPolygons( const std::vector 0 /** Tesselates the given mesh the given amount of times */ void WorldConverter::TesselateMesh( WorldMeshInfo* mesh, int amount ) { // Copy old vertices so we can directly write to the vectors again @@ -2066,7 +1752,6 @@ void WorldConverter::TesselateMesh( WorldMeshInfo* mesh, int amount ) { vx[1] = mesh->Vertices[mesh->Indices[i + 1]]; vx[2] = mesh->Vertices[mesh->Indices[i + 2]]; - std::vector triTess; WorldConverter::TesselateTriangle( vx, triTess, 1 ); @@ -2112,3 +1797,4 @@ void WorldConverter::TesselateMesh( WorldMeshInfo* mesh, int amount ) { // Mark dirty mesh->SaveInfo = true; } +#endif diff --git a/D3D11Engine/WorldConverter.h b/D3D11Engine/WorldConverter.h index 068f40e1..fe05e383 100644 --- a/D3D11Engine/WorldConverter.h +++ b/D3D11Engine/WorldConverter.h @@ -35,9 +35,6 @@ class WorldConverter { /** Converts the worldmesh into a more usable format */ static HRESULT ConvertWorldMesh( zCPolygon** polys, unsigned int numPolygons, std::map>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh, bool indoorLocation ); - /** Converts the worldmesh into a PNAEN-buffer */ - static HRESULT ConvertWorldMeshPNAEN( zCPolygon** polys, unsigned int numPolygons, std::map>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh ); - /** Converts a loaded custommesh to be the worldmesh */ static XRESULT LoadWorldMeshFromFile( const std::string& file, std::map>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh ); @@ -58,7 +55,6 @@ class WorldConverter { /** Extracts a 3DS-Mesh from a zCVisual */ static void Extract3DSMeshFromVisual2( zCProgMeshProto* visual, MeshVisualInfo* meshInfo ); - static void Extract3DSMeshFromVisual2PNAEN( zCProgMeshProto* visual, MeshVisualInfo* meshInfo ); /** Updates a Morph-Mesh visual */ static void UpdateMorphMeshVisual( void* visual, MeshVisualInfo* meshInfo ); @@ -72,7 +68,6 @@ class WorldConverter { /** Extracts a zCProgMeshProto from a zCMesh */ static void ExtractProgMeshProtoFromMesh( zCMesh* mesh, MeshVisualInfo* meshInfo ); - /** Extracts a node-visual */ static void ExtractNodeVisual( int index, zCModelNodeInst* node, std::map>& attachments ); @@ -92,8 +87,10 @@ class WorldConverter { /** Creates the FullSectionMesh for the given section */ static void GenerateFullSectionMesh( WorldMeshSectionInfo& section ); +#if ENABLE_TESSELATION > 0 /** Tesselates the given triangle and adds the values to the list */ static void TesselateTriangle( ExVertexStruct* tri, std::vector& tesselated, int amount ); +#endif /** Builds a big vertexbuffer from the world sections */ static void WrapVertexBuffers( const std::list*>& vertexBuffers, const std::list*>& indexBuffers, std::vector& outVertices, std::vector& outIndices, std::vector& outOffsets ); @@ -101,15 +98,19 @@ class WorldConverter { /** Caches a mesh */ static void CacheMesh( const std::map, std::vector>>> geometry, const std::string& file ); +#if ENABLE_TESSELATION > 0 /** Turns a MeshInfo into PNAEN */ static void CreatePNAENInfoFor( MeshInfo* mesh, bool softNormals = false ); static void CreatePNAENInfoFor( SkeletalMeshInfo* mesh, MeshInfo* bindPoseMesh, bool softNormals = false ); static void CreatePNAENInfoFor( WorldMeshInfo* mesh, bool softNormals = false ); +#endif /** Converts ExVertexStruct into a zCPolygon*-Attay */ static void ConvertExVerticesTozCPolygons( const std::vector& vertices, const std::vector& indices, zCMaterial* material, std::vector& polyArray ); +#if ENABLE_TESSELATION > 0 /** Tesselates the given mesh the given amount of times */ static void TesselateMesh( WorldMeshInfo* mesh, int amount = 1 ); +#endif }; diff --git a/D3D11Engine/WorldObjects.cpp b/D3D11Engine/WorldObjects.cpp index 277ffc3d..1a9e424a 100644 --- a/D3D11Engine/WorldObjects.cpp +++ b/D3D11Engine/WorldObjects.cpp @@ -10,6 +10,7 @@ const int WORLDMESHINFO_VERSION = 5; const int VISUALINFO_VERSION = 5; +#if ENABLE_TESSELATION > 0 /** Saves the info for this visual */ void WorldMeshInfo::SaveWorldMeshInfo( const std::string& name ) { FILE* f = fopen( ("system\\GD3D11\\meshes\\infos\\" + name + ".wi").c_str(), "wb" ); @@ -20,12 +21,15 @@ void WorldMeshInfo::SaveWorldMeshInfo( const std::string& name ) { return; } + char WriteBuffer[sizeof( int ) + sizeof( TesselationSettings )] = {}; // Write the version first - fwrite( &WORLDMESHINFO_VERSION, sizeof( WORLDMESHINFO_VERSION ), 1, f ); + memcpy( WriteBuffer, &WORLDMESHINFO_VERSION, sizeof( int ) ); // Then the TesselationInfo - fwrite( &TesselationSettings.buffer, sizeof( TesselationSettings ), 1, f ); + memcpy( WriteBuffer + sizeof( int ), &TesselationSettings.buffer, sizeof( TesselationSettings.buffer ) ); + + fwrite( WriteBuffer, 1, sizeof( WriteBuffer ), f ); Toolbox::SaveStringToFILE( f, TesselationSettings.TesselationShader ); fclose( f ); @@ -40,12 +44,11 @@ void WorldMeshInfo::LoadWorldMeshInfo( const std::string& name ) { return; } - // Read the version first - int version; - fread( &version, sizeof( version ), 1, f ); + char ReadBuffer[sizeof( int ) + sizeof( TesselationSettings )]; + fread( ReadBuffer, 1, sizeof( ReadBuffer ), f ); - // Then the TesselationInfo - fread( &TesselationSettings.buffer, sizeof( TesselationSettings ), 1, f ); + // Read the TesselationInfo + memcpy( &TesselationSettings.buffer, ReadBuffer + sizeof( int ), sizeof( TesselationSettings.buffer ) ); TesselationSettings.TesselationShader = Toolbox::LoadStringFromFILE( f ); TesselationSettings.UpdateConstantbuffer(); @@ -57,6 +60,7 @@ void WorldMeshInfo::LoadWorldMeshInfo( const std::string& name ) { fclose( f ); } +#endif /** Updates the vobs constantbuffer */ void VobInfo::UpdateVobConstantBuffer() { @@ -93,6 +97,7 @@ void SkeletalVobInfo::UpdateVobConstantBuffer() { VobConstantBuffer->UpdateBuffer( &cb ); } +#if ENABLE_TESSELATION > 0 /** creates/updates the constantbuffer */ void VisualTesselationSettings::UpdateConstantbuffer() { if ( Constantbuffer ) { @@ -101,8 +106,9 @@ void VisualTesselationSettings::UpdateConstantbuffer() { Engine::GraphicsEngine->CreateConstantBuffer( &Constantbuffer, &buffer, sizeof( buffer ) ); } } +#endif - +#if ENABLE_TESSELATION > 0 /** Creates PNAEN-Info for all meshes if not already there */ void SkeletalMeshVisualInfo::CreatePNAENInfo( bool softNormals ) { for ( std::map>::iterator it = SkeletalMeshes.begin(); it != SkeletalMeshes.end(); it++ ) { @@ -126,7 +132,9 @@ void SkeletalMeshVisualInfo::ClearPNAENInfo() { BaseVisualInfo::ClearPNAENInfo(); } +#endif +#if ENABLE_TESSELATION > 0 /** Creates PNAEN-Info for all meshes if not already there */ void MeshVisualInfo::CreatePNAENInfo( bool softNormals ) { for ( std::map>::iterator it = Meshes.begin(); it != Meshes.end(); it++ ) { @@ -160,12 +168,15 @@ void BaseVisualInfo::SaveMeshVisualInfo( const std::string& name ) { return; } + char WriteBuffer[sizeof( int ) + sizeof( TesselationInfo )] = {}; // Write the version first - fwrite( &VISUALINFO_VERSION, sizeof( VISUALINFO_VERSION ), 1, f ); + memcpy( WriteBuffer, &VISUALINFO_VERSION, sizeof( int ) ); // Then the TesselationInfo - fwrite( &TesselationInfo.buffer, sizeof( TesselationInfo ), 1, f ); + memcpy( WriteBuffer + sizeof( int ), &TesselationInfo.buffer, sizeof( TesselationInfo.buffer ) ); + + fwrite( WriteBuffer, 1, sizeof( WriteBuffer ), f ); Toolbox::SaveStringToFILE( f, TesselationInfo.TesselationShader ); fclose( f ); @@ -184,13 +195,14 @@ void BaseVisualInfo::LoadMeshVisualInfo( const std::string& name ) { fread( ReadBuffer, 1, sizeof( ReadBuffer ), f ); // Read the TesselationInfo - memcpy( &TesselationInfo.buffer, ReadBuffer + sizeof( int ), sizeof( TesselationInfo ) ); + memcpy( &TesselationInfo.buffer, ReadBuffer + sizeof( int ), sizeof( TesselationInfo.buffer ) ); TesselationInfo.TesselationShader = Toolbox::LoadStringFromFILE( f ); TesselationInfo.UpdateConstantbuffer(); fclose( f ); } +#endif SectionInstanceCache::~SectionInstanceCache() { for ( std::map::iterator it = InstanceCache.begin(); it != InstanceCache.end(); it++ ) { @@ -204,8 +216,9 @@ MeshInfo::~MeshInfo() { delete MeshVertexBuffer; delete MeshIndexBuffer; +#if ENABLE_TESSELATION > 0 delete MeshIndexBufferPNAEN; - +#endif } SkeletalMeshInfo::~SkeletalMeshInfo() { @@ -214,7 +227,9 @@ SkeletalMeshInfo::~SkeletalMeshInfo() { delete MeshVertexBuffer; delete MeshIndexBuffer; +#if ENABLE_TESSELATION > 0 delete MeshIndexBufferPNAEN; +#endif } /** Clears the cache for the given progmesh */ @@ -234,11 +249,9 @@ void WorldMeshSectionInfo::SaveSectionMeshToFile( const std::string& name ) { if ( !f ) return; - - } - +#if ENABLE_TESSELATION > 0 /** Saves the mesh infos for this section */ void WorldMeshSectionInfo::SaveMeshInfos( const std::string& worldName, INT2 sectionPos ) { for ( auto it = WorldMeshes.begin(); it != WorldMeshes.end(); it++ ) { @@ -265,6 +278,7 @@ void WorldMeshSectionInfo::LoadMeshInfos( const std::string& worldName, INT2 sec } } } +#endif /** Creates buffers for this mesh info */ XRESULT MeshInfo::Create( ExVertexStruct* vertices, unsigned int numVertices, VERTEX_INDEX* indices, unsigned int numIndices ) { diff --git a/D3D11Engine/WorldObjects.h b/D3D11Engine/WorldObjects.h index 7c7d4177..cb649efd 100644 --- a/D3D11Engine/WorldObjects.h +++ b/D3D11Engine/WorldObjects.h @@ -62,6 +62,7 @@ struct cmpMeshKey { } };*/ +#if ENABLE_TESSELATION > 0 struct VisualTesselationSettings { VisualTesselationSettings() { buffer.VT_DisplacementStrength = 0.0f; @@ -88,6 +89,7 @@ struct VisualTesselationSettings { std::string TesselationShader; Buffer buffer; }; +#endif /** Holds information about a mesh, ready to be loaded into the renderer */ struct MeshInfo { @@ -96,7 +98,9 @@ struct MeshInfo { MeshIndexBuffer = nullptr; BaseIndexLocation = 0; MeshIndex = -1; +#if ENABLE_TESSELATION > 0 MeshIndexBufferPNAEN = nullptr; +#endif } virtual ~MeshInfo(); @@ -109,9 +113,11 @@ struct MeshInfo { std::vector Vertices; std::vector Indices; +#if ENABLE_TESSELATION > 0 D3D11VertexBuffer* MeshIndexBufferPNAEN; std::vector IndicesPNAEN; std::vector VerticesPNAEN; +#endif unsigned int BaseIndexLocation; unsigned int MeshIndex; }; @@ -121,6 +127,7 @@ struct WorldMeshInfo : public MeshInfo { SaveInfo = false; } +#if ENABLE_TESSELATION > 0 /** Saves the info for this visual */ void SaveWorldMeshInfo( const std::string& name ); @@ -128,6 +135,7 @@ struct WorldMeshInfo : public MeshInfo { void LoadWorldMeshInfo( const std::string& name ); VisualTesselationSettings TesselationSettings; +#endif /** If true we will save an info-file on next zen-resource-save */ bool SaveInfo; @@ -157,7 +165,9 @@ struct SkeletalMeshInfo { MeshVertexBuffer = nullptr; MeshIndexBuffer = nullptr; visual = nullptr; +#if ENABLE_TESSELATION > 0 MeshIndexBufferPNAEN = nullptr; +#endif } ~SkeletalMeshInfo(); @@ -167,8 +177,10 @@ struct SkeletalMeshInfo { std::vector Vertices; std::vector Indices; +#if ENABLE_TESSELATION > 0 D3D11VertexBuffer* MeshIndexBufferPNAEN; std::vector IndicesPNAEN; +#endif /** Actual visual containing this */ zCMeshSoftSkin* visual; @@ -187,6 +199,7 @@ struct BaseVisualInfo { } } +#if ENABLE_TESSELATION > 0 /** Creates PNAEN-Info for all meshes if not already there */ virtual void CreatePNAENInfo( bool softNormals = false ) {} @@ -198,11 +211,14 @@ struct BaseVisualInfo { /** Loads the info for this visual */ virtual void LoadMeshVisualInfo( const std::string& name ); +#endif std::map> Meshes; +#if ENABLE_TESSELATION > 0 /** Tesselation settings for this vob */ VisualTesselationSettings TesselationInfo; +#endif /** "size" of the mesh. The distance between it's bbox min and bbox max */ float MeshSize; @@ -244,8 +260,10 @@ struct MeshVisualInfo : public BaseVisualInfo { Instances.clear(); } +#if ENABLE_TESSELATION > 0 /** Creates PNAEN-Info for all meshes if not already there */ void CreatePNAENInfo( bool softNormals = false ); +#endif std::map, cmpMeshKey> MeshesByTexture; @@ -279,11 +297,13 @@ struct SkeletalMeshVisualInfo : public BaseVisualInfo { } } +#if ENABLE_TESSELATION > 0 /** Creates PNAEN-Info for all meshes if not already there */ void CreatePNAENInfo( bool softNormals = false ); /** Removes PNAEN info from this visual */ void ClearPNAENInfo(); +#endif /** Submeshes of this visual */ std::map> SkeletalMeshes; @@ -483,11 +503,13 @@ struct WorldMeshSectionInfo { /** Saves this sections mesh to a file */ void SaveSectionMeshToFile( const std::string& name ); +#if ENABLE_TESSELATION > 0 /** Saves the mesh infos for this section */ void SaveMeshInfos( const std::string& worldName, INT2 sectionPos ); /** Saves the mesh infos for this section */ void LoadMeshInfos( const std::string& worldName, INT2 sectionPos ); +#endif std::map WorldMeshes; std::map> WorldMeshesByCustomTexture; diff --git a/D3D11Engine/pch.h b/D3D11Engine/pch.h index 92df8296..2f1a2641 100644 --- a/D3D11Engine/pch.h +++ b/D3D11Engine/pch.h @@ -27,7 +27,9 @@ #define stdext std #endif -#define VERSION_NUMBER "17.8-dev3" +#define ENABLE_TESSELATION 0 + +#define VERSION_NUMBER "17.8-dev4" __declspec(selectany) const char* VERSION_NUMBER_STR = VERSION_NUMBER; extern bool FeatureLevel10Compatibility; diff --git a/D3D11Engine/zCSkyController_Outdoor.h b/D3D11Engine/zCSkyController_Outdoor.h index 40156b44..329509a8 100644 --- a/D3D11Engine/zCSkyController_Outdoor.h +++ b/D3D11Engine/zCSkyController_Outdoor.h @@ -36,7 +36,6 @@ class zCSkyLayerData { DirectX::XMFLOAT2 TexSpeed; }; - class zCSkyState { public: float Time; @@ -147,6 +146,62 @@ class zCSkyController_Outdoor : public zCSkyController { return s_contMasterTime; }*/ + float GetTimeStartRain() { + return *(float*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_TimeStartRain); + } + + void SetTimeStartRain( float timeStartRain ) { + *(float*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_TimeStartRain) = timeStartRain; + } + + float GetTimeStopRain() { + return *(float*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_TimeStopRain); + } + + void SetTimeStopRain( float timeStopRain ) { + *(float*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_TimeStopRain) = timeStopRain; + } + + int GetRenderLighting() { +#ifndef BUILD_GOTHIC_1_08k + return *(int*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_RenderLightning); +#else + return 0; +#endif + } + + void SetRenderLighting( int renderLighting ) { +#ifndef BUILD_GOTHIC_1_08k + *(int*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_RenderLightning) = renderLighting; +#else + (void)renderLighting; +#endif + } + + int GetRainingCounter() { +#ifndef BUILD_GOTHIC_1_08k + return *(int*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_RainingCounter); +#else + return 0; +#endif + } + + void SetRainingCounter( int rainCtr ) { +#ifndef BUILD_GOTHIC_1_08k + *(int*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_RainingCounter) = rainCtr; +#else + (void)rainCtr; +#endif + } + + float GetLastMasterTime() { + return *(float*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_LastMasterTime); + } + + void SetLastMasterTime( float lastMasterTime ) { + *(float*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_LastMasterTime) = lastMasterTime; + } + /** Returns the master-time wrapped between 0 and 1 */ float GetMasterTime() { return *(float*)(((char*)this) + GothicMemoryLocations::zCSkyController_Outdoor::Offset_MasterTime); From 43edbb01ec0315b8938edabfed8d2091b5b8c852 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Sun, 30 Jan 2022 15:07:23 +0100 Subject: [PATCH 15/15] Fix line drawing(fix flickering and z-position) --- D3D11Engine/BaseLineRenderer.h | 20 ++------- D3D11Engine/D3D11GraphicsEngine.cpp | 2 +- D3D11Engine/D3D11LineRenderer.cpp | 50 ++++++++++----------- D3D11Engine/D3D11LineRenderer.h | 15 ++----- D3D11Engine/D3D11ShaderManager.cpp | 3 ++ D3D11Engine/GothicAPI.cpp | 24 ---------- D3D11Engine/GothicAPI.h | 3 -- D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl | 57 ++++++++++++++++++++++++ D3D11Engine/zCRndD3D.h | 17 +++---- 9 files changed, 100 insertions(+), 91 deletions(-) create mode 100644 D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl diff --git a/D3D11Engine/BaseLineRenderer.h b/D3D11Engine/BaseLineRenderer.h index b66cf540..6e49412b 100644 --- a/D3D11Engine/BaseLineRenderer.h +++ b/D3D11Engine/BaseLineRenderer.h @@ -1,7 +1,7 @@ #pragma once #include "pch.h" -#pragma pack (push, 1) +#pragma pack (push, 1) struct LineVertex { LineVertex() {} LineVertex( const DirectX::XMFLOAT3& position, DWORD color = 0xFFFFFFFF ) { @@ -24,17 +24,7 @@ struct LineVertex { float4 Position; float4 Color; }; -#pragma pack (pop) - -struct ScreenSpaceLine { - ScreenSpaceLine() {} - ScreenSpaceLine( const DirectX::XMFLOAT3& position, DWORD color = 0xFFFFFFFF ) { - Position = position; - Color = color; - } - DirectX::XMFLOAT3 Position; - DWORD Color; -}; +#pragma pack (pop) class BaseLineRenderer { public: @@ -43,13 +33,11 @@ class BaseLineRenderer { /** Adds a line to the list */ virtual XRESULT AddLine( const LineVertex& v1, const LineVertex& v2 ) = 0; - virtual XRESULT AddLineDeferred( const ScreenSpaceLine& v1, const ScreenSpaceLine& v2 ) = 0; + virtual XRESULT AddLineScreenSpace( const LineVertex& v1, const LineVertex& v2 ) = 0; /** Flushes the cached lines */ virtual XRESULT Flush() = 0; - - /** Calculates the world-position from screen position and draws the lines */ - virtual XRESULT FlushDeferredLines() = 0; + virtual XRESULT FlushScreenSpace() = 0; /** Clears the line cache */ virtual XRESULT ClearCache() = 0; diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index 8cccc342..e150bff5 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -2338,7 +2338,7 @@ XRESULT D3D11GraphicsEngine::OnStartWorldRendering() { // Draw debug lines LineRenderer->Flush(); - LineRenderer->FlushDeferredLines(); + LineRenderer->FlushScreenSpace(); if ( Engine::GAPI->GetRendererState().RendererSettings.EnableHDR ) PfxRenderer->RenderHDR(); diff --git a/D3D11Engine/D3D11LineRenderer.cpp b/D3D11Engine/D3D11LineRenderer.cpp index 8a712fb8..5e576c2a 100644 --- a/D3D11Engine/D3D11LineRenderer.cpp +++ b/D3D11Engine/D3D11LineRenderer.cpp @@ -29,6 +29,17 @@ XRESULT D3D11LineRenderer::AddLine( const LineVertex& v1, const LineVertex& v2 ) return XR_SUCCESS; } +/** Adds a line to the list */ +XRESULT D3D11LineRenderer::AddLineScreenSpace( const LineVertex& v1, const LineVertex& v2 ) { + if ( ScreenSpaceLineCache.size() >= 0xFFFFFFFF ) { + return XR_FAILED; + } + + ScreenSpaceLineCache.push_back( v1 ); + ScreenSpaceLineCache.push_back( v2 ); + return XR_SUCCESS; +} + /** Flushes the cached lines */ XRESULT D3D11LineRenderer::Flush() { D3D11GraphicsEngineBase* engine = (D3D11GraphicsEngineBase*)Engine::GraphicsEngine; @@ -72,52 +83,41 @@ XRESULT D3D11LineRenderer::Flush() { //Draw the mesh engine->GetContext()->Draw( LineCache.size(), 0 ); - //engine->DrawVertexBuffer(LineBuffer, LineCache.size(), sizeof(LineVertex)); - // Clear for the next frame - ClearCache(); + LineCache.clear(); return XR_SUCCESS; } /** Flushes the cached lines */ -XRESULT D3D11LineRenderer::FlushDeferredLines() { +XRESULT D3D11LineRenderer::FlushScreenSpace() { D3D11GraphicsEngineBase* engine = (D3D11GraphicsEngineBase*)Engine::GraphicsEngine; - if ( DeferredLineCache.size() == 0 ) + if ( ScreenSpaceLineCache.size() == 0 ) return XR_SUCCESS; - static std::vector verticies; - - verticies.clear(); - - Engine::GAPI->UnprojectLinesIntoLineVerticies( DeferredLineCache, verticies ); - // Check buffersize and create a new one if needed - if ( !LineBuffer || verticies.size() > LineBufferSize ) { + if ( !LineBuffer || ScreenSpaceLineCache.size() > LineBufferSize ) { // Create a new buffer delete LineBuffer; XLE( engine->CreateVertexBuffer( &LineBuffer ) ); - XLE( LineBuffer->Init( &verticies[0], verticies.size() * sizeof( LineVertex ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_DYNAMIC, D3D11VertexBuffer::CA_WRITE ) ); - LineBufferSize = verticies.size(); + XLE( LineBuffer->Init( &ScreenSpaceLineCache[0], ScreenSpaceLineCache.size() * sizeof( LineVertex ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_DYNAMIC, D3D11VertexBuffer::CA_WRITE ) ); + LineBufferSize = ScreenSpaceLineCache.size(); } else { // Just update our buffer - XLE( LineBuffer->UpdateBuffer( &verticies[0], verticies.size() * sizeof( LineVertex ) ) ); + XLE( LineBuffer->UpdateBuffer( &ScreenSpaceLineCache[0], ScreenSpaceLineCache.size() * sizeof( LineVertex ) ) ); } - Engine::GAPI->SetWorldTransformXM( XMMatrixIdentity() ); - Engine::GAPI->SetViewTransformXM( Engine::GAPI->GetViewMatrixXM() ); - engine->SetActivePixelShader( "PS_Lines" ); - engine->SetActiveVertexShader( "VS_Lines" ); + engine->SetActiveVertexShader( "VS_Lines_XYZRHW" ); + + engine->BindViewportInformation( "VS_Lines_XYZRHW", 0 ); engine->SetDefaultStates(); Engine::GAPI->GetRendererState().BlendState.SetAlphaBlending(); Engine::GAPI->GetRendererState().BlendState.SetDirty(); engine->SetupVS_ExMeshDrawCall(); - engine->SetupVS_ExConstantBuffer(); - engine->SetupVS_ExPerInstanceConstantBuffer(); engine->GetContext()->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST ); // Draw the lines @@ -126,17 +126,13 @@ XRESULT D3D11LineRenderer::FlushDeferredLines() { engine->GetContext()->IASetVertexBuffers( 0, 1, LineBuffer->GetVertexBuffer().GetAddressOf(), &uStride, &offset ); //Draw the mesh - engine->GetContext()->Draw( verticies.size(), 0 ); - - //engine->DrawVertexBuffer(LineBuffer, LineCache.size(), sizeof(LineVertex)); + engine->GetContext()->Draw( ScreenSpaceLineCache.size(), 0 ); // Clear for the next frame - DeferredLineCache.clear(); - verticies.clear(); + ScreenSpaceLineCache.clear(); return XR_SUCCESS; } - /** Clears the line cache */ XRESULT D3D11LineRenderer::ClearCache() { LineCache.clear(); diff --git a/D3D11Engine/D3D11LineRenderer.h b/D3D11Engine/D3D11LineRenderer.h index 18593c0b..12b53f83 100644 --- a/D3D11Engine/D3D11LineRenderer.h +++ b/D3D11Engine/D3D11LineRenderer.h @@ -10,28 +10,19 @@ class D3D11LineRenderer : /** Adds a line to the list */ virtual XRESULT AddLine( const LineVertex& v1, const LineVertex& v2 ); - virtual XRESULT AddLineDeferred( const ScreenSpaceLine& v1, const ScreenSpaceLine& v2 ) { - if ( DeferredLineCache.size() >= 0xFFFFFFFF ) { - return XR_FAILED; - } - - DeferredLineCache.push_back( v1 ); - DeferredLineCache.push_back( v2 ); - return XR_SUCCESS; - } + virtual XRESULT AddLineScreenSpace( const LineVertex& v1, const LineVertex& v2 ); /** Flushes the cached lines */ virtual XRESULT Flush(); - virtual XRESULT FlushDeferredLines(); + virtual XRESULT FlushScreenSpace(); /** Clears the line cache */ virtual XRESULT ClearCache(); - private: /** Line cache */ std::vector LineCache; - std::vector DeferredLineCache; + std::vector ScreenSpaceLineCache; /** Buffer to hold the lines on the GPU */ D3D11VertexBuffer* LineBuffer; diff --git a/D3D11Engine/D3D11ShaderManager.cpp b/D3D11Engine/D3D11ShaderManager.cpp index 733c0c3f..52cc28da 100644 --- a/D3D11Engine/D3D11ShaderManager.cpp +++ b/D3D11Engine/D3D11ShaderManager.cpp @@ -138,6 +138,9 @@ XRESULT D3D11ShaderManager::Init() { Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerFrame ) ); Shaders.back().cBufferSizes.push_back( sizeof( VS_ExConstantBuffer_PerInstance ) ); + Shaders.push_back( ShaderInfo( "VS_Lines_XYZRHW", "VS_Lines_XYZRHW.hlsl", "v", 6 ) ); + Shaders.back().cBufferSizes.push_back( 2 * sizeof( float2 ) ); + Shaders.push_back( ShaderInfo( "PS_Lines", "PS_Lines.hlsl", "p" ) ); Shaders.push_back( ShaderInfo( "PS_LinesSel", "PS_LinesSel.hlsl", "p" ) ); diff --git a/D3D11Engine/GothicAPI.cpp b/D3D11Engine/GothicAPI.cpp index 79a783a1..6211d048 100644 --- a/D3D11Engine/GothicAPI.cpp +++ b/D3D11Engine/GothicAPI.cpp @@ -2571,30 +2571,6 @@ void XM_CALLCONV GothicAPI::UnprojectXM( FXMVECTOR p, XMVECTOR& worldPos, XMVECT worldDir = XMVector3TransformCoord( XMVector3Normalize( u ), invView ); } -void XM_CALLCONV GothicAPI::UnprojectLinesIntoLineVerticies( const std::vector& lines, std::vector& lineVerticies ) -{ - auto cam = zCCamera::GetCamera(); - XMMATRIX proj = XMMatrixTranspose( XMLoadFloat4x4( &cam->trafoProjection ) ); - XMMATRIX invView = XMMatrixTranspose( XMLoadFloat4x4( &cam->trafoViewInv ) ); - - // Convert to screenspace - auto res = Engine::GraphicsEngine->GetResolution(); - XMFLOAT3 pos; - for ( auto& l : lines ) { - FXMVECTOR u = XMVectorSet( - (((2.0f * l.Position.x) / res.x) - 1) / proj.r[0].m128_f32[0], - -(((2.0f * l.Position.y) / res.y) - 1) / proj.r[1].m128_f32[1], - 1, - 0 ); - - // Transform and output - //auto worldPos = XMVector3TransformCoord( u, invView ); - auto worldPos = XMVector3TransformCoord( XMVector3Normalize( u ), invView ); - XMStoreFloat3( &pos, worldPos ); - lineVerticies.push_back( LineVertex( pos, l.Color ) ); - } -} - /** Unprojects the current cursor */ XMVECTOR GothicAPI::UnprojectCursorXM() { XMVECTOR mPos, mDir; diff --git a/D3D11Engine/GothicAPI.h b/D3D11Engine/GothicAPI.h index 60c82177..8991376c 100644 --- a/D3D11Engine/GothicAPI.h +++ b/D3D11Engine/GothicAPI.h @@ -377,9 +377,6 @@ class GothicAPI { /** Unprojects a pixel-position on the screen */ void XM_CALLCONV UnprojectXM( DirectX::FXMVECTOR p, DirectX::XMVECTOR& worldPos, DirectX::XMVECTOR& worldDir ); - /** Unprojects a pixel-position on the screen */ - void XM_CALLCONV GothicAPI::UnprojectLinesIntoLineVerticies( const std::vector& lines, std::vector& lineVerticies ); - /** Unprojects the current cursor, returns it's direction in world-space */ DirectX::XMVECTOR XM_CALLCONV UnprojectCursorXM(); diff --git a/D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl b/D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl new file mode 100644 index 00000000..aba1ab88 --- /dev/null +++ b/D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl @@ -0,0 +1,57 @@ +//-------------------------------------------------------------------------------------- +// Simple vertex shader +//-------------------------------------------------------------------------------------- + +cbuffer Viewport : register( b0 ) +{ + float2 V_ViewportPos; + float2 V_ViewportSize; +}; + +//-------------------------------------------------------------------------------------- +// Input / Output structures +//-------------------------------------------------------------------------------------- +struct VS_INPUT +{ + float4 vPosition : POSITION; + float4 vDiffuse : DIFFUSE; +}; + +struct VS_OUTPUT +{ + float4 vDiffuse : TEXCOORD0; + float4 vPosition : SV_POSITION; +}; + +/** Transforms a pre-transformed xyzrhw-coordinate into d3d11-space */ +float4 TransformXYZRHW(float4 xyzrhw) +{ + // MAGIC (: + + // Convert from viewport-coordinates to normalized device coordinates + float3 ndc; + ndc.x = ((2 * (xyzrhw.x - V_ViewportPos.x)) / V_ViewportSize.x) - 1; + ndc.y = 1 - ((2 * (xyzrhw.y - V_ViewportPos.y)) / V_ViewportSize.y); + ndc.z = xyzrhw.z; + + // Remove the stupid half-pixel offset from pre D3D10 + ndc.xy -= 0.5f / V_ViewportSize; + + // Convert to clip-space. rhw is actually 1/w ("reciprocal"). So to undo the devide by w, devide by the given 1/w. + float actualW = 1.0f / xyzrhw.w; + float3 clipSpace = ndc.xyz * actualW; + + return float4(clipSpace, actualW); +} + +//-------------------------------------------------------------------------------------- +// Vertex Shader +//-------------------------------------------------------------------------------------- +VS_OUTPUT VSMain( VS_INPUT Input ) +{ + VS_OUTPUT Output; + + Output.vPosition = TransformXYZRHW(Input.vPosition); + Output.vDiffuse = Input.vDiffuse; + return Output; +} diff --git a/D3D11Engine/zCRndD3D.h b/D3D11Engine/zCRndD3D.h index 6687c0ce..40c40f3a 100644 --- a/D3D11Engine/zCRndD3D.h +++ b/D3D11Engine/zCRndD3D.h @@ -33,25 +33,26 @@ class zCRndD3D { } /** Draws a straight line from xyz1 to xyz2 */ - static void __fastcall hooked_zCRndD3DDrawLineZ( void* thisptr, void* unknwn, float x1, float y1, float z1, float x2, float y2, float z2, zColor color ) { - // TODO: Implement occlusion culling for the lines. - // TODO: Find out why lines are flickering - + static void __fastcall hooked_zCRndD3DDrawLineZ( void* thisptr, void* unknwn, float x1, float y1, float z1VSInv, float x2, float y2, float z2VSInv, zColor color ) { + if ( color.bgra.alpha == 0 ) { + color.bgra.alpha = 255; + } auto lineRenderer = Engine::GraphicsEngine->GetLineRenderer(); if ( lineRenderer ) { - lineRenderer->AddLineDeferred( ScreenSpaceLine( XMFLOAT3( x1, y1, z1 ), color.dword ), ScreenSpaceLine( XMFLOAT3( x2, y2, z2 ), color.dword ) ); + auto& proj = Engine::GAPI->GetProjectionMatrix(); + float actualz1 = proj._33 + proj._34 * z1VSInv; + float actualz2 = proj._33 + proj._34 * z2VSInv; + lineRenderer->AddLineScreenSpace( LineVertex( XMFLOAT3( x1, y1, actualz1 ), color.dword, z1VSInv ), LineVertex( XMFLOAT3( x2, y2, actualz2 ), color.dword, z2VSInv ) ); } } static void __fastcall hooked_zCRndD3DDrawLine( void* thisptr, void* unknwn, float x1, float y1, float x2, float y2, zColor color ) { - // TODO: Find out why lines are flickering - if ( color.bgra.alpha == 0 ) { color.bgra.alpha = 255; } auto lineRenderer = Engine::GraphicsEngine->GetLineRenderer(); if ( lineRenderer ) { - lineRenderer->AddLineDeferred( ScreenSpaceLine( XMFLOAT3( x1, y1, 0 ), color.dword ), ScreenSpaceLine( XMFLOAT3( x2, y2, 0 ), color.dword ) ); + lineRenderer->AddLineScreenSpace( LineVertex( XMFLOAT3( x1, y1, 1.f ), color.dword, 1.f ), LineVertex( XMFLOAT3( x2, y2, 1.f ), color.dword, 1.f ) ); } }