Skip to content

Commit

Permalink
Fixes & Improvements
Browse files Browse the repository at this point in the history
-Fix hashing render states over uninitialized variables
-Fix some awful glitches in indoor locations with enabled shadows
-Remove unused calculations for some particle effects
-Force water to be rendered always when texture is available
-Change cache-in to not check for cache-out since dx7 code doesn't check for it too
-Allow Steam Overlay to properly acquire/release inputs
  • Loading branch information
SaiyansKing committed Sep 11, 2021
1 parent 1710bb9 commit 7f81d93
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 49 deletions.
2 changes: 1 addition & 1 deletion D3D11Engine/D2DSettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ XRESULT D2DSettingsDialog::InitControls() {
SV_Checkbox* godraysCheckbox = new SV_Checkbox( MainView, MainPanel );
godraysCheckbox->SetSize( D2D1::SizeF( 160, 20 ) );
switch ( userLanguage ) {
case LANGUAGE_POLISH: godraysCheckbox->SetCaption( L"Promienie Boga" ); break;
case LANGUAGE_POLISH: godraysCheckbox->SetCaption( L"GodRays" ); break;
default: godraysCheckbox->SetCaption( L"Enable GodRays" ); break;
}
godraysCheckbox->SetDataToUpdate( &Engine::GAPI->GetRendererState().RendererSettings.EnableGodRays );
Expand Down
2 changes: 2 additions & 0 deletions D3D11Engine/D3D11Engine.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ copy "$(OutDir)$(TargetName).pdb" "$(G1_SYSTEM_PATH)\ddraw.pdb"</Command>
<ClInclude Include="oCSpawnManager.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="BaseShadowedPointLight.h" />
<ClInclude Include="SteamOverlay.h" />
<ClInclude Include="SV_GMeshInfoView.h" />
<ClInclude Include="StackWalker.h" />
<ClInclude Include="SV_Border.h" />
Expand Down Expand Up @@ -906,6 +907,7 @@ copy "$(OutDir)$(TargetName).pdb" "$(G1_SYSTEM_PATH)\ddraw.pdb"</Command>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release_NoOpt_G1|Win32'">pch.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="BaseShadowedPointLight.cpp" />
<ClCompile Include="SteamOverlay.cpp" />
<ClCompile Include="SV_GMeshInfoView.cpp" />
<ClCompile Include="StackWalker.cpp" />
<ClCompile Include="SV_Border.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions D3D11Engine/D3D11Engine.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,9 @@
<ClInclude Include="GothicMemoryLocations1_12f.h">
<Filter>ZenGin</Filter>
</ClInclude>
<ClInclude Include="SteamOverlay.h">
<Filter>Tools</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
Expand Down Expand Up @@ -952,6 +955,9 @@
<ClCompile Include="D3D11GraphicsEngine.cpp">
<Filter>Engine\D3D11\Engine</Filter>
</ClCompile>
<ClCompile Include="SteamOverlay.cpp">
<Filter>Tools</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="ddraw.def">
Expand Down
56 changes: 34 additions & 22 deletions D3D11Engine/D3D11GraphicsEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define DEBUG_D3D11
#endif

#include "SteamOverlay.h"
#include <dxgi1_6.h>

namespace wrl = Microsoft::WRL;
Expand Down Expand Up @@ -451,6 +452,7 @@ XRESULT D3D11GraphicsEngine::Init() {
DXGI_FORMAT_R8G8B8A8_UNORM, nullptr, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN, 1, 6 );

SteamOverlay::Init();
return XR_SUCCESS;
}

