This commit is contained in:
Lwmte 2024-12-24 00:51:11 +01:00
parent 12dae8df99
commit ca25f87738
17 changed files with 524 additions and 375 deletions

View file

@ -61,6 +61,18 @@ namespace TEN::Renderer
_isLocked = true; _isLocked = true;
} }
void Renderer::ReloadShaders()
{
try
{
_shaderManager.LoadAllShaders(_screenWidth, _screenHeight);
}
catch (const std::exception& e)
{
TENLog("An exception occured during shader reload: " + std::string(e.what()), LogLevel::Error);
}
}
int Renderer::Synchronize() int Renderer::Synchronize()
{ {
// Sync the renderer // Sync the renderer

View file

@ -53,6 +53,7 @@
#include "Renderer/Graphics/Texture2DArray.h" #include "Renderer/Graphics/Texture2DArray.h"
#include "Renderer/Graphics/VertexBuffer.h" #include "Renderer/Graphics/VertexBuffer.h"
#include "Renderer/Graphics/Vertices/PostProcessVertex.h" #include "Renderer/Graphics/Vertices/PostProcessVertex.h"
#include "Renderer/ShaderManager/ShaderManager.h"
#include "Renderer/Structures/RendererItem.h" #include "Renderer/Structures/RendererItem.h"
#include "Renderer/Structures/RendererEffect.h" #include "Renderer/Structures/RendererEffect.h"
#include "Renderer/Structures/RendererLine3D.h" #include "Renderer/Structures/RendererLine3D.h"
@ -65,7 +66,6 @@
#include "Renderer/Structures/RendererRoomAmbientMap.h" #include "Renderer/Structures/RendererRoomAmbientMap.h"
#include "Renderer/Structures/RendererObject.h" #include "Renderer/Structures/RendererObject.h"
#include "Renderer/Structures/RendererStar.h" #include "Renderer/Structures/RendererStar.h"
#include "Structures/RendererShader.h"
enum GAME_OBJECT_ID : short; enum GAME_OBJECT_ID : short;
enum class SphereSpaceType; enum class SphereSpaceType;
@ -81,6 +81,7 @@ namespace TEN::Renderer
using namespace TEN::Renderer::ConstantBuffers; using namespace TEN::Renderer::ConstantBuffers;
using namespace TEN::Renderer::Graphics; using namespace TEN::Renderer::Graphics;
using namespace TEN::Renderer::Structures; using namespace TEN::Renderer::Structures;
using namespace TEN::Renderer::Utils;
using namespace DirectX::SimpleMath; using namespace DirectX::SimpleMath;
using TexturePair = std::tuple<Texture2D, Texture2D>; using TexturePair = std::tuple<Texture2D, Texture2D>;
@ -123,34 +124,6 @@ namespace TEN::Renderer
RenderTarget2D _tempRoomAmbientRenderTarget4; RenderTarget2D _tempRoomAmbientRenderTarget4;
Texture2DArray _shadowMap; Texture2DArray _shadowMap;
// Shaders
RendererShader _sRooms;
RendererShader _sRoomsAnimated;
RendererShader _sRoomsTransparent;
RendererShader _sRoomAmbient;
RendererShader _sRoomAmbientSky;
RendererShader _sItems;
RendererShader _sStatics;
RendererShader _sInstancedStatics;
RendererShader _sSprites;
RendererShader _sInstancedSprites;
RendererShader _sSky;
RendererShader _sSolid;
RendererShader _sInventory;
RendererShader _sFullScreenQuad;
RendererShader _sShadowMap;
RendererShader _sHUD;
RendererShader _sHUDColor;
RendererShader _sHUDTexture;
RendererShader _sHUDBarColor;
RendererShader _sGBuffer;
RendererShader _sGBufferRooms;
RendererShader _sGBufferRoomsAnimated;
RendererShader _sGBufferItems;
RendererShader _sGBufferStatics;
RendererShader _sGBufferInstancedStatics;
// Constant buffers // Constant buffers
RenderView _gameCamera; RenderView _gameCamera;
@ -341,14 +314,6 @@ namespace TEN::Renderer
RenderTarget2D _SMAAEdgesRenderTarget; RenderTarget2D _SMAAEdgesRenderTarget;
RenderTarget2D _SMAABlendRenderTarget; RenderTarget2D _SMAABlendRenderTarget;
RendererShader _sSMAAEdgeDetection;
RendererShader _sSMAALumaEdgeDetection;
RendererShader _sSMAAColorEdgeDetection;
RendererShader _sSMAADepthEdgeDetection;
RendererShader _sSMAABlendingWeightCalculation;
RendererShader _sSMAANeighborhoodBlending;
RendererShader _sFXAA;
// Post-process // Post-process
PostProcessMode _postProcessMode = PostProcessMode::None; PostProcessMode _postProcessMode = PostProcessMode::None;
@ -357,12 +322,6 @@ namespace TEN::Renderer
VertexBuffer<PostProcessVertex> _fullscreenTriangleVertexBuffer; VertexBuffer<PostProcessVertex> _fullscreenTriangleVertexBuffer;
ComPtr<ID3D11InputLayout> _fullscreenTriangleInputLayout = nullptr; ComPtr<ID3D11InputLayout> _fullscreenTriangleInputLayout = nullptr;
RendererShader _sPostProcess;
RendererShader _sPostProcessMonochrome;
RendererShader _sPostProcessNegative;
RendererShader _sPostProcessExclusion;
RendererShader _sPostProcessFinalPass;
RendererShader _sPostProcessLensFlare;
bool _doingFullscreenPass = false; bool _doingFullscreenPass = false;
@ -373,9 +332,6 @@ namespace TEN::Renderer
RenderTarget2D _SSAOBlurredRenderTarget; RenderTarget2D _SSAOBlurredRenderTarget;
std::vector<Vector4> _SSAOKernel; std::vector<Vector4> _SSAOKernel;
RendererShader _sSSAO;
RendererShader _sSSAOBlur;
// New ambient light techinque // New ambient light techinque
RenderTarget2D _roomAmbientMapFront; RenderTarget2D _roomAmbientMapFront;
@ -398,10 +354,9 @@ namespace TEN::Renderer
float _interpolationFactor = 0.0f; float _interpolationFactor = 0.0f;
bool _graphicsSettingsChanged = false; bool _graphicsSettingsChanged = false;
// Private functions // Shader manager.
RendererShader CompileOrLoadShader(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines = nullptr); ShaderManager _shaderManager;
void BindShader(const RendererShader& shader);
void ApplySMAA(RenderTarget2D* renderTarget, RenderView& view); void ApplySMAA(RenderTarget2D* renderTarget, RenderView& view);
void ApplyFXAA(RenderTarget2D* renderTarget, RenderView& view); void ApplyFXAA(RenderTarget2D* renderTarget, RenderView& view);
@ -643,6 +598,7 @@ namespace TEN::Renderer
void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison); void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison);
void Create(); void Create();
void Initialize(int w, int h, bool windowed, HWND handle); void Initialize(int w, int h, bool windowed, HWND handle);
void ReloadShaders();
void Render(float interpFactor); void Render(float interpFactor);
void RenderTitle(float interpFactor); void RenderTitle(float interpFactor);
void Lock(); void Lock();

View file

@ -14,7 +14,7 @@ namespace TEN::Renderer
ResetScissor(); ResetScissor();
// Common vertex shader to all fullscreen effects // Common vertex shader to all fullscreen effects
BindShader(_sPostProcess); _shaderManager.Bind(Shader::PostProcess);
// We draw a fullscreen triangle // We draw a fullscreen triangle
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@ -40,8 +40,8 @@ namespace TEN::Renderer
SetCullMode(CullMode::CounterClockwise); SetCullMode(CullMode::CounterClockwise);
_context->OMSetRenderTargets(1, _SMAAEdgesRenderTarget.RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, _SMAAEdgesRenderTarget.RenderTargetView.GetAddressOf(), nullptr);
BindShader(_sSMAAEdgeDetection); _shaderManager.Bind(Shader::SMAAEdgeDetection);
BindShader(_sSMAAColorEdgeDetection); _shaderManager.Bind(Shader::SMAAColorEdgeDetection);
_stSMAABuffer.BlendFactor = 1.0f; _stSMAABuffer.BlendFactor = 1.0f;
_cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get()); _cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get());
@ -59,7 +59,7 @@ namespace TEN::Renderer
// 2) Blend weights calculation. // 2) Blend weights calculation.
_context->OMSetRenderTargets(1, _SMAABlendRenderTarget.RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, _SMAABlendRenderTarget.RenderTargetView.GetAddressOf(), nullptr);
BindShader(_sSMAABlendingWeightCalculation); _shaderManager.Bind(Shader::SMAABlendingWeightCalculation);
_stSMAABuffer.SubsampleIndices = Vector4::Zero; _stSMAABuffer.SubsampleIndices = Vector4::Zero;
_cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get()); _cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get());
@ -76,7 +76,7 @@ namespace TEN::Renderer
// 3) Neighborhood blending. // 3) Neighborhood blending.
_context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr);
BindShader(_sSMAANeighborhoodBlending); _shaderManager.Bind(Shader::SMAANeighborhoodBlending);
BindRenderTargetAsTexture(static_cast<TextureRegister>(0), &_SMAASceneRenderTarget, SamplerStateRegister::LinearClamp); BindRenderTargetAsTexture(static_cast<TextureRegister>(0), &_SMAASceneRenderTarget, SamplerStateRegister::LinearClamp);
BindRenderTargetAsTexture(static_cast<TextureRegister>(1), &_SMAASceneSRGBRenderTarget, SamplerStateRegister::LinearClamp); BindRenderTargetAsTexture(static_cast<TextureRegister>(1), &_SMAASceneSRGBRenderTarget, SamplerStateRegister::LinearClamp);
@ -100,7 +100,7 @@ namespace TEN::Renderer
ResetScissor(); ResetScissor();
// Common vertex shader to all fullscreen effects // Common vertex shader to all fullscreen effects
BindShader(_sPostProcess); _shaderManager.Bind(Shader::PostProcess);
// We draw a fullscreen triangle // We draw a fullscreen triangle
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@ -123,7 +123,7 @@ namespace TEN::Renderer
_context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black); _context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black);
_context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr);
BindShader(_sFXAA); _shaderManager.Bind(Shader::FXAA);
_stPostProcessBuffer.ViewportWidth = _screenWidth; _stPostProcessBuffer.ViewportWidth = _screenWidth;
_stPostProcessBuffer.ViewportHeight = _screenHeight; _stPostProcessBuffer.ViewportHeight = _screenHeight;

