Skip to content

Commit

Permalink
Fixes & Improvements
Browse files Browse the repository at this point in the history
-Limit shadowmap size to 8192 for feature_level_10_0 comaptibility graphic cards
-Fix Stream Output Geometry Shaders for feature_level_10_0
-Disable weird caching for cached-out surfaces
-Mark every loaded polygon from indoor location as "indoor"
-Render indoor vobs in indoor locations using render distances from normal vobs
  • Loading branch information
SaiyansKing committed Sep 17, 2021
1 parent 203bc6c commit 5e4e9bf
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 47 deletions.
7 changes: 6 additions & 1 deletion D3D11Engine/BaseAntTweakBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ XRESULT BaseAntTweakBar::Init() {
TwAddVarRW( Bar_General, "TesselationFrustumCulling", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.TesselationFrustumCulling, nullptr );
TwAddVarRW( Bar_General, "AtmosphericScattering", TW_TYPE_BOOLCPP, &Engine::GAPI->GetRendererState().RendererSettings.AtmosphericScattering, nullptr );

TwType t = TwDefineEnumFromString( "ShadowmapSizeEnum", "512, 1024, 2048, 4096, 8192, 16384" );
TwType t;
if ( FeatureLevel10Compatibility ) {
t = TwDefineEnumFromString( "ShadowmapSizeEnum", "512, 1024, 2048, 4096, 8192" );
} else {
t = TwDefineEnumFromString( "ShadowmapSizeEnum", "512, 1024, 2048, 4096, 8192, 16384" );
}
TwAddVarRW( Bar_General, "ShadowmapSize", t, &Engine::GAPI->GetRendererState().RendererSettings.ShadowMapSize, nullptr );
TwAddVarRW( Bar_General, "WorldShadowRangeScale", TW_TYPE_FLOAT, &Engine::GAPI->GetRendererState().RendererSettings.WorldShadowRangeScale, nullptr );
TwDefine( " General/WorldShadowRangeScale step=0.01 min=0" );
Expand Down
6 changes: 5 additions & 1 deletion D3D11Engine/D2DSettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,11 @@ XRESULT D2DSettingsDialog::InitControls() {
shadowmapSizeSlider->SetPositionAndSize( D2D1::Point2F( 10, 22 ), D2D1::SizeF( 150, 15 ) );
shadowmapSizeSlider->AlignUnder( shadowmapSizeLabel, 5 );
shadowmapSizeSlider->SetSliderChangedCallback( ShadowQualitySliderChanged, this );
shadowmapSizeSlider->SetDisplayValues( { "0", "512", "1024", "2048", "4096", "8192", "16384" } );
if ( FeatureLevel10Compatibility ) {
shadowmapSizeSlider->SetDisplayValues( { "0", "512", "1024", "2048", "4096", "8192" } );
} else {
shadowmapSizeSlider->SetDisplayValues( { "0", "512", "1024", "2048", "4096", "8192", "16384" } );
}
shadowmapSizeSlider->SetIsIntegralSlider( true );
shadowmapSizeSlider->SetMinMax( 1.0f, 6.0f );

Expand Down
3 changes: 2 additions & 1 deletion D3D11Engine/D3D11GShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ XRESULT D3D11GShader::LoadShader( const char* geometryShader, const std::vector<
}

// Create the shader from a vertexshader
engine->GetDevice()->CreateGeometryShaderWithStreamOutput( gsBlob->GetBufferPointer(), gsBlob->GetBufferSize(), soDec, numSoDecElements, &stride, 1, D3D11_SO_NO_RASTERIZED_STREAM, nullptr, GeometryShader.GetAddressOf() );
LE( engine->GetDevice()->CreateGeometryShaderWithStreamOutput( gsBlob->GetBufferPointer(), gsBlob->GetBufferSize(), soDec, numSoDecElements, &stride, 1,
(FeatureLevel10Compatibility ? 0 : D3D11_SO_NO_RASTERIZED_STREAM), nullptr, GeometryShader.GetAddressOf() ) );
}

SetDebugName( GeometryShader.Get(), geometryShader );
Expand Down
15 changes: 14 additions & 1 deletion D3D11Engine/D3D11GraphicsEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,15 @@ XRESULT D3D11GraphicsEngine::OnResize( INT2 newSize ) {

DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFSDesc = {};

// Get current refresh rate
{
DEVMODEA devMode;
if ( EnumDisplaySettingsA( nullptr, ENUM_CURRENT_SETTINGS, &devMode ) ) {
swapChainFSDesc.RefreshRate.Numerator = devMode.dmDisplayFrequency;
swapChainFSDesc.RefreshRate.Denominator = 1;
}
}

if ( m_swapchainflip ) swapChainFSDesc.Windowed = true;
else {
bool windowed = Engine::GAPI->HasCommandlineParameter( "ZWINDOW" ) ||
Expand Down Expand Up @@ -710,7 +719,7 @@ XRESULT D3D11GraphicsEngine::OnResize( INT2 newSize ) {
HDRBackBuffer = std::make_unique<RenderToTextureBuffer>( GetDevice().Get(), Resolution.x, Resolution.y,
(Engine::GAPI->GetRendererState().RendererSettings.CompressBackBuffer ? DXGI_FORMAT_R11G11B10_FLOAT : DXGI_FORMAT_R16G16B16A16_FLOAT) );

int s = Engine::GAPI->GetRendererState().RendererSettings.ShadowMapSize;
int s = std::min<int>( std::max<int>( Engine::GAPI->GetRendererState().RendererSettings.ShadowMapSize, 512 ), (FeatureLevel10Compatibility ? 8192 : 16384) );
WorldShadowmap1 = std::make_unique<RenderToDepthStencilBuffer>(
GetDevice().Get(), s, s, DXGI_FORMAT_R16_TYPELESS, nullptr, DXGI_FORMAT_D16_UNORM,
DXGI_FORMAT_R16_UNORM );
Expand Down Expand Up @@ -811,6 +820,8 @@ XRESULT D3D11GraphicsEngine::OnBeginFrame() {
int s = Engine::GAPI->GetRendererState().RendererSettings.ShadowMapSize;

if ( WorldShadowmap1->GetSizeX() != s ) {
s = std::min<int>(std::max<int>(s, 512), (FeatureLevel10Compatibility ? 8192 : 16384));

int old = WorldShadowmap1->GetSizeX();
LogInfo() << "Shadowmapresolution changed to: " << s << "x" << s;
WorldShadowmap1 = std::make_unique<RenderToDepthStencilBuffer>(
Expand All @@ -821,6 +832,8 @@ XRESULT D3D11GraphicsEngine::OnBeginFrame() {

Engine::GAPI->GetRendererState().RendererSettings.WorldShadowRangeScale =
Toolbox::GetRecommendedWorldShadowRangeScaleForSize( s );

Engine::GAPI->GetRendererState().RendererSettings.ShadowMapSize = s;
}

// Force the mode
Expand Down
34 changes: 6 additions & 28 deletions D3D11Engine/GothicAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,16 +536,17 @@ void GothicAPI::OnGeometryLoaded( zCPolygon** polys, unsigned int numPolygons )
ResetWorld();
ResetMaterialInfo();

bool indoorLocation = (oCGame::GetGame()->_zCSession_world->GetBspTree()->GetBspTreeMode() == zBSP_MODE_INDOOR);
std::string worldStr = "system\\GD3D11\\meshes\\WLD_" + LoadedWorldInfo->WorldName + ".obj";
// Convert world to our own format
#ifdef BUILD_GOTHIC_2_6_fix
WorldConverter::ConvertWorldMesh( polys, numPolygons, &WorldSections, LoadedWorldInfo.get(), &WrappedWorldMesh );
WorldConverter::ConvertWorldMesh( polys, numPolygons, &WorldSections, LoadedWorldInfo.get(), &WrappedWorldMesh, indoorLocation );
#else
if ( Toolbox::FileExists( worldStr ) ) {
WorldConverter::LoadWorldMeshFromFile( worldStr, &WorldSections, LoadedWorldInfo.get(), &WrappedWorldMesh );
LoadedWorldInfo->CustomWorldLoaded = true;
} else {
WorldConverter::ConvertWorldMesh( polys, numPolygons, &WorldSections, LoadedWorldInfo.get(), &WrappedWorldMesh );
WorldConverter::ConvertWorldMesh( polys, numPolygons, &WorldSections, LoadedWorldInfo.get(), &WrappedWorldMesh, indoorLocation );
}
#endif
LogInfo() << "Done extracting world!";
Expand Down Expand Up @@ -3114,6 +3115,7 @@ void GothicAPI::BuildBspVobMapCacheHelper( zCBspBase* base ) {
BspInfo& bvi = BspLeafVobLists[base];
bvi.OriginalNode = base;

bool outdoorLocation = (LoadedWorldInfo->BspTree->GetBspTreeMode() == zBSP_MODE_OUTDOOR);
if ( base->IsLeaf() ) {
zCBspLeaf* leaf = (zCBspLeaf*)base;

Expand All @@ -3130,7 +3132,8 @@ void GothicAPI::BuildBspVobMapCacheHelper( zCBspBase* base ) {
if ( v ) {
float vobSmallSize = Engine::GAPI->GetRendererState().RendererSettings.SmallVobSize;

if ( vob->IsIndoorVob() ) {
// Treat indoor vobs as indoor vobs only in outdoor locations
if ( outdoorLocation && vob->IsIndoorVob() ) {
// Only add once
if ( std::find( bvi.IndoorVobs.begin(), bvi.IndoorVobs.end(), v ) == bvi.IndoorVobs.end() ) {
v->ParentBSPNodes.push_back( &bvi );
Expand Down Expand Up @@ -3188,31 +3191,6 @@ void GothicAPI::BuildBspVobMapCacheHelper( zCBspBase* base ) {
vi->IsIndoorVob = true;
}
}

VobLightInfo* vi = VobLightMap[vob];
if ( vi ) {
if ( !vi->IsIndoorVob ) {
// Only add once
if ( std::find( bvi.Lights.begin(), bvi.Lights.end(), vi ) == bvi.Lights.end() ) {
vi->ParentBSPNodes.push_back( &bvi );
bvi.Lights.push_back( vi );
}
} else {
// Only add once
if ( std::find( bvi.IndoorLights.begin(), bvi.IndoorLights.end(), vi ) == bvi.IndoorLights.end() ) {
vi->ParentBSPNodes.push_back( &bvi );
bvi.IndoorLights.push_back( vi );
}
}

#ifdef BUILD_SPACER
// Add lights to drawable voblist, so we can draw their helper-visuals when wanted
// Also, make sure they end up in the dynamic list, so their visuals don't stay in place
//VobInfo * v = VobMap[leaf->LightVobList.Array[i]];
//if (v)
// MoveVobFromBspToDynamic(v);
#endif
}
}

bvi.NumStaticLights = leaf->LightVobList.NumInArray;
Expand Down
2 changes: 2 additions & 0 deletions D3D11Engine/GothicMemoryLocations1_08k.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ struct GothicMemoryLocations {
static const unsigned int DrawLine = 0x00716B00;
static const unsigned int DrawPoly = 0x00714B60;
static const unsigned int DrawPolySimple = 0x007143F0;
static const unsigned int CacheInSurface = 0x0071A3E0;
static const unsigned int CacheOutSurface = 0x0071A7F0;

static const unsigned int Offset_RenderState = 0x34;
static const unsigned int Offset_BoundTexture = 0x80E38;
Expand Down
2 changes: 2 additions & 0 deletions D3D11Engine/GothicMemoryLocations1_12f.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ struct GothicMemoryLocations {
static const unsigned int DrawLine = 0x00752A70;
static const unsigned int DrawPoly = 0x00750960;
static const unsigned int DrawPolySimple = 0x007501C0;
static const unsigned int CacheInSurface = 0x007565D0;
static const unsigned int CacheOutSurface = 0x00756A60;

static const unsigned int Offset_RenderState = 0x34;
static const unsigned int Offset_BoundTexture = 0x80E38;
Expand Down
2 changes: 2 additions & 0 deletions D3D11Engine/GothicMemoryLocations2_6_fix.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ struct GothicMemoryLocations {
static const unsigned int DrawLine = 0x0064d8e0;
static const unsigned int DrawPoly = 0x0064B260;
static const unsigned int DrawPolySimple = 0x0064AC30;
static const unsigned int CacheInSurface = 0x00652B90;
static const unsigned int CacheOutSurface = 0x00652F40;
static const unsigned int Vid_GetGammaCorrection = 0x00659610;

static const unsigned int Offset_RenderState = 0x38;
Expand Down
11 changes: 9 additions & 2 deletions D3D11Engine/HookedFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,16 @@ void HookedFunctionInfo::InitHooks() {
#ifdef BUILD_1_12F
LogInfo() << "Patching: Fix integer overflow crash";
PatchAddr( 0x00506B31, "\xEB" );

LogInfo() << "Patching: Marking texture as cached-in after cache-out";
PatchAddr( 0x005E90BE, "\x90\x90" );
#else
LogInfo() << "Patching: Fix integer overflow crash";
PatchAddr( 0x004F4024, "\xEB" );
PatchAddr( 0x004F43FC, "\xEB" );

LogInfo() << "Patching: Marking texture as cached-in after cache-out";
PatchAddr( 0x005CA683, "\x90\x90" );
#endif
#endif

Expand Down Expand Up @@ -121,9 +127,10 @@ void HookedFunctionInfo::InitHooks() {
LogInfo() << "Patching: Texture size is lower than 32 - fix";
PatchAddr( 0x005F4E20, "\xC7\x05\xBC\xB3\x99\x00\x00\x40\x00\x00\xEB\x4D\x90\x90" );

#endif
LogInfo() << "Patching: Marking texture as cached-in after cache-out";
PatchAddr( 0x005F5573, "\x90\x90" );

// HACK Workaround to fix debuglines in godmode
#if (defined BUILD_GOTHIC_2_6_fix)
LogInfo() << "Patching: Godmode Debuglines";
// oCMagFrontier::GetDistanceNewWorld
PatchAddr( 0x00473f37, "\xBD\x00\x00\x00\x00" ); // replace MOV EBP, 0x1 with MOV EBP, 0x0
Expand Down
18 changes: 6 additions & 12 deletions D3D11Engine/WorldConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ HRESULT WorldConverter::ConvertWorldMeshPNAEN( zCPolygon** polys, unsigned int n
}

/** Converts the worldmesh into a more usable format */
HRESULT WorldConverter::ConvertWorldMesh( zCPolygon** polys, unsigned int numPolygons, std::map<int, std::map<int, WorldMeshSectionInfo>>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh ) {
HRESULT WorldConverter::ConvertWorldMesh( zCPolygon** polys, unsigned int numPolygons, std::map<int, std::map<int, WorldMeshSectionInfo>>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh, bool indoorLocation ) {
// Go through every polygon and put it into its section
for ( unsigned int i = 0; i < numPolygons; i++ ) {
zCPolygon* poly = polys[i];
Expand Down Expand Up @@ -585,12 +585,14 @@ HRESULT WorldConverter::ConvertWorldMesh( zCPolygon** polys, unsigned int numPol
if ( poly->GetLightmap() ) {
t.TexCoord2 = poly->GetLightmap()->GetLightmapUV( *t.Position.toXMFLOAT3() );
t.Color = DEFAULT_LIGHTMAP_POLY_COLOR;
} else if ( indoorLocation ) {
t.TexCoord2 = float2( 0.0f, 0.0f );
t.Color = DEFAULT_LIGHTMAP_POLY_COLOR;
} else {
t.TexCoord2.x = 0.0f;
t.TexCoord2.y = 0.0f;
t.TexCoord2 = float2( 0.0f, 0.0f );

if ( poly->GetMaterial() && poly->GetMaterial()->GetMatGroup() == zMAT_GROUP_WATER ) {
t.Normal = float3( 0, 1, 0 ); // Get rid of ugly shadows on water
t.Normal = float3( 0.0f, 1.0f, 0.0f ); // 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;
Expand Down Expand Up @@ -720,14 +722,6 @@ HRESULT WorldConverter::ConvertWorldMesh( zCPolygon** polys, unsigned int numPol
Engine::GraphicsEngine->CreateVertexBuffer( &wmi->MeshVertexBuffer );
Engine::GraphicsEngine->CreateVertexBuffer( &wmi->MeshIndexBuffer );

LogInfo() << "Smoothing worldmesh normals...";
DWORD sStart = Toolbox::timeSinceStartMs();

// Generate smooth normals
//MeshModifier::ComputeSmoothNormals( wrappedVertices );

LogInfo() << "Process took " << Toolbox::timeSinceStartMs() - sStart << "ms";

// Init and fill them
wmi->MeshVertexBuffer->Init( &wrappedVertices[0], wrappedVertices.size() * sizeof( ExVertexStruct ), D3D11VertexBuffer::B_VERTEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE );
wmi->MeshIndexBuffer->Init( &wrappedIndices[0], wrappedIndices.size() * sizeof( unsigned int ), D3D11VertexBuffer::B_INDEXBUFFER, D3D11VertexBuffer::U_IMMUTABLE );
Expand Down
2 changes: 1 addition & 1 deletion D3D11Engine/WorldConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class WorldConverter {
static void WorldMeshCollectPolyRange( const float3& position, float range, std::map<int, std::map<int, WorldMeshSectionInfo>>& inSections, std::map<MeshKey, WorldMeshInfo*, cmpMeshKey>& outMeshes );

/** Converts the worldmesh into a more usable format */
static HRESULT ConvertWorldMesh( zCPolygon** polys, unsigned int numPolygons, std::map<int, std::map<int, WorldMeshSectionInfo>>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh );
static HRESULT ConvertWorldMesh( zCPolygon** polys, unsigned int numPolygons, std::map<int, std::map<int, WorldMeshSectionInfo>>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh, bool indoorLocation );

/** Converts the worldmesh into a PNAEN-buffer */
static HRESULT ConvertWorldMeshPNAEN( zCPolygon** polys, unsigned int numPolygons, std::map<int, std::map<int, WorldMeshSectionInfo>>* outSections, WorldInfo* info, MeshInfo** outWrappedMesh );
Expand Down
12 changes: 12 additions & 0 deletions D3D11Engine/zCRndD3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ class zCRndD3D {

XHook( HookedFunctions::OriginalFunctions.original_zCRnd_D3D_DrawPoly, GothicMemoryLocations::zCRndD3D::DrawPoly, hooked_zCRndD3DDrawPoly );
XHook( HookedFunctions::OriginalFunctions.original_zCRnd_D3D_DrawPolySimple, GothicMemoryLocations::zCRndD3D::DrawPolySimple, hooked_zCRndD3DDrawPolySimple );

XHook( GothicMemoryLocations::zCRndD3D::CacheInSurface, hooked_zCSurfaceCache_D3DCacheInSurface );
XHook( GothicMemoryLocations::zCRndD3D::CacheOutSurface, hooked_zCSurfaceCache_D3DCacheOutSurface );
}

/** Disable caching surfaces to let engine create new surfaces for every textures */
static int __fastcall hooked_zCSurfaceCache_D3DCacheInSurface( void* thisptr, void* _EDX, void* surface, void* slotindex ) {
return FALSE;
}

static void* __fastcall hooked_zCSurfaceCache_D3DCacheOutSurface( void* thisptr, void* _EDX, void* slotindex ) {
return nullptr;
}

/** Draws a straight line from xyz1 to xyz2 */
Expand Down

0 comments on commit 5e4e9bf

Please sign in to comment.