Expand Down Expand Up @@ -773,6 +775,7 @@ XRESULT D3D11GraphicsEngine::OnBeginFrame() {

s_firstFrame = false;

SteamOverlay::Update();
#ifdef BUILD_1_12F
// Some shitty workaround for weird hidden window bug that happen on d3d11 renderer
if ( !(GetWindowLongA( OutputWindow, GWL_STYLE ) & WS_VISIBLE) ) {
Expand Down Expand Up @@ -2007,9 +2010,8 @@ XRESULT D3D11GraphicsEngine::DrawMeshInfoListAlphablended(
// Draw the list
for ( auto const& it : list ) {
int indicesNumMod = 1;
if ( it.first.Material->GetAniTexture() != nullptr ) {
MyDirectDrawSurface7* surface =
it.first.Material->GetAniTexture()->GetSurface();
if ( zCTexture* texture = it.first.Material->GetAniTexture() ) {
MyDirectDrawSurface7* surface = texture->GetSurface();
ID3D11ShaderResourceView* srv[3];

// Get diffuse and normalmap
Expand All @@ -2026,16 +2028,15 @@ XRESULT D3D11GraphicsEngine::DrawMeshInfoListAlphablended(
GetContext()->PSSetShaderResources( 0, 3, srv );

// Get the right shader for it

BindShaderForTexture( it.first.Material->GetAniTexture(), false,
it.first.Material->GetAlphaFunc() );
int alphaFunc = it.first.Material->GetAlphaFunc();
BindShaderForTexture( texture, false, alphaFunc );

// Check for alphablending on world mesh
if ( lastAlphaFunc != it.first.Material->GetAlphaFunc() ) {
if ( it.first.Material->GetAlphaFunc() == zMAT_ALPHA_FUNC_BLEND )
if ( lastAlphaFunc != alphaFunc ) {
if ( alphaFunc == zMAT_ALPHA_FUNC_BLEND )
Engine::GAPI->GetRendererState().BlendState.SetAlphaBlending();

if ( it.first.Material->GetAlphaFunc() == zMAT_ALPHA_FUNC_ADD )
if ( alphaFunc == zMAT_ALPHA_FUNC_ADD )
Engine::GAPI->GetRendererState().BlendState.SetAdditiveBlending();

Engine::GAPI->GetRendererState().BlendState.SetDirty();
Expand All @@ -2044,7 +2045,7 @@ XRESULT D3D11GraphicsEngine::DrawMeshInfoListAlphablended(
Engine::GAPI->GetRendererState().DepthState.SetDirty();

UpdateRenderStates();
lastAlphaFunc = it.first.Material->GetAlphaFunc();
lastAlphaFunc = alphaFunc;
}

MaterialInfo* info = it.first.Info;
Expand All @@ -2053,7 +2054,7 @@ XRESULT D3D11GraphicsEngine::DrawMeshInfoListAlphablended(
info->Constantbuffer->BindToPixelShader( 2 );

// Don't let the game unload the texture after some time
it.first.Material->GetAniTexture()->CacheIn( 0.6f );
texture->CacheIn( 0.6f );

// Draw the section-part
DrawVertexBufferIndexedUINT( nullptr, nullptr, it.second->Indices.size(),
Expand Down Expand Up @@ -2134,16 +2135,16 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) {
zCTexture* aniTex = worldMesh.first.Material->GetTexture();
if ( !aniTex ) continue;

if ( aniTex->CacheIn( 0.6f ) != zRES_CACHED_IN ) {
continue;
}

// Check surface type
if ( worldMesh.first.Info->MaterialType == MaterialInfo::MT_Water ) {
FrameWaterSurfaces[aniTex].push_back( worldMesh.second );
continue;
}

if ( aniTex->CacheIn( 0.6f ) != zRES_CACHED_IN ) {
continue;
}

// Check if the animated texture and the registered textures are the
// same
MeshKey key = worldMesh.first;
Expand Down Expand Up @@ -2233,7 +2234,7 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) {
GetContext()->PSSetShaderResources( 0, 3, srv );

// Get the right shader for it
BindShaderForTexture( mesh.first.Material->GetAniTexture(), false,
BindShaderForTexture( mesh.first.Texture, false,
mesh.first.Material->GetAlphaFunc() );

if ( info ) {
Expand All @@ -2242,10 +2243,10 @@ XRESULT D3D11GraphicsEngine::DrawWorldMesh( bool noTextures ) {
info->Constantbuffer->BindToPixelShader( 2 );

// Don't let the game unload the texture after some time
mesh.first.Material->GetAniTexture()->CacheIn( 0.6f );
//mesh.first.Texture->CacheIn( 0.6f );
boundInfo = info;
}
bound = mesh.first.Material->GetAniTexture();
bound = mesh.first.Texture;
// Bind normalmap to HDS
if ( !mesh.second->IndicesPNAEN.empty() ) {
GetContext()->DSSetShaderResources( 0, 1, boundNormalmap.GetAddressOf() );
Expand Down Expand Up @@ -2628,10 +2629,9 @@ void D3D11GraphicsEngine::DrawWaterSurfaces() {
for ( auto const& it : FrameWaterSurfaces ) {
if ( it.first ) {
// Bind diffuse
if ( it.first->CacheIn( -1 ) ==
zRES_CACHED_IN ) // Force immediate cache in, because water is
// important!
it.first->Bind( 0 );
it.first->CacheIn( -1 ); // Force immediate cache in, because water
// is important!
it.first->Bind( 0 );
}
// Draw surfaces
for ( auto const& mesh : it.second ) {
Expand Down Expand Up @@ -4074,8 +4074,17 @@ XRESULT D3D11GraphicsEngine::DrawLighting( std::vector<VobLightInfo*>& lights )
Engine::GAPI->SetCameraReplacementPtr( &cr );

// Indoor worlds don't need shadowmaps for the world
static zTBspMode lastBspMode = zBSP_MODE_OUTDOOR;
if ( Engine::GAPI->GetLoadedWorldInfo()->BspTree->GetBspTreeMode() == zBSP_MODE_OUTDOOR ) {
RenderShadowmaps( WorldShadowCP, nullptr, true );
lastBspMode = zBSP_MODE_OUTDOOR;
} else if ( Engine::GAPI->GetRendererState().RendererSettings.EnableShadows ) {
// We need to clear shadowmap to avoid some glitches in indoor locations
// only need to do it once :)
if ( lastBspMode == zBSP_MODE_OUTDOOR ) {
GetContext()->ClearDepthStencilView( WorldShadowmap1->GetDepthStencilView().Get(), D3D11_CLEAR_DEPTH, 0.0f, 0 );
lastBspMode = zBSP_MODE_INDOOR;
}
}

SetDefaultStates();
Expand Down Expand Up @@ -4666,6 +4675,9 @@ LRESULT D3D11GraphicsEngine::OnWindowMessage( HWND hWnd, UINT msg, WPARAM wParam
}

UpdateClipCursor( hWnd );

// Sometimes Gothic doesn't aquire/release input so let's do it ourselves
Engine::GAPI->SetEnableGothicInput( m_isWindowActive );
}
break;
case WM_WINDOWPOSCHANGED: UpdateClipCursor( hWnd ); break;
Expand Down
18 changes: 4 additions & 14 deletions D3D11Engine/GothicAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ void GothicAPI::SetEnableGothicInput( bool value ) {
dInputKeyboard->Acquire();
}

#ifdef BUILD_GOTHIC_2_6_fix
/*#ifdef BUILD_GOTHIC_2_6_fix
// Kill the check for doing freelook only in fullscreen, since we force the game to run windowed internally
const int flSize = GothicMemoryLocations::GlobalObjects::NOP_FreelookWindowedCheckEnd - GothicMemoryLocations::GlobalObjects::NOP_FreelookWindowedCheckStart;
Expand All @@ -401,7 +401,7 @@ void GothicAPI::SetEnableGothicInput( bool value ) {
memcpy( &s_CheckInst[0], (void*)GothicMemoryLocations::GlobalObjects::NOP_FreelookWindowedCheckStart, flSize );
}
#endif
#endif*/
#endif

}
Expand Down Expand Up @@ -1918,16 +1918,12 @@ void GothicAPI::DrawParticleFX( zCVob* source, zCParticleFX* fx, ParticleFrameDa
// Maybe create more emitters?
fx->CheckDependentEmitter();

DirectX::XMFLOAT4X4 sw;
source->GetWorldMatrix( &sw );

zTParticle* pfx = fx->GetFirstParticle();
if ( pfx ) {
// Get texture
zCTexture* texture = nullptr;
if ( zCParticleEmitter* emitter = fx->GetEmitter() ) {
texture = emitter->GetVisTexture();
if ( texture ) {
if ( (texture = emitter->GetVisTexture()) != nullptr ) {
// Check if it's loaded
if ( texture->CacheIn( 0.6f ) != zRES_CACHED_IN ) {
return;
Expand Down Expand Up @@ -2006,12 +2002,6 @@ void GothicAPI::DrawParticleFX( zCVob* source, zCParticleFX* fx, ParticleFrameDa
if ( alignment == zPARTICLE_ALIGNMENT_XY ) {
ii.drawMode = 2;
} else if ( alignment == zPARTICLE_ALIGNMENT_VELOCITY || alignment == zPARTICLE_ALIGNMENT_VELOCITY_3D ) {
// Rotate velocity so it fits with the vob

XMFLOAT3 velocity;
XMStoreFloat3( &velocity, DirectX::XMVector3TransformNormal( XMVector3Normalize( XMLoadFloat3( &p->Vel ) ), XMMatrixTranspose( XMLoadFloat4x4( &sw ) ) ) );
ii.velocity = velocity;

ii.drawMode = 3;
} // TODO: Y-Locked!

Expand All @@ -2027,7 +2017,7 @@ void GothicAPI::DrawParticleFX( zCVob* source, zCParticleFX* fx, ParticleFrameDa
if ( fx->GetEmitter()->GetVisTexAniIsLooping() != 2 ) { // 2 seems to be some magic case with sinus smoothing
color.w = std::min( p->Alpha, 255.0f ) / 255.0f;
} else {
color.w = std::min( (zCParticleFX::SinSmooth( fabs( (p->Alpha - fx->GetEmitter()->GetVisAlphaStart()) * fx->GetEmitter()->GetAlphaDist() ) ) * p->Alpha) / 255.0f, 255.0f );
color.w = std::min( (zCParticleFX::SinSmooth( fabs( (p->Alpha - fx->GetEmitter()->GetVisAlphaStart()) * fx->GetEmitter()->GetAlphaDist() ) ) * p->Alpha) / 255.0f, 1.0f );
}

color.w = std::max( color.w, 0.0f );
Expand Down
10 changes: 9 additions & 1 deletion D3D11Engine/GothicGraphicsState.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class BaseDepthBufferState;
struct GothicDepthBufferStateInfo : public GothicPipelineState {
GothicDepthBufferStateInfo() {
StructSize = sizeof( GothicDepthBufferStateInfo );
Padding[0] = Padding[1] = false;
}

/** Layed out for D3D11 */
Expand All @@ -186,6 +187,7 @@ struct GothicDepthBufferStateInfo : public GothicPipelineState {
/** Depthbuffer settings */
bool DepthBufferEnabled;
bool DepthWriteEnabled;
bool Padding[2];
ECompareFunc DepthBufferCompareFunc;

/** Deletes all cached states */
Expand Down Expand Up @@ -224,6 +226,7 @@ class BaseBlendStateInfo;
struct GothicBlendStateInfo : public GothicPipelineState {
GothicBlendStateInfo() {
StructSize = sizeof( GothicBlendStateInfo );
Padding = false;
}

/** Layed out for D3D11 */
Expand Down Expand Up @@ -292,6 +295,7 @@ struct GothicBlendStateInfo : public GothicPipelineState {
BlendOpAlpha = BO_BLEND_OP_ADD;
BlendEnabled = true;
AlphaToCoverage = false;
ColorWritesEnabled = true;
}

/** Sets up modualte blending */
Expand All @@ -304,6 +308,7 @@ struct GothicBlendStateInfo : public GothicPipelineState {
BlendOpAlpha = BO_BLEND_OP_ADD;
BlendEnabled = true;
AlphaToCoverage = false;
ColorWritesEnabled = true;
}

EBlendFunc SrcBlend;
Expand All @@ -315,6 +320,7 @@ struct GothicBlendStateInfo : public GothicPipelineState {
bool BlendEnabled;
bool AlphaToCoverage;
bool ColorWritesEnabled;
bool Padding;

/** Deletes all cached states */
static void DeleteCachedObjects() {
Expand Down Expand Up @@ -365,6 +371,7 @@ class BaseRasterizerStateInfo;
struct GothicRasterizerStateInfo : public GothicPipelineState {
GothicRasterizerStateInfo() {
StructSize = sizeof( GothicRasterizerStateInfo );
Padding = false;
}

/** Layed out for D3D11 */
Expand All @@ -386,8 +393,9 @@ struct GothicRasterizerStateInfo : public GothicPipelineState {
ECullMode CullMode;
bool FrontCounterClockwise;
bool DepthClipEnable;
int ZBias;
bool Wireframe;
bool Padding;
int ZBias;

/** Deletes all cached states */
static void DeleteCachedObjects() {
Expand Down
39 changes: 39 additions & 0 deletions D3D11Engine/SteamOverlay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "Engine.h"
#include "GothicAPI.h"
#include "SteamOverlay.h"

// We can detect whether steam overlay is visible by checking if it request using mouse or keyboard
// easiest way to do it would be by using steamapi callbacks however because the game can be launched
// without steam it doesn't feel right doing it that way
namespace SteamOverlay
{
static bool IsSteamOverlayEnabled = false;

typedef bool( WINAPI* PFN_IsOverlayEnabled )();
typedef bool( WINAPI* PFN_SteamOverlayIsUsingMouse )();
typedef bool( WINAPI* PFN_SteamOverlayIsUsingKeyboard )();
static PFN_IsOverlayEnabled IsOverlayEnabled = nullptr;
static PFN_SteamOverlayIsUsingMouse SteamOverlayIsUsingMouse = nullptr;
static PFN_SteamOverlayIsUsingKeyboard SteamOverlayIsUsingKeyboard = nullptr;

void Init()
{
HMODULE soModule = GetModuleHandleA( "GameOverlayRenderer.dll" );
if ( soModule ) {
IsOverlayEnabled = reinterpret_cast<PFN_IsOverlayEnabled>(GetProcAddress( soModule, "IsOverlayEnabled" ));
SteamOverlayIsUsingMouse = reinterpret_cast<PFN_SteamOverlayIsUsingMouse>(GetProcAddress( soModule, "SteamOverlayIsUsingMouse" ));
SteamOverlayIsUsingKeyboard = reinterpret_cast<PFN_SteamOverlayIsUsingKeyboard>(GetProcAddress( soModule, "SteamOverlayIsUsingKeyboard" ));
}
}

void Update()
{
if ( IsOverlayEnabled && IsOverlayEnabled() && (SteamOverlayIsUsingMouse || SteamOverlayIsUsingKeyboard) ) {
bool isSOEnabled = (SteamOverlayIsUsingMouse && SteamOverlayIsUsingMouse()) || (SteamOverlayIsUsingKeyboard && SteamOverlayIsUsingKeyboard());
if ( IsSteamOverlayEnabled != isSOEnabled ) {
Engine::GAPI->SetEnableGothicInput( IsSteamOverlayEnabled );
IsSteamOverlayEnabled = isSOEnabled;
}
}
}
}
7 changes: 7 additions & 0 deletions D3D11Engine/SteamOverlay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace SteamOverlay
{
void Init();
void Update();
};
Loading

0 comments on commit 7f81d93

Please sign in to comment.