View file

@ -167,7 +167,7 @@ namespace TEN::Renderer
UINT offset = 0; UINT offset = 0;
// Set shaders // Set shaders
BindShader(_sShadowMap); _shaderManager.Bind(Shader::ShadowMap);
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@ -284,7 +284,7 @@ namespace TEN::Renderer
{ {
auto& moveableObject = *_moveableObjects[objectID]; auto& moveableObject = *_moveableObjects[objectID];
BindShader(_sInstancedStatics); _shaderManager.Bind(Shader::InstancedStatics);
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
unsigned int offset = 0; unsigned int offset = 0;
@ -361,7 +361,7 @@ namespace TEN::Renderer
SetDepthState(DepthState::Read); SetDepthState(DepthState::Read);
SetCullMode(CullMode::None); SetCullMode(CullMode::None);
BindShader(_sSolid); _shaderManager.Bind(Shader::Solid);
auto worldMatrix = Matrix::CreateOrthographicOffCenter(0, _screenWidth, _screenHeight, 0, _viewport.MinDepth, _viewport.MaxDepth); auto worldMatrix = Matrix::CreateOrthographicOffCenter(0, _screenWidth, _screenHeight, 0, _viewport.MinDepth, _viewport.MaxDepth);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
@ -531,12 +531,12 @@ namespace TEN::Renderer
{ {
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferStatics); _shaderManager.Bind(Shader::GBufferStatics);
} }
else else
{ {
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
} }
UINT stride = sizeof(Vertex); UINT stride = sizeof(Vertex);
@ -656,12 +656,12 @@ namespace TEN::Renderer
{ {
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferStatics); _shaderManager.Bind(Shader::GBufferStatics);
} }
else else
{ {
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
} }
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
@ -792,12 +792,12 @@ namespace TEN::Renderer
{ {
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferInstancedStatics); _shaderManager.Bind(Shader::GBufferInstancedStatics);
} }
else else
{ {
BindShader(_sInstancedStatics); _shaderManager.Bind(Shader::InstancedStatics);
} }
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
@ -919,12 +919,12 @@ namespace TEN::Renderer
{ {
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferInstancedStatics); _shaderManager.Bind(Shader::GBufferInstancedStatics);
} }
else else
{ {
BindShader(_sInstancedStatics); _shaderManager.Bind(Shader::InstancedStatics);
} }
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
@ -1026,12 +1026,12 @@ namespace TEN::Renderer
{ {
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferStatics); _shaderManager.Bind(Shader::GBufferStatics);
} }
else else
{ {
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
} }
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
@ -1089,7 +1089,7 @@ namespace TEN::Renderer
SetBlendMode(BlendMode::Additive); SetBlendMode(BlendMode::Additive);
SetCullMode(CullMode::None); SetCullMode(CullMode::None);
BindShader(_sSolid); _shaderManager.Bind(Shader::Solid);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
@ -1122,7 +1122,7 @@ namespace TEN::Renderer
SetBlendMode(BlendMode::Additive); SetBlendMode(BlendMode::Additive);
SetCullMode(CullMode::None); SetCullMode(CullMode::None);
BindShader(_sSolid); _shaderManager.Bind(Shader::Solid);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetInputLayout(_inputLayout.Get()); _context->IASetInputLayout(_inputLayout.Get());
@ -1926,7 +1926,7 @@ namespace TEN::Renderer
SetBlendMode(BlendMode::Opaque); SetBlendMode(BlendMode::Opaque);
SetCullMode(CullMode::CounterClockwise); SetCullMode(CullMode::CounterClockwise);
BindShader(_sRoomAmbient); _shaderManager.Bind(Shader::RoomAmbient);
// Bind and clear render target // Bind and clear render target
_context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black); _context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black);
@ -1976,7 +1976,7 @@ namespace TEN::Renderer
if (levelPtr->Horizon) if (levelPtr->Horizon)
{ {
BindShader(_sRoomAmbientSky); _shaderManager.Bind(Shader::RoomAmbientSky);
if (Lara.Control.Look.OpticRange != 0) if (Lara.Control.Look.OpticRange != 0)
AlterFOV(ANGLE(DEFAULT_FOV) - Lara.Control.Look.OpticRange, false); AlterFOV(ANGLE(DEFAULT_FOV) - Lara.Control.Look.OpticRange, false);
@ -2058,7 +2058,7 @@ namespace TEN::Renderer
_context->ClearDepthStencilView(renderTarget->DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); _context->ClearDepthStencilView(renderTarget->DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
} }
BindShader(_sRoomAmbient); _shaderManager.Bind(Shader::RoomAmbient);
// Draw rooms // Draw rooms
UINT stride = sizeof(Vertex); UINT stride = sizeof(Vertex);
@ -2264,12 +2264,12 @@ namespace TEN::Renderer
// Set shaders. // Set shaders.
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferItems); _shaderManager.Bind(Shader::GBufferItems);
} }
else else
{ {
BindShader(_sItems); _shaderManager.Bind(Shader::Items);
} }
BindRenderTargetAsTexture(TextureRegister::SSAO, &_SSAOBlurredRenderTarget, SamplerStateRegister::PointWrap); BindRenderTargetAsTexture(TextureRegister::SSAO, &_SSAOBlurredRenderTarget, SamplerStateRegister::PointWrap);
@ -2406,12 +2406,12 @@ namespace TEN::Renderer
#ifdef DISABLE_INSTANCING #ifdef DISABLE_INSTANCING
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferStatics); _shaderManager.Bind(Shader::GBufferStatics);
} }
else else
{ {
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
} }
// Bind vertex and index buffer // Bind vertex and index buffer
@ -2487,12 +2487,12 @@ namespace TEN::Renderer
#else #else
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
BindShader(_sGBufferInstancedStatics); _shaderManager.Bind(Shader::GBufferInstancedStatics);
} }
else else
{ {
BindShader(_sInstancedStatics); _shaderManager.Bind(Shader::InstancedStatics);
} }
// Bind vertex and index buffer // Bind vertex and index buffer
@ -2682,11 +2682,11 @@ namespace TEN::Renderer
{ {
if (rendererPass == RendererPass::GBuffer) if (rendererPass == RendererPass::GBuffer)
{ {
BindShader(_sGBuffer); _shaderManager.Bind(Shader::GBuffer);
} }
else else
{ {
BindShader(_sRooms); _shaderManager.Bind(Shader::Rooms);
} }
UINT stride = sizeof(Vertex); UINT stride = sizeof(Vertex);
@ -2750,11 +2750,11 @@ namespace TEN::Renderer
{ {
if (rendererPass != RendererPass::GBuffer) if (rendererPass != RendererPass::GBuffer)
{ {
if (animated == 0) BindShader(_sRooms); else BindShader(_sRoomsAnimated); if (animated == 0) _shaderManager.Bind(Shader::Rooms); else _shaderManager.Bind(Shader::RoomsAnimated);
} }
else else
{ {
if (animated == 0) BindShader(_sGBufferRooms); else BindShader(_sGBufferRoomsAnimated); if (animated == 0) _shaderManager.Bind(Shader::GBufferRooms); else _shaderManager.Bind(Shader::GBufferRoomsAnimated);
} }
for (const auto& bucket : room.Buckets) for (const auto& bucket : room.Buckets)
@ -2853,7 +2853,7 @@ namespace TEN::Renderer
// Draw sky. // Draw sky.
auto rotation = Matrix::CreateRotationX(PI); auto rotation = Matrix::CreateRotationX(PI);
BindShader(_sSky); _shaderManager.Bind(Shader::Sky);
BindTexture(TextureRegister::ColorMap, &_skyTexture, SamplerStateRegister::AnisotropicClamp); BindTexture(TextureRegister::ColorMap, &_skyTexture, SamplerStateRegister::AnisotropicClamp);
_context->IASetVertexBuffers(0, 1, _skyVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); _context->IASetVertexBuffers(0, 1, _skyVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
@ -2894,7 +2894,7 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
BindShader(_sInstancedSprites); _shaderManager.Bind(Shader::InstancedSprites);
// Set up vertex buffer and parameters. // Set up vertex buffer and parameters.
UINT stride = sizeof(Vertex); UINT stride = sizeof(Vertex);
@ -3033,7 +3033,7 @@ namespace TEN::Renderer
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
BindShader(_sSky); _shaderManager.Bind(Shader::Sky);
auto& moveableObj = *_moveableObjects[ID_HORIZON]; auto& moveableObj = *_moveableObjects[ID_HORIZON];
@ -3077,7 +3077,7 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
BindShader(_sInstancedSprites); _shaderManager.Bind(Shader::InstancedSprites);
// Set up vertex buffer and parameters. // Set up vertex buffer and parameters.
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
@ -3504,7 +3504,7 @@ namespace TEN::Renderer
ROOM_INFO* nativeRoom = &g_Level.Rooms[objectInfo->Room->RoomNumber]; ROOM_INFO* nativeRoom = &g_Level.Rooms[objectInfo->Room->RoomNumber];
BindShader(_sRooms); _shaderManager.Bind(Shader::Rooms);
UINT stride = sizeof(Vertex); UINT stride = sizeof(Vertex);
UINT offset = 0; UINT offset = 0;
@ -3521,7 +3521,7 @@ namespace TEN::Renderer
SetScissor(objectInfo->Room->ClipBounds); SetScissor(objectInfo->Room->ClipBounds);
if (objectInfo->Bucket->Animated != 0) if (objectInfo->Bucket->Animated != 0)
BindShader(_sRoomsAnimated); _shaderManager.Bind(Shader::RoomsAnimated);
SetBlendMode(objectInfo->Bucket->BlendMode); SetBlendMode(objectInfo->Bucket->BlendMode);
SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD); SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
@ -3587,7 +3587,7 @@ namespace TEN::Renderer
SetBlendMode(objectInfo->Bucket->BlendMode); SetBlendMode(objectInfo->Bucket->BlendMode);
SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD); SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
BindShader(_sItems); _shaderManager.Bind(Shader::Items);
// Bind main item properties. // Bind main item properties.
Matrix world = objectInfo->Item->InterpolatedWorld; Matrix world = objectInfo->Item->InterpolatedWorld;
@ -3627,7 +3627,7 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetInputLayout(_inputLayout.Get()); _context->IASetInputLayout(_inputLayout.Get());
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
Matrix world = objectInfo->Static->World; Matrix world = objectInfo->Static->World;
_stStatic.World = world; _stStatic.World = world;
@ -3665,7 +3665,7 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetInputLayout(_inputLayout.Get()); _context->IASetInputLayout(_inputLayout.Get());
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
Matrix world = objectInfo->World; Matrix world = objectInfo->World;
_stStatic.World = world; _stStatic.World = world;
@ -3704,10 +3704,10 @@ namespace TEN::Renderer
SetDepthState(DepthState::Write); SetDepthState(DepthState::Write);
// Common vertex shader to all full screen effects // Common vertex shader to all full screen effects
BindShader(_sPostProcess); _shaderManager.Bind(Shader::PostProcess);
// SSAO pixel shader // SSAO pixel shader
BindShader(_sSSAO); _shaderManager.Bind(Shader::SSAO);
_context->ClearRenderTargetView(_SSAORenderTarget.RenderTargetView.Get(), Colors::White); _context->ClearRenderTargetView(_SSAORenderTarget.RenderTargetView.Get(), Colors::White);
_context->OMSetRenderTargets(1, _SSAORenderTarget.RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, _SSAORenderTarget.RenderTargetView.GetAddressOf(), nullptr);
@ -3751,7 +3751,7 @@ namespace TEN::Renderer
DrawTriangles(3, 0); DrawTriangles(3, 0);
// Blur step // Blur step
BindShader(_sSSAOBlur); _shaderManager.Bind(Shader::SSAOBlur);
_context->ClearRenderTargetView(_SSAOBlurredRenderTarget.RenderTargetView.Get(), Colors::Black); _context->ClearRenderTargetView(_SSAOBlurredRenderTarget.RenderTargetView.Get(), Colors::Black);
_context->OMSetRenderTargets(1, _SSAOBlurredRenderTarget.RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, _SSAOBlurredRenderTarget.RenderTargetView.GetAddressOf(), nullptr);

View file

@ -132,8 +132,8 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetIndexBuffer(bar.IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); _context->IASetIndexBuffer(bar.IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
BindShader(_sHUD); _shaderManager.Bind(Shader::HUD);
BindShader(_sHUDTexture); _shaderManager.Bind(Shader::HUDTexture);
SetBlendMode(BlendMode::Opaque); SetBlendMode(BlendMode::Opaque);
SetDepthState(DepthState::None); SetDepthState(DepthState::None);
@ -161,8 +161,8 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetIndexBuffer(bar.InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); _context->IASetIndexBuffer(bar.InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
BindShader(_sHUD); _shaderManager.Bind(Shader::HUD);
BindShader(_sHUDBarColor); _shaderManager.Bind(Shader::HUDBarColor);
_stHUDBar.Percent = percent; _stHUDBar.Percent = percent;
_stHUDBar.Poisoned = isPoisoned; _stHUDBar.Poisoned = isPoisoned;
@ -195,8 +195,8 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetIndexBuffer(g_LoadingBar->IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); _context->IASetIndexBuffer(g_LoadingBar->IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
BindShader(_sHUD); _shaderManager.Bind(Shader::HUD);
BindShader(_sHUDTexture); _shaderManager.Bind(Shader::HUDTexture);
SetBlendMode(BlendMode::Opaque); SetBlendMode(BlendMode::Opaque);
SetDepthState(DepthState::None); SetDepthState(DepthState::None);
@ -220,8 +220,8 @@ namespace TEN::Renderer
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetIndexBuffer(g_LoadingBar->InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); _context->IASetIndexBuffer(g_LoadingBar->InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
BindShader(_sHUD); _shaderManager.Bind(Shader::HUD);
BindShader(_sHUDBarColor); _shaderManager.Bind(Shader::HUDBarColor);
_stHUDBar.Percent = percentage / 100.0f; _stHUDBar.Percent = percentage / 100.0f;
_stHUDBar.Poisoned = false; _stHUDBar.Poisoned = false;
@ -305,7 +305,7 @@ namespace TEN::Renderer
vertices[3].UV.y = 1.0f; vertices[3].UV.y = 1.0f;
vertices[3].Color = Vector4(1.0f, 0.0f, 0.0f, 1.0f); vertices[3].Color = Vector4(1.0f, 0.0f, 0.0f, 1.0f);
BindShader(_sFullScreenQuad); _shaderManager.Bind(Shader::FullScreenQuad);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetInputLayout(_inputLayout.Get()); _context->IASetInputLayout(_inputLayout.Get());
@ -341,7 +341,7 @@ namespace TEN::Renderer
if (renderView.DisplaySpritesToDraw.empty()) if (renderView.DisplaySpritesToDraw.empty())
return; return;
BindShader(_sFullScreenQuad); _shaderManager.Bind(Shader::FullScreenQuad);
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_context->IASetInputLayout(_inputLayout.Get()); _context->IASetInputLayout(_inputLayout.Get());
@ -463,7 +463,7 @@ namespace TEN::Renderer
vertices[3].UV.y = uvEnd.y; vertices[3].UV.y = uvEnd.y;
vertices[3].Color = colorVec4; vertices[3].Color = colorVec4;
BindShader(_sFullScreenQuad); _shaderManager.Bind(Shader::FullScreenQuad);
_context->PSSetShaderResources(0, 1, &texture); _context->PSSetShaderResources(0, 1, &texture);
@ -540,7 +540,7 @@ namespace TEN::Renderer
vertices[3].UV.y = uvEnd.y; vertices[3].UV.y = uvEnd.y;
vertices[3].Color = Vector4(color.x, color.y, color.z, 1.0f); vertices[3].Color = Vector4(color.x, color.y, color.z, 1.0f);
BindShader(_sFullScreenQuad); _shaderManager.Bind(Shader::FullScreenQuad);
_context->PSSetShaderResources(0, 1, &texture); _context->PSSetShaderResources(0, 1, &texture);
auto* sampler = _renderStates->AnisotropicClamp(); auto* sampler = _renderStates->AnisotropicClamp();

View file

@ -1022,7 +1022,7 @@ namespace TEN::Renderer
if (!settings.MuzzleFlash) if (!settings.MuzzleFlash)
return false; return false;
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
unsigned int offset = 0; unsigned int offset = 0;
@ -1143,7 +1143,7 @@ namespace TEN::Renderer
void Renderer::DrawBaddyGunflashes(RenderView& view) void Renderer::DrawBaddyGunflashes(RenderView& view)
{ {
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
unsigned int offset = 0; unsigned int offset = 0;
@ -1369,7 +1369,7 @@ namespace TEN::Renderer
void Renderer::DrawEffects(RenderView& view, RendererPass rendererPass) void Renderer::DrawEffects(RenderView& view, RendererPass rendererPass)
{ {
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
unsigned int offset = 0; unsigned int offset = 0;
@ -1410,7 +1410,7 @@ namespace TEN::Renderer
if (activeDebrisExist) if (activeDebrisExist)
{ {
BindShader(_sStatics); _shaderManager.Bind(Shader::Statics);
SetCullMode(CullMode::None); SetCullMode(CullMode::None);

View file

@ -816,7 +816,7 @@ namespace TEN::Renderer
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set shaders. // Set shaders.
BindShader(_sInventory); _shaderManager.Bind(Shader::Inventory);
// Set matrices. // Set matrices.
CCameraMatrixBuffer hudCamera; CCameraMatrixBuffer hudCamera;
@ -1009,7 +1009,7 @@ namespace TEN::Renderer
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set shaders // Set shaders
BindShader(_sInventory); _shaderManager.Bind(Shader::Inventory);
if (CurrentLevel == 0) if (CurrentLevel == 0)
{ {

View file

@ -19,11 +19,6 @@ extern GameConfiguration g_Configuration;
using namespace TEN::Renderer::Utils; using namespace TEN::Renderer::Utils;
static std::wstring GetAssetPath(const wchar_t* fileName)
{
return TEN::Utils::ToWString(g_GameFlow->GetGameDir()) + fileName;
}
namespace TEN::Renderer namespace TEN::Renderer
{ {
void Renderer::Initialize(int w, int h, bool windowed, HWND handle) void Renderer::Initialize(int w, int h, bool windowed, HWND handle)
@ -36,13 +31,12 @@ namespace TEN::Renderer
InitializeScreen(w, h, handle, false); InitializeScreen(w, h, handle, false);
InitializeCommonTextures(); InitializeCommonTextures();
// Load shaders
_shaderManager.LoadAllShaders(w, h);
// Initialize render states // Initialize render states
_renderStates = std::make_unique<CommonStates>(_device.Get()); _renderStates = std::make_unique<CommonStates>(_device.Get());
// Load shaders
const D3D_SHADER_MACRO roomDefinesAnimated[] = { "ANIMATED", "", nullptr, nullptr };
const D3D_SHADER_MACRO roomDefinesShadowMap[] = { "SHADOW_MAP", "", nullptr, nullptr };
// Initialize input layout using first vertex shader. // Initialize input layout using first vertex shader.
D3D11_INPUT_ELEMENT_DESC inputLayoutItems[] = D3D11_INPUT_ELEMENT_DESC inputLayoutItems[] =
{ {
@ -60,40 +54,8 @@ namespace TEN::Renderer
{ "HASH", 0, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } { "HASH", 0, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
}; };
_sRooms = CompileOrLoadShader("Rooms", "", ShaderType::PixelAndVertex); auto& roomShader = _shaderManager.Get(Shader::Rooms);
Utils::throwIfFailed(_device->CreateInputLayout(inputLayoutItems, 12, _sRooms.Vertex.Blob->GetBufferPointer(), _sRooms.Vertex.Blob->GetBufferSize(), &_inputLayout)); Utils::throwIfFailed(_device->CreateInputLayout(inputLayoutItems, 12, roomShader.Vertex.Blob->GetBufferPointer(), roomShader.Vertex.Blob->GetBufferSize(), &_inputLayout));
_sRoomsAnimated = CompileOrLoadShader("Rooms", "", ShaderType::Vertex, &roomDefinesAnimated[0]);
_sItems = CompileOrLoadShader("Items", "", ShaderType::PixelAndVertex);
_sStatics = CompileOrLoadShader("Statics", "", ShaderType::PixelAndVertex);
_sSky = CompileOrLoadShader("Sky", "", ShaderType::PixelAndVertex);
_sSprites = CompileOrLoadShader("Sprites", "", ShaderType::PixelAndVertex);
_sSolid = CompileOrLoadShader("Solid", "", ShaderType::PixelAndVertex);
_sInventory = CompileOrLoadShader("Inventory", "", ShaderType::PixelAndVertex);
_sFullScreenQuad = CompileOrLoadShader("FullScreenQuad", "", ShaderType::PixelAndVertex);
_sShadowMap = CompileOrLoadShader("ShadowMap", "", ShaderType::PixelAndVertex, &roomDefinesShadowMap[0]);
_sHUD = CompileOrLoadShader("HUD", "", ShaderType::Vertex);
_sHUDColor = CompileOrLoadShader("HUD", "ColoredHUD", ShaderType::Pixel);
_sHUDTexture = CompileOrLoadShader("HUD", "TexturedHUD", ShaderType::Pixel);
_sHUDBarColor = CompileOrLoadShader("HUD", "TexturedHUDBar", ShaderType::Pixel);
_sInstancedStatics = CompileOrLoadShader("InstancedStatics", "", ShaderType::PixelAndVertex);
_sInstancedSprites = CompileOrLoadShader("InstancedSprites", "", ShaderType::PixelAndVertex);
_sGBuffer = CompileOrLoadShader("GBuffer", "", ShaderType::Pixel);
_sGBufferRooms = CompileOrLoadShader("GBuffer", "Rooms", ShaderType::Vertex);
_sGBufferRoomsAnimated = CompileOrLoadShader("GBuffer", "Rooms", ShaderType::Vertex, &roomDefinesAnimated[0]);
_sGBufferItems = CompileOrLoadShader("GBuffer", "Items", ShaderType::Vertex);
_sGBufferStatics = CompileOrLoadShader("GBuffer", "Statics", ShaderType::Vertex);
_sGBufferInstancedStatics = CompileOrLoadShader("GBuffer", "InstancedStatics", ShaderType::Vertex);
_sRoomAmbient = CompileOrLoadShader("RoomAmbient", "", ShaderType::PixelAndVertex);
_sRoomAmbientSky = CompileOrLoadShader("RoomAmbient", "Sky", ShaderType::Vertex);
_sFXAA = CompileOrLoadShader("FXAA", "", ShaderType::Pixel);
_sSSAO = CompileOrLoadShader("SSAO", "", ShaderType::Pixel);
_sSSAOBlur = CompileOrLoadShader("SSAO", "Blur", ShaderType::Pixel);
const D3D_SHADER_MACRO transparentDefines[] = { "TRANSPARENT", "", nullptr, nullptr };
_sRoomsTransparent = CompileOrLoadShader("Rooms", "", ShaderType::Pixel, &transparentDefines[0]);
// Initialize constant buffers // Initialize constant buffers
_cbCameraMatrices = CreateConstantBuffer<CCameraMatrixBuffer>(); _cbCameraMatrices = CreateConstantBuffer<CCameraMatrixBuffer>();
@ -220,7 +182,7 @@ namespace TEN::Renderer
shadowSamplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; shadowSamplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
shadowSamplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; shadowSamplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
Utils::throwIfFailed(_device->CreateSamplerState(&shadowSamplerDesc, _shadowSampler.GetAddressOf())); Utils::throwIfFailed(_device->CreateSamplerState(&shadowSamplerDesc, _shadowSampler.GetAddressOf()));
_shadowSampler->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("ShadowSampler") + 1, "ShadowSampler"); _shadowSampler->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("ShadowSampler") - 1, "ShadowSampler");
D3D11_RASTERIZER_DESC rasterizerStateDesc = {}; D3D11_RASTERIZER_DESC rasterizerStateDesc = {};
@ -285,8 +247,6 @@ namespace TEN::Renderer
_fullscreenTriangleVertexBuffer = VertexBuffer<PostProcessVertex>(_device.Get(), 3, &vertices[0]); _fullscreenTriangleVertexBuffer = VertexBuffer<PostProcessVertex>(_device.Get(), 3, &vertices[0]);
_sPostProcess = CompileOrLoadShader("PostProcess", "", ShaderType::PixelAndVertex);
D3D11_INPUT_ELEMENT_DESC postProcessInputLayoutItems[] = D3D11_INPUT_ELEMENT_DESC postProcessInputLayoutItems[] =
{ {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
@ -294,14 +254,9 @@ namespace TEN::Renderer
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
}; };
auto& ppShader = _shaderManager.Get(Shader::PostProcess);
Utils::throwIfFailed(_device->CreateInputLayout(postProcessInputLayoutItems, 3, Utils::throwIfFailed(_device->CreateInputLayout(postProcessInputLayoutItems, 3,
_sPostProcess.Vertex.Blob->GetBufferPointer(), _sPostProcess.Vertex.Blob->GetBufferSize(), &_fullscreenTriangleInputLayout)); ppShader.Vertex.Blob->GetBufferPointer(), ppShader.Vertex.Blob->GetBufferSize(), &_fullscreenTriangleInputLayout));
_sPostProcessMonochrome = CompileOrLoadShader("PostProcess", "Monochrome", ShaderType::Pixel);
_sPostProcessNegative = CompileOrLoadShader("PostProcess", "Negative", ShaderType::Pixel);
_sPostProcessExclusion = CompileOrLoadShader("PostProcess", "Exclusion", ShaderType::Pixel);
_sPostProcessFinalPass = CompileOrLoadShader("PostProcess", "FinalPass", ShaderType::Pixel);
_sPostProcessLensFlare = CompileOrLoadShader("PostProcess", "LensFlare", ShaderType::Pixel);
} }
void Renderer::CreateSSAONoiseTexture() void Renderer::CreateSSAONoiseTexture()
@ -382,8 +337,9 @@ namespace TEN::Renderer
void Renderer::InitializeSky() void Renderer::InitializeSky()
{ {
Vertex vertices[SKY_VERTICES_COUNT]; std::vector<Vertex> vertices(SKY_VERTICES_COUNT);
int indices[SKY_INDICES_COUNT]; std::vector<int> indices(SKY_INDICES_COUNT);
int size = SKY_SIZE; int size = SKY_SIZE;
int lastVertex = 0; int lastVertex = 0;
@ -452,8 +408,8 @@ namespace TEN::Renderer
} }
} }
_skyVertexBuffer = VertexBuffer<Vertex>(_device.Get(), SKY_VERTICES_COUNT, vertices); _skyVertexBuffer = VertexBuffer<Vertex>(_device.Get(), SKY_VERTICES_COUNT, vertices.data());
_skyIndexBuffer = IndexBuffer(_device.Get(), SKY_INDICES_COUNT, indices); _skyIndexBuffer = IndexBuffer(_device.Get(), SKY_INDICES_COUNT, indices.data());
} }
void Renderer::InitializeScreen(int w, int h, HWND handle, bool reset) void Renderer::InitializeScreen(int w, int h, HWND handle, bool reset)
@ -561,40 +517,6 @@ namespace TEN::Renderer
_SMAASceneSRGBRenderTarget = RenderTarget2D(_device.Get(), &_SMAASceneRenderTarget, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); _SMAASceneSRGBRenderTarget = RenderTarget2D(_device.Get(), &_SMAASceneRenderTarget, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
_SMAAEdgesRenderTarget = RenderTarget2D(_device.Get(), w, h, DXGI_FORMAT_R8G8_UNORM, false, DXGI_FORMAT_UNKNOWN); _SMAAEdgesRenderTarget = RenderTarget2D(_device.Get(), w, h, DXGI_FORMAT_R8G8_UNORM, false, DXGI_FORMAT_UNKNOWN);
_SMAABlendRenderTarget = RenderTarget2D(_device.Get(), w, h, DXGI_FORMAT_R8G8B8A8_UNORM, false, DXGI_FORMAT_UNKNOWN); _SMAABlendRenderTarget = RenderTarget2D(_device.Get(), w, h, DXGI_FORMAT_R8G8B8A8_UNORM, false, DXGI_FORMAT_UNKNOWN);
auto string = std::stringstream{};
auto defines = std::vector<D3D10_SHADER_MACRO>{};
// Set up pixel size macro.
string << "float4(1.0 / " << w << ", 1.0 / " << h << ", " << w << ", " << h << ")";
auto pixelSizeText = string.str();
auto renderTargetMetricsMacro = D3D10_SHADER_MACRO{ "SMAA_RT_METRICS", pixelSizeText.c_str() };
defines.push_back(renderTargetMetricsMacro);
if (g_Configuration.AntialiasingMode == AntialiasingMode::Medium)
{
defines.push_back({ "SMAA_PRESET_HIGH", nullptr });
}
else
{
defines.push_back({ "SMAA_PRESET_ULTRA", nullptr });
}
// defines.push_back({ "SMAA_PREDICATION", "1" });
// Set up target macro.
auto dx101Macro = D3D10_SHADER_MACRO{ "SMAA_HLSL_4_1", "1" };
defines.push_back(dx101Macro);
auto null = D3D10_SHADER_MACRO{ nullptr, nullptr };
defines.push_back(null);
_sSMAALumaEdgeDetection = CompileOrLoadShader("SMAA", "LumaEdgeDetection", ShaderType::Pixel, defines.data());
_sSMAAColorEdgeDetection = CompileOrLoadShader("SMAA", "ColorEdgeDetection", ShaderType::Pixel, defines.data());
_sSMAADepthEdgeDetection = CompileOrLoadShader("SMAA", "DepthEdgeDetection", ShaderType::Pixel, defines.data());
_sSMAABlendingWeightCalculation = CompileOrLoadShader("SMAA", "BlendingWeightCalculation", ShaderType::PixelAndVertex, defines.data());
_sSMAANeighborhoodBlending = CompileOrLoadShader("SMAA", "NeighborhoodBlending", ShaderType::PixelAndVertex, defines.data());
_sSMAAEdgeDetection = CompileOrLoadShader("SMAA", "EdgeDetection", ShaderType::Vertex, defines.data());
} }
void Renderer::InitializeCommonTextures() void Renderer::InitializeCommonTextures()
@ -641,6 +563,9 @@ namespace TEN::Renderer
} }
Utils::throwIfFailed(res); Utils::throwIfFailed(res);
// Initialize shader manager
_shaderManager.Initialize(_device, _context);
} }
void Renderer::ToggleFullScreen(bool force) void Renderer::ToggleFullScreen(bool force)
@ -676,152 +601,4 @@ namespace TEN::Renderer
UpdateWindow(WindowsHandle); UpdateWindow(WindowsHandle);
} }
void Renderer::BindShader(const RendererShader& shader)
{
if (shader.Vertex.Shader != nullptr) _context->VSSetShader(shader.Vertex.Shader.Get(), nullptr, 0);
if (shader.Pixel.Shader != nullptr) _context->PSSetShader(shader.Pixel.Shader.Get(), nullptr, 0);
if (shader.Compute.Shader != nullptr) _context->CSSetShader(shader.Compute.Shader.Get(), nullptr, 0);
}
RendererShader Renderer::CompileOrLoadShader(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines)
{
RendererShader result = {};
// We need to increment the counter to avoid overwriting compiled shaders with the same source file name.
static int compileCounter = 0;
// Define paths for native (uncompiled) shaders and compiled shaders.
std::wstring shaderPath = GetAssetPath(L"Shaders\\");
std::wstring compiledShaderPath = shaderPath + L"Bin\\";
std::wstring wideFileName = TEN::Utils::ToWString(fileName);
// Ensure the /Bin subdirectory exists.
std::filesystem::create_directories(compiledShaderPath);
// Helper function to load or compile a shader.
auto loadOrCompileShader = [this, type, defines, shaderPath, compiledShaderPath]
(const std::wstring& baseFileName, const std::string& shaderType, const std::string& functionName, const char* model, ComPtr<ID3D10Blob>& bytecode)
{
// Construct the full paths using GetAssetPath.
auto prefix = ((compileCounter < 10) ? L"0" : L"") + std::to_wstring(compileCounter) + L"_";
auto csoFileName = compiledShaderPath + prefix + baseFileName + L"." + std::wstring(shaderType.begin(), shaderType.end()) + L".cso";
auto srcFileName = shaderPath + baseFileName;
// Try both .hlsl and .fx extensions for the source shader.
auto srcFileNameWithExtension = srcFileName + L".hlsl";
if (!std::filesystem::exists(srcFileNameWithExtension))
{
srcFileNameWithExtension = srcFileName + L".fx";
if (!std::filesystem::exists(srcFileNameWithExtension))
{
TENLog("Shader source file not found: " + TEN::Utils::ToString(srcFileNameWithExtension), LogLevel::Error);
throw std::runtime_error("Shader source file not found");
}
}
// Check modification dates of the source and compiled files.
bool shouldRecompile = false;
if (std::filesystem::exists(csoFileName))
{
auto csoTime = std::filesystem::last_write_time(csoFileName);
auto srcTime = std::filesystem::last_write_time(srcFileNameWithExtension);
shouldRecompile = srcTime > csoTime; // Recompile if the source is newer.
}
// Load compiled shader if it exists and is up to date.
if (!shouldRecompile)
{
std::ifstream csoFile(csoFileName, std::ios::binary);
if (csoFile.is_open())
{
// Load compiled shader.
csoFile.seekg(0, std::ios::end);
size_t fileSize = csoFile.tellg();
csoFile.seekg(0, std::ios::beg);
std::vector<char> buffer(fileSize);
csoFile.read(buffer.data(), fileSize);
csoFile.close();
D3DCreateBlob(fileSize, &bytecode);
memcpy(bytecode->GetBufferPointer(), buffer.data(), fileSize);
return;
}
}
// Set up compilation flags according to the build configuration.
unsigned int flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
if constexpr (DebugBuild)
flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
else
flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_IEEE_STRICTNESS;
auto trimmedFileName = std::filesystem::path(srcFileNameWithExtension).filename().string();
TENLog("Compiling shader: " + trimmedFileName, LogLevel::Info);
// Compile shader.
ComPtr<ID3D10Blob> errors;
HRESULT res = D3DCompileFromFile(srcFileNameWithExtension.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE,
(shaderType + functionName).c_str(), model, flags, 0, bytecode.GetAddressOf(), errors.GetAddressOf());
if (FAILED(res))
{
if (errors)
{
auto error = std::string(static_cast<const char*>(errors->GetBufferPointer()));
TENLog(error, LogLevel::Error);
throw std::runtime_error(error);
}
else
{
TENLog("Error while compiling shader: " + trimmedFileName, LogLevel::Error);
throwIfFailed(res);
}
}
// Save compiled shader to .cso file.
std::ofstream outCsoFile(csoFileName, std::ios::binary);
if (outCsoFile.is_open())
{
outCsoFile.write(reinterpret_cast<const char*>(bytecode->GetBufferPointer()), bytecode->GetBufferSize());
outCsoFile.close();
}
};
// Load or compile and create pixel shader.
if (type == ShaderType::Pixel || type == ShaderType::PixelAndVertex)
{
loadOrCompileShader(wideFileName, "PS", funcName, "ps_5_0", result.Pixel.Blob);
throwIfFailed(_device->CreatePixelShader(result.Pixel.Blob->GetBufferPointer(), result.Pixel.Blob->GetBufferSize(),
nullptr, result.Pixel.Shader.GetAddressOf()
));
}
// Load or compile and create vertex shader.
if (type == ShaderType::Vertex || type == ShaderType::PixelAndVertex)
{
loadOrCompileShader(wideFileName, "VS", funcName, "vs_5_0", result.Vertex.Blob);
throwIfFailed(_device->CreateVertexShader(result.Vertex.Blob->GetBufferPointer(), result.Vertex.Blob->GetBufferSize(),
nullptr, result.Vertex.Shader.GetAddressOf()
));
}
// Load or compile and create compute shader.
if (type == ShaderType::Compute)
{
loadOrCompileShader(wideFileName, "CS", funcName, "cs_5_0", result.Compute.Blob);
throwIfFailed(_device->CreateComputeShader(result.Compute.Blob->GetBufferPointer(), result.Compute.Blob->GetBufferSize(),
nullptr, result.Compute.Shader.GetAddressOf()
));
}
// Increment the compile counter.
compileCounter++;
return result;
}
} }

View file

@ -42,7 +42,7 @@ namespace TEN::Renderer
_cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get()); _cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
// Common vertex shader to all fullscreen effects. // Common vertex shader to all fullscreen effects.
BindShader(_sPostProcess); _shaderManager.Bind(Shader::PostProcess);
// Draw fullscreen triangle. // Draw fullscreen triangle.
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@ -71,7 +71,7 @@ namespace TEN::Renderer
_context->ClearRenderTargetView(_postProcessRenderTarget[destRenderTarget].RenderTargetView.Get(), clearColor); _context->ClearRenderTargetView(_postProcessRenderTarget[destRenderTarget].RenderTargetView.Get(), clearColor);
_context->OMSetRenderTargets(1, _postProcessRenderTarget[destRenderTarget].RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, _postProcessRenderTarget[destRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
BindShader(_sPostProcessLensFlare); _shaderManager.Bind(Shader::PostProcessLensFlare);
for (int i = 0; i < view.LensFlaresToDraw.size(); i++) for (int i = 0; i < view.LensFlaresToDraw.size(); i++)
{ {
@ -97,15 +97,15 @@ namespace TEN::Renderer
switch (_postProcessMode) switch (_postProcessMode)
{ {
case PostProcessMode::Monochrome: case PostProcessMode::Monochrome:
BindShader(_sPostProcessMonochrome); _shaderManager.Bind(Shader::PostProcessMonochrome);
break; break;
case PostProcessMode::Negative: case PostProcessMode::Negative:
BindShader(_sPostProcessNegative); _shaderManager.Bind(Shader::PostProcessNegative);
break; break;
case PostProcessMode::Exclusion: case PostProcessMode::Exclusion:
BindShader(_sPostProcessExclusion); _shaderManager.Bind(Shader::PostProcessExclusion);
break; break;
default: default:
@ -120,7 +120,7 @@ namespace TEN::Renderer
} }
// Do final pass. // Do final pass.
BindShader(_sPostProcessFinalPass); _shaderManager.Bind(Shader::PostProcessFinalPass);
_context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black); _context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black);
_context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr); _context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr);
@ -172,7 +172,7 @@ namespace TEN::Renderer
ResetScissor(); ResetScissor();
// Common vertex shader to all fullscreen effects // Common vertex shader to all fullscreen effects
BindShader(_sPostProcess); _shaderManager.Bind(Shader::PostProcess);
// We draw a fullscreen triangle // We draw a fullscreen triangle
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

View file

@ -279,7 +279,7 @@ namespace TEN::Renderer
SetDepthState(DepthState::Read); SetDepthState(DepthState::Read);
SetCullMode(CullMode::None); SetCullMode(CullMode::None);
BindShader(_sInstancedSprites); _shaderManager.Bind(Shader::InstancedSprites);
// Set up vertex buffer and parameters. // Set up vertex buffer and parameters.
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
@ -340,7 +340,7 @@ namespace TEN::Renderer
SetDepthState(DepthState::Read); SetDepthState(DepthState::Read);
SetCullMode(CullMode::None); SetCullMode(CullMode::None);
BindShader(_sSprites); _shaderManager.Bind(Shader::Sprites);
wasGPUSet = true; wasGPUSet = true;
} }
@ -411,7 +411,7 @@ namespace TEN::Renderer
SetBlendMode(object->Sprite->BlendMode); SetBlendMode(object->Sprite->BlendMode);
SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD); SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
BindShader(_sInstancedSprites); _shaderManager.Bind(Shader::InstancedSprites);
// Set up vertex buffer and parameters. // Set up vertex buffer and parameters.
UINT stride = sizeof(Vertex); UINT stride = sizeof(Vertex);
@ -456,7 +456,7 @@ namespace TEN::Renderer
SetBlendMode(object->Sprite->BlendMode); SetBlendMode(object->Sprite->BlendMode);
SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD); SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
BindShader(_sSprites); _shaderManager.Bind(Shader::Sprites);
_stSprite.IsSoftParticle = object->Sprite->SoftParticle ? 1 : 0; _stSprite.IsSoftParticle = object->Sprite->SoftParticle ? 1 : 0;
_stSprite.RenderType = (int)object->Sprite->renderType; _stSprite.RenderType = (int)object->Sprite->renderType;
@ -501,7 +501,7 @@ namespace TEN::Renderer
UINT stride = sizeof(Vertex); UINT stride = sizeof(Vertex);
UINT offset = 0; UINT offset = 0;
BindShader(_sSprites); _shaderManager.Bind(Shader::Sprites);
_sortedPolygonsVertexBuffer.Update(_context.Get(), _sortedPolygonsVertices.data(), 0, (int)_sortedPolygonsVertices.size()); _sortedPolygonsVertexBuffer.Update(_context.Get(), _sortedPolygonsVertices.data(), 0, (int)_sortedPolygonsVertices.size());

View file

@ -8,8 +8,9 @@
#include <wrl/client.h> #include <wrl/client.h>
#include "Renderer/Renderer.h" #include "Renderer/Renderer.h"
#include "Renderer/Structures/RendererShader.h"
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Specific/trutils.h" #include "Specific/trutils.h"
#include "Structures/RendererShader.h"
namespace TEN::Renderer::Utils namespace TEN::Renderer::Utils
{ {
@ -42,4 +43,9 @@ namespace TEN::Renderer::Utils
throw std::runtime_error("An error occured!"); throw std::runtime_error("An error occured!");
} }
} }
std::wstring GetAssetPath(const wchar_t* fileName)
{
return TEN::Utils::ToWString(g_GameFlow->GetGameDir()) + fileName;
}
} }

View file

@ -9,4 +9,6 @@ namespace TEN::Renderer::Utils
void throwIfFailed(const HRESULT& res); void throwIfFailed(const HRESULT& res);
void throwIfFailed(const HRESULT& res, const std::string& info); void throwIfFailed(const HRESULT& res, const std::string& info);
void throwIfFailed(const HRESULT& res, const std::wstring& info); void throwIfFailed(const HRESULT& res, const std::wstring& info);
std::wstring GetAssetPath(const wchar_t* fileName);
} }

View file

@ -0,0 +1,306 @@
#include "framework.h"
#include "Renderer/ShaderManager/ShaderManager.h"
#include <d3dcompiler.h>
#include <filesystem>
#include <fstream>
#include "Renderer/RendererUtils.h"
#include "Specific/configuration.h"
#include "Specific/trutils.h"
namespace TEN::Renderer::Utils
{
void ShaderManager::LoadAllShaders(int width, int height)
{
TENLog("Loading shaders...", LogLevel::Info);
// Unbind any currently bound shader.
Bind(Shader::None);
// Reset compile counter.
_compileCounter = 0;
// Generic shaders.
const D3D_SHADER_MACRO roomDefinesAnimated[] = { "ANIMATED", "", nullptr, nullptr };
const D3D_SHADER_MACRO roomDefinesShadowMap[] = { "SHADOW_MAP", "", nullptr, nullptr };
Load(Shader::Rooms, "Rooms", "", ShaderType::PixelAndVertex);
Load(Shader::RoomsAnimated, "Rooms", "", ShaderType::Vertex, &roomDefinesAnimated[0]);
Load(Shader::Items, "Items", "", ShaderType::PixelAndVertex);
Load(Shader::Statics, "Statics", "", ShaderType::PixelAndVertex);
Load(Shader::Sky, "Sky", "", ShaderType::PixelAndVertex);
Load(Shader::Sprites, "Sprites", "", ShaderType::PixelAndVertex);
Load(Shader::Solid, "Solid", "", ShaderType::PixelAndVertex);
Load(Shader::Inventory, "Inventory", "", ShaderType::PixelAndVertex);
Load(Shader::FullScreenQuad, "FullScreenQuad", "", ShaderType::PixelAndVertex);
Load(Shader::ShadowMap, "ShadowMap", "", ShaderType::PixelAndVertex, roomDefinesShadowMap);
Load(Shader::HUD, "HUD", "", ShaderType::Vertex);
Load(Shader::HUDColor, "HUD", "ColoredHUD", ShaderType::Pixel);
Load(Shader::HUDTexture, "HUD", "TexturedHUD", ShaderType::Pixel);
Load(Shader::HUDBarColor, "HUD", "TexturedHUDBar", ShaderType::Pixel);
Load(Shader::InstancedStatics, "InstancedStatics", "", ShaderType::PixelAndVertex);
Load(Shader::InstancedSprites, "InstancedSprites", "", ShaderType::PixelAndVertex);
Load(Shader::GBuffer, "GBuffer", "", ShaderType::Pixel);
Load(Shader::GBufferRooms, "GBuffer", "Rooms", ShaderType::Vertex);
Load(Shader::GBufferRoomsAnimated, "GBuffer", "Rooms", ShaderType::Vertex, roomDefinesAnimated);
Load(Shader::GBufferItems, "GBuffer", "Items", ShaderType::Vertex);
Load(Shader::GBufferStatics, "GBuffer", "Statics", ShaderType::Vertex);
Load(Shader::GBufferInstancedStatics, "GBuffer", "InstancedStatics", ShaderType::Vertex);
Load(Shader::RoomAmbient, "RoomAmbient", "", ShaderType::PixelAndVertex);
Load(Shader::RoomAmbientSky, "RoomAmbient", "Sky", ShaderType::Vertex);
Load(Shader::FXAA, "FXAA", "", ShaderType::Pixel);
Load(Shader::SSAO, "SSAO", "", ShaderType::Pixel);
Load(Shader::SSAOBlur, "SSAO", "Blur", ShaderType::Pixel);
const D3D_SHADER_MACRO transparentDefines[] = { "TRANSPARENT", "", nullptr, nullptr };
Load(Shader::RoomsTransparent, "Rooms", "", ShaderType::Pixel, transparentDefines);
// Post-process shaders.
Load(Shader::PostProcess, "PostProcess", "", ShaderType::PixelAndVertex);
Load(Shader::PostProcessMonochrome, "PostProcess", "Monochrome", ShaderType::Pixel);
Load(Shader::PostProcessNegative, "PostProcess", "Negative", ShaderType::Pixel);
Load(Shader::PostProcessExclusion, "PostProcess", "Exclusion", ShaderType::Pixel);
Load(Shader::PostProcessFinalPass, "PostProcess", "FinalPass", ShaderType::Pixel);
Load(Shader::PostProcessLensFlare, "PostProcess", "LensFlare", ShaderType::Pixel);
// SMAA shaders.
auto string = std::stringstream{};
auto defines = std::vector<D3D10_SHADER_MACRO>{};
// Set up pixel size macro.
string << "float4(1.0 / " << width << ", 1.0 / " << height << ", " << width << ", " << height << ")";
auto pixelSizeText = string.str();
auto renderTargetMetricsMacro = D3D10_SHADER_MACRO{ "SMAA_RT_METRICS", pixelSizeText.c_str() };
defines.push_back(renderTargetMetricsMacro);
if (g_Configuration.AntialiasingMode == AntialiasingMode::Medium)
{
defines.push_back({ "SMAA_PRESET_HIGH", nullptr });
}
else
{
defines.push_back({ "SMAA_PRESET_ULTRA", nullptr });
}
// defines.push_back({ "SMAA_PREDICATION", "1" });
// Set up target macro.
auto dx101Macro = D3D10_SHADER_MACRO{ "SMAA_HLSL_4_1", "1" };
defines.push_back(dx101Macro);
auto null = D3D10_SHADER_MACRO{ nullptr, nullptr };
defines.push_back(null);
Load(Shader::SMAAEdgeDetection, "SMAA", "EdgeDetection", ShaderType::Vertex, defines.data());
Load(Shader::SMAALumaEdgeDetection, "SMAA", "LumaEdgeDetection", ShaderType::Pixel, defines.data());
Load(Shader::SMAAColorEdgeDetection, "SMAA", "ColorEdgeDetection", ShaderType::Pixel, defines.data());
Load(Shader::SMAADepthEdgeDetection, "SMAA", "DepthEdgeDetection", ShaderType::Pixel, defines.data());
Load(Shader::SMAABlendingWeightCalculation, "SMAA", "BlendingWeightCalculation", ShaderType::PixelAndVertex, defines.data());
Load(Shader::SMAANeighborhoodBlending, "SMAA", "NeighborhoodBlending", ShaderType::PixelAndVertex, defines.data());
}
void ShaderManager::Initialize(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContext>& context)
{
_device = device;
_context = context;
}
ShaderManager::~ShaderManager()
{
_device = nullptr;
_context = nullptr;
for (int i = 0; i < (int)Shader::Count; i++)
Destroy((Shader)i);
}
void ShaderManager::Destroy(Shader shader)
{
auto& shaderData = _shaders[(int)shader];
if (shaderData.Vertex.Shader != nullptr)
{
shaderData.Vertex.Shader.Reset();
shaderData.Vertex.Blob.Reset();
}
if (shaderData.Pixel.Shader != nullptr)
{
shaderData.Pixel.Shader.Reset();
shaderData.Pixel.Blob.Reset();
}
if (shaderData.Compute.Shader != nullptr)
{
shaderData.Compute.Shader.Reset();
shaderData.Compute.Blob.Reset();
}
}
RendererShader ShaderManager::LoadOrCompile(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines)
{
RendererShader result = {};
// Define paths for native (uncompiled) shaders and compiled shaders.
std::wstring shaderPath = GetAssetPath(L"Shaders\\");
std::wstring compiledShaderPath = shaderPath + L"Bin\\";
std::wstring wideFileName = TEN::Utils::ToWString(fileName);
// Ensure the /Bin subdirectory exists.
std::filesystem::create_directories(compiledShaderPath);
// Helper function to load or compile a shader.
auto loadOrCompileShader = [this, type, defines, shaderPath, compiledShaderPath]
(const std::wstring& baseFileName, const std::string& shaderType, const std::string& functionName, const char* model, ComPtr<ID3D10Blob>& bytecode)
{
// Construct the full paths using GetAssetPath.
auto prefix = ((_compileCounter < 10) ? L"0" : L"") + std::to_wstring(_compileCounter) + L"_";
auto csoFileName = compiledShaderPath + prefix + baseFileName + L"." + std::wstring(shaderType.begin(), shaderType.end()) + L".cso";
auto srcFileName = shaderPath + baseFileName;
// Try both .hlsl and .fx extensions for the source shader.
auto srcFileNameWithExtension = srcFileName + L".hlsl";
if (!std::filesystem::exists(srcFileNameWithExtension))
{
srcFileNameWithExtension = srcFileName + L".fx";
if (!std::filesystem::exists(srcFileNameWithExtension))
{
TENLog("Shader source file not found: " + TEN::Utils::ToString(srcFileNameWithExtension), LogLevel::Error);
throw std::runtime_error("Shader source file not found");
}
}
// Check modification dates of the source and compiled files.
bool shouldRecompile = true;
if (std::filesystem::exists(csoFileName))
{
auto csoTime = std::filesystem::last_write_time(csoFileName);
auto srcTime = std::filesystem::last_write_time(srcFileNameWithExtension);
shouldRecompile = srcTime > csoTime; // Recompile if the source is newer.
}
// Load compiled shader if it exists and is up to date.
if (!shouldRecompile)
{
std::ifstream csoFile(csoFileName, std::ios::binary);
if (csoFile.is_open())
{
// Load compiled shader.
csoFile.seekg(0, std::ios::end);
size_t fileSize = csoFile.tellg();
csoFile.seekg(0, std::ios::beg);
std::vector<char> buffer(fileSize);
csoFile.read(buffer.data(), fileSize);
csoFile.close();
D3DCreateBlob(fileSize, &bytecode);
memcpy(bytecode->GetBufferPointer(), buffer.data(), fileSize);
return;
}
}
// Set up compilation flags according to the build configuration.
unsigned int flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
if constexpr (DebugBuild)
flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
else
flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_IEEE_STRICTNESS;
auto trimmedFileName = std::filesystem::path(srcFileNameWithExtension).filename().string();
TENLog("Compiling shader: " + trimmedFileName, LogLevel::Info);
// Compile shader.
ComPtr<ID3D10Blob> errors;
HRESULT res = D3DCompileFromFile(srcFileNameWithExtension.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE,
(shaderType + functionName).c_str(), model, flags, 0, bytecode.GetAddressOf(), errors.GetAddressOf());
if (FAILED(res))
{
if (errors)
{
auto error = std::string(static_cast<const char*>(errors->GetBufferPointer()));
TENLog(error, LogLevel::Error);
throw std::runtime_error(error);
}
else
{
TENLog("Error while compiling shader: " + trimmedFileName, LogLevel::Error);
throwIfFailed(res);
}
}
// Save compiled shader to .cso file.
std::ofstream outCsoFile(csoFileName, std::ios::binary);
if (outCsoFile.is_open())
{
outCsoFile.write(reinterpret_cast<const char*>(bytecode->GetBufferPointer()), bytecode->GetBufferSize());
outCsoFile.close();
}
};
// Load or compile and create pixel shader.
if (type == ShaderType::Pixel || type == ShaderType::PixelAndVertex)
{
loadOrCompileShader(wideFileName, "PS", funcName, "ps_5_0", result.Pixel.Blob);
throwIfFailed(_device->CreatePixelShader(result.Pixel.Blob->GetBufferPointer(), result.Pixel.Blob->GetBufferSize(),
nullptr, result.Pixel.Shader.GetAddressOf()
));
}
// Load or compile and create vertex shader.
if (type == ShaderType::Vertex || type == ShaderType::PixelAndVertex)
{
loadOrCompileShader(wideFileName, "VS", funcName, "vs_5_0", result.Vertex.Blob);
throwIfFailed(_device->CreateVertexShader(result.Vertex.Blob->GetBufferPointer(), result.Vertex.Blob->GetBufferSize(),
nullptr, result.Vertex.Shader.GetAddressOf()
));
}
// Load or compile and create compute shader.
if (type == ShaderType::Compute)
{
loadOrCompileShader(wideFileName, "CS", funcName, "cs_5_0", result.Compute.Blob);
throwIfFailed(_device->CreateComputeShader(result.Compute.Blob->GetBufferPointer(), result.Compute.Blob->GetBufferSize(),
nullptr, result.Compute.Shader.GetAddressOf()
));
}
// Increment the compile counter.
_compileCounter++;
return result;
}
void ShaderManager::Load(Shader shader, const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines)
{
Destroy(shader);
_shaders[(int)shader] = LoadOrCompile(fileName, funcName, type, defines);
}
void ShaderManager::Bind(Shader shader)
{
auto& shaderObj = _shaders[(int)shader];
if (shaderObj.Vertex.Shader != nullptr) _context->VSSetShader(shaderObj.Vertex.Shader.Get(), nullptr, 0);
if (shaderObj.Pixel.Shader != nullptr) _context->PSSetShader(shaderObj.Pixel.Shader.Get(), nullptr, 0);
if (shaderObj.Compute.Shader != nullptr) _context->CSSetShader(shaderObj.Compute.Shader.Get(), nullptr, 0);
}
const RendererShader& ShaderManager::Get(Shader shader)
{
return _shaders[(int)shader];
}
}

View file

@ -0,0 +1,84 @@
#pragma once
#include "framework.h"
#include "Renderer/Structures/RendererShader.h"
namespace TEN::Renderer::Utils
{
using namespace TEN::Renderer::Structures;
enum class Shader
{
None,
Rooms,
RoomsAnimated,
RoomsTransparent,
RoomAmbient,
RoomAmbientSky,
Items,
Statics,
InstancedStatics,
Sprites,
InstancedSprites,
Sky,
Solid,
Inventory,
FullScreenQuad,
ShadowMap,
HUD,
HUDColor,
HUDTexture,
HUDBarColor,
GBuffer,
GBufferRooms,
GBufferRoomsAnimated,
GBufferItems,
GBufferStatics,
GBufferInstancedStatics,
SMAAEdgeDetection,
SMAALumaEdgeDetection,
SMAAColorEdgeDetection,
SMAADepthEdgeDetection,
SMAABlendingWeightCalculation,
SMAANeighborhoodBlending,
FXAA,
PostProcess,
PostProcessMonochrome,
PostProcessNegative,
PostProcessExclusion,
PostProcessFinalPass,
PostProcessLensFlare,
SSAO,
SSAOBlur,
Count
};
class ShaderManager
{
private:
ComPtr<ID3D11Device> _device = nullptr;
ComPtr<ID3D11DeviceContext> _context = nullptr;
int _compileCounter = 0;
std::array<RendererShader, (int)Shader::Count> _shaders = {};
RendererShader LoadOrCompile(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines);
void Load(Shader shader, const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines = nullptr);
void Destroy(Shader shader);
public:
ShaderManager() = default;
~ShaderManager();
void Initialize(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContext>& context);
void LoadAllShaders(int width, int height);
void Bind(Shader shader);
const RendererShader& Get(Shader shader);
};
}

View file

@ -4,7 +4,6 @@
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#include <stdlib.h>
#include <d3d11.h> #include <d3d11.h>
#include <SimpleMath.h> #include <SimpleMath.h>

View file

@ -651,6 +651,11 @@ namespace TEN::Input
if ((KeyMap[KC_F10] || KeyMap[KC_F11]) && dbDebugPage) if ((KeyMap[KC_F10] || KeyMap[KC_F11]) && dbDebugPage)
g_Renderer.SwitchDebugPage(KeyMap[KC_F10]); g_Renderer.SwitchDebugPage(KeyMap[KC_F10]);
dbDebugPage = !(KeyMap[KC_F10] || KeyMap[KC_F11]); dbDebugPage = !(KeyMap[KC_F10] || KeyMap[KC_F11]);
// Reload shaders.
static bool dbReloadShaders = true;
if (KeyMap[KC_F9] && dbReloadShaders)
g_Renderer.ReloadShaders();
} }
static void UpdateRumble() static void UpdateRumble()

View file

@ -822,6 +822,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<ClInclude Include="Renderer\Graphics\Vertices\Vertex.h" /> <ClInclude Include="Renderer\Graphics\Vertices\Vertex.h" />
<ClInclude Include="Renderer\Renderer.h" /> <ClInclude Include="Renderer\Renderer.h" />
<ClInclude Include="Renderer\RendererEnums.h" /> <ClInclude Include="Renderer\RendererEnums.h" />
<ClInclude Include="Renderer\ShaderManager\ShaderManager.h" />
<ClInclude Include="Renderer\Structures\RendererMirror.h" /> <ClInclude Include="Renderer\Structures\RendererMirror.h" />
<ClInclude Include="Renderer\RendererSprite2D.h" /> <ClInclude Include="Renderer\RendererSprite2D.h" />
<ClInclude Include="Renderer\RendererBucket.h" /> <ClInclude Include="Renderer\RendererBucket.h" />
@ -1316,6 +1317,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<ClCompile Include="Renderer\RendererString.cpp" /> <ClCompile Include="Renderer\RendererString.cpp" />
<ClCompile Include="Renderer\RendererUtils.cpp" /> <ClCompile Include="Renderer\RendererUtils.cpp" />
<ClCompile Include="Renderer\RenderView.cpp" /> <ClCompile Include="Renderer\RenderView.cpp" />
<ClCompile Include="Renderer\ShaderManager\ShaderManager.cpp" />
<ClCompile Include="Scripting\Internal\LuaHandler.cpp" /> <ClCompile Include="Scripting\Internal\LuaHandler.cpp" />
<ClCompile Include="Scripting\Internal\ScriptAssert.cpp" /> <ClCompile Include="Scripting\Internal\ScriptAssert.cpp" />
<ClCompile Include="Scripting\Internal\ScriptInterfaceState.cpp" /> <ClCompile Include="Scripting\Internal\ScriptInterfaceState.cpp" />