mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Work
This commit is contained in:
parent
12dae8df99
commit
ca25f87738
17 changed files with 524 additions and 375 deletions
|
@ -61,6 +61,18 @@ namespace TEN::Renderer
|
|||
_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()
|
||||
{
|
||||
// Sync the renderer
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "Renderer/Graphics/Texture2DArray.h"
|
||||
#include "Renderer/Graphics/VertexBuffer.h"
|
||||
#include "Renderer/Graphics/Vertices/PostProcessVertex.h"
|
||||
#include "Renderer/ShaderManager/ShaderManager.h"
|
||||
#include "Renderer/Structures/RendererItem.h"
|
||||
#include "Renderer/Structures/RendererEffect.h"
|
||||
#include "Renderer/Structures/RendererLine3D.h"
|
||||
|
@ -65,7 +66,6 @@
|
|||
#include "Renderer/Structures/RendererRoomAmbientMap.h"
|
||||
#include "Renderer/Structures/RendererObject.h"
|
||||
#include "Renderer/Structures/RendererStar.h"
|
||||
#include "Structures/RendererShader.h"
|
||||
|
||||
enum GAME_OBJECT_ID : short;
|
||||
enum class SphereSpaceType;
|
||||
|
@ -81,6 +81,7 @@ namespace TEN::Renderer
|
|||
using namespace TEN::Renderer::ConstantBuffers;
|
||||
using namespace TEN::Renderer::Graphics;
|
||||
using namespace TEN::Renderer::Structures;
|
||||
using namespace TEN::Renderer::Utils;
|
||||
using namespace DirectX::SimpleMath;
|
||||
|
||||
using TexturePair = std::tuple<Texture2D, Texture2D>;
|
||||
|
@ -123,34 +124,6 @@ namespace TEN::Renderer
|
|||
RenderTarget2D _tempRoomAmbientRenderTarget4;
|
||||
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
|
||||
|
||||
RenderView _gameCamera;
|
||||
|
@ -341,14 +314,6 @@ namespace TEN::Renderer
|
|||
RenderTarget2D _SMAAEdgesRenderTarget;
|
||||
RenderTarget2D _SMAABlendRenderTarget;
|
||||
|
||||
RendererShader _sSMAAEdgeDetection;
|
||||
RendererShader _sSMAALumaEdgeDetection;
|
||||
RendererShader _sSMAAColorEdgeDetection;
|
||||
RendererShader _sSMAADepthEdgeDetection;
|
||||
RendererShader _sSMAABlendingWeightCalculation;
|
||||
RendererShader _sSMAANeighborhoodBlending;
|
||||
RendererShader _sFXAA;
|
||||
|
||||
// Post-process
|
||||
|
||||
PostProcessMode _postProcessMode = PostProcessMode::None;
|
||||
|
@ -357,12 +322,6 @@ namespace TEN::Renderer
|
|||
|
||||
VertexBuffer<PostProcessVertex> _fullscreenTriangleVertexBuffer;
|
||||
ComPtr<ID3D11InputLayout> _fullscreenTriangleInputLayout = nullptr;
|
||||
RendererShader _sPostProcess;
|
||||
RendererShader _sPostProcessMonochrome;
|
||||
RendererShader _sPostProcessNegative;
|
||||
RendererShader _sPostProcessExclusion;
|
||||
RendererShader _sPostProcessFinalPass;
|
||||
RendererShader _sPostProcessLensFlare;
|
||||
|
||||
bool _doingFullscreenPass = false;
|
||||
|
||||
|
@ -373,9 +332,6 @@ namespace TEN::Renderer
|
|||
RenderTarget2D _SSAOBlurredRenderTarget;
|
||||
std::vector<Vector4> _SSAOKernel;
|
||||
|
||||
RendererShader _sSSAO;
|
||||
RendererShader _sSSAOBlur;
|
||||
|
||||
// New ambient light techinque
|
||||
|
||||
RenderTarget2D _roomAmbientMapFront;
|
||||
|
@ -398,10 +354,9 @@ namespace TEN::Renderer
|
|||
float _interpolationFactor = 0.0f;
|
||||
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);
|
||||
void BindShader(const RendererShader& shader);
|
||||
ShaderManager _shaderManager;
|
||||
|
||||
void ApplySMAA(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 Create();
|
||||
void Initialize(int w, int h, bool windowed, HWND handle);
|
||||
void ReloadShaders();
|
||||
void Render(float interpFactor);
|
||||
void RenderTitle(float interpFactor);
|
||||
void Lock();
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace TEN::Renderer
|
|||
ResetScissor();
|
||||
|
||||
// Common vertex shader to all fullscreen effects
|
||||
BindShader(_sPostProcess);
|
||||
_shaderManager.Bind(Shader::PostProcess);
|
||||
|
||||
// We draw a fullscreen triangle
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -40,8 +40,8 @@ namespace TEN::Renderer
|
|||
SetCullMode(CullMode::CounterClockwise);
|
||||
_context->OMSetRenderTargets(1, _SMAAEdgesRenderTarget.RenderTargetView.GetAddressOf(), nullptr);
|
||||
|
||||
BindShader(_sSMAAEdgeDetection);
|
||||
BindShader(_sSMAAColorEdgeDetection);
|
||||
_shaderManager.Bind(Shader::SMAAEdgeDetection);
|
||||
_shaderManager.Bind(Shader::SMAAColorEdgeDetection);
|
||||
|
||||
_stSMAABuffer.BlendFactor = 1.0f;
|
||||
_cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get());
|
||||
|
@ -59,7 +59,7 @@ namespace TEN::Renderer
|
|||
// 2) Blend weights calculation.
|
||||
_context->OMSetRenderTargets(1, _SMAABlendRenderTarget.RenderTargetView.GetAddressOf(), nullptr);
|
||||
|
||||
BindShader(_sSMAABlendingWeightCalculation);
|
||||
_shaderManager.Bind(Shader::SMAABlendingWeightCalculation);
|
||||
|
||||
_stSMAABuffer.SubsampleIndices = Vector4::Zero;
|
||||
_cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get());
|
||||
|
@ -76,7 +76,7 @@ namespace TEN::Renderer
|
|||
// 3) Neighborhood blending.
|
||||
_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>(1), &_SMAASceneSRGBRenderTarget, SamplerStateRegister::LinearClamp);
|
||||
|
@ -100,7 +100,7 @@ namespace TEN::Renderer
|
|||
ResetScissor();
|
||||
|
||||
// Common vertex shader to all fullscreen effects
|
||||
BindShader(_sPostProcess);
|
||||
_shaderManager.Bind(Shader::PostProcess);
|
||||
|
||||
// We draw a fullscreen triangle
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -123,7 +123,7 @@ namespace TEN::Renderer
|
|||
_context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black);
|
||||
_context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr);
|
||||
|
||||
BindShader(_sFXAA);
|
||||
_shaderManager.Bind(Shader::FXAA);
|
||||
|
||||
_stPostProcessBuffer.ViewportWidth = _screenWidth;
|
||||
_stPostProcessBuffer.ViewportHeight = _screenHeight;
|
||||
|
|
|
@ -167,7 +167,7 @@ namespace TEN::Renderer
|
|||
UINT offset = 0;
|
||||
|
||||
// Set shaders
|
||||
BindShader(_sShadowMap);
|
||||
_shaderManager.Bind(Shader::ShadowMap);
|
||||
|
||||
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -284,7 +284,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
auto& moveableObject = *_moveableObjects[objectID];
|
||||
|
||||
BindShader(_sInstancedStatics);
|
||||
_shaderManager.Bind(Shader::InstancedStatics);
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
unsigned int offset = 0;
|
||||
|
@ -361,7 +361,7 @@ namespace TEN::Renderer
|
|||
SetDepthState(DepthState::Read);
|
||||
SetCullMode(CullMode::None);
|
||||
|
||||
BindShader(_sSolid);
|
||||
_shaderManager.Bind(Shader::Solid);
|
||||
auto worldMatrix = Matrix::CreateOrthographicOffCenter(0, _screenWidth, _screenHeight, 0, _viewport.MinDepth, _viewport.MaxDepth);
|
||||
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||
|
@ -531,12 +531,12 @@ namespace TEN::Renderer
|
|||
{
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferStatics);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferStatics);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
}
|
||||
|
||||
UINT stride = sizeof(Vertex);
|
||||
|
@ -656,12 +656,12 @@ namespace TEN::Renderer
|
|||
{
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferStatics);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferStatics);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
}
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
|
@ -792,12 +792,12 @@ namespace TEN::Renderer
|
|||
{
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferInstancedStatics);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferInstancedStatics);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sInstancedStatics);
|
||||
_shaderManager.Bind(Shader::InstancedStatics);
|
||||
}
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
|
@ -919,12 +919,12 @@ namespace TEN::Renderer
|
|||
{
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferInstancedStatics);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferInstancedStatics);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sInstancedStatics);
|
||||
_shaderManager.Bind(Shader::InstancedStatics);
|
||||
}
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
|
@ -1026,12 +1026,12 @@ namespace TEN::Renderer
|
|||
{
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferStatics);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferStatics);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
}
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
|
@ -1089,7 +1089,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(BlendMode::Additive);
|
||||
SetCullMode(CullMode::None);
|
||||
|
||||
BindShader(_sSolid);
|
||||
_shaderManager.Bind(Shader::Solid);
|
||||
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||
|
||||
|
@ -1122,7 +1122,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(BlendMode::Additive);
|
||||
SetCullMode(CullMode::None);
|
||||
|
||||
BindShader(_sSolid);
|
||||
_shaderManager.Bind(Shader::Solid);
|
||||
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetInputLayout(_inputLayout.Get());
|
||||
|
@ -1926,7 +1926,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(BlendMode::Opaque);
|
||||
SetCullMode(CullMode::CounterClockwise);
|
||||
|
||||
BindShader(_sRoomAmbient);
|
||||
_shaderManager.Bind(Shader::RoomAmbient);
|
||||
|
||||
// Bind and clear render target
|
||||
_context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black);
|
||||
|
@ -1976,7 +1976,7 @@ namespace TEN::Renderer
|
|||
|
||||
if (levelPtr->Horizon)
|
||||
{
|
||||
BindShader(_sRoomAmbientSky);
|
||||
_shaderManager.Bind(Shader::RoomAmbientSky);
|
||||
|
||||
if (Lara.Control.Look.OpticRange != 0)
|
||||
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);
|
||||
}
|
||||
|
||||
BindShader(_sRoomAmbient);
|
||||
_shaderManager.Bind(Shader::RoomAmbient);
|
||||
|
||||
// Draw rooms
|
||||
UINT stride = sizeof(Vertex);
|
||||
|
@ -2264,12 +2264,12 @@ namespace TEN::Renderer
|
|||
// Set shaders.
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferItems);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferItems);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sItems);
|
||||
_shaderManager.Bind(Shader::Items);
|
||||
}
|
||||
|
||||
BindRenderTargetAsTexture(TextureRegister::SSAO, &_SSAOBlurredRenderTarget, SamplerStateRegister::PointWrap);
|
||||
|
@ -2406,12 +2406,12 @@ namespace TEN::Renderer
|
|||
#ifdef DISABLE_INSTANCING
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferStatics);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferStatics);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
}
|
||||
|
||||
// Bind vertex and index buffer
|
||||
|
@ -2487,12 +2487,12 @@ namespace TEN::Renderer
|
|||
#else
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
BindShader(_sGBufferInstancedStatics);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
_shaderManager.Bind(Shader::GBufferInstancedStatics);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sInstancedStatics);
|
||||
_shaderManager.Bind(Shader::InstancedStatics);
|
||||
}
|
||||
|
||||
// Bind vertex and index buffer
|
||||
|
@ -2682,11 +2682,11 @@ namespace TEN::Renderer
|
|||
{
|
||||
if (rendererPass == RendererPass::GBuffer)
|
||||
{
|
||||
BindShader(_sGBuffer);
|
||||
_shaderManager.Bind(Shader::GBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
BindShader(_sRooms);
|
||||
_shaderManager.Bind(Shader::Rooms);
|
||||
}
|
||||
|
||||
UINT stride = sizeof(Vertex);
|
||||
|
@ -2750,11 +2750,11 @@ namespace TEN::Renderer
|
|||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
|
@ -2853,7 +2853,7 @@ namespace TEN::Renderer
|
|||
// Draw sky.
|
||||
auto rotation = Matrix::CreateRotationX(PI);
|
||||
|
||||
BindShader(_sSky);
|
||||
_shaderManager.Bind(Shader::Sky);
|
||||
BindTexture(TextureRegister::ColorMap, &_skyTexture, SamplerStateRegister::AnisotropicClamp);
|
||||
|
||||
_context->IASetVertexBuffers(0, 1, _skyVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
|
@ -2894,7 +2894,7 @@ namespace TEN::Renderer
|
|||
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
BindShader(_sInstancedSprites);
|
||||
_shaderManager.Bind(Shader::InstancedSprites);
|
||||
|
||||
// Set up vertex buffer and parameters.
|
||||
UINT stride = sizeof(Vertex);
|
||||
|
@ -3033,7 +3033,7 @@ namespace TEN::Renderer
|
|||
_context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
BindShader(_sSky);
|
||||
_shaderManager.Bind(Shader::Sky);
|
||||
|
||||
auto& moveableObj = *_moveableObjects[ID_HORIZON];
|
||||
|
||||
|
@ -3077,7 +3077,7 @@ namespace TEN::Renderer
|
|||
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
BindShader(_sInstancedSprites);
|
||||
_shaderManager.Bind(Shader::InstancedSprites);
|
||||
|
||||
// Set up vertex buffer and parameters.
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
|
@ -3504,7 +3504,7 @@ namespace TEN::Renderer
|
|||
|
||||
ROOM_INFO* nativeRoom = &g_Level.Rooms[objectInfo->Room->RoomNumber];
|
||||
|
||||
BindShader(_sRooms);
|
||||
_shaderManager.Bind(Shader::Rooms);
|
||||
|
||||
UINT stride = sizeof(Vertex);
|
||||
UINT offset = 0;
|
||||
|
@ -3521,7 +3521,7 @@ namespace TEN::Renderer
|
|||
SetScissor(objectInfo->Room->ClipBounds);
|
||||
|
||||
if (objectInfo->Bucket->Animated != 0)
|
||||
BindShader(_sRoomsAnimated);
|
||||
_shaderManager.Bind(Shader::RoomsAnimated);
|
||||
|
||||
SetBlendMode(objectInfo->Bucket->BlendMode);
|
||||
SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
|
||||
|
@ -3587,7 +3587,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(objectInfo->Bucket->BlendMode);
|
||||
SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
BindShader(_sItems);
|
||||
_shaderManager.Bind(Shader::Items);
|
||||
|
||||
// Bind main item properties.
|
||||
Matrix world = objectInfo->Item->InterpolatedWorld;
|
||||
|
@ -3627,7 +3627,7 @@ namespace TEN::Renderer
|
|||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetInputLayout(_inputLayout.Get());
|
||||
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
|
||||
Matrix world = objectInfo->Static->World;
|
||||
_stStatic.World = world;
|
||||
|
@ -3665,7 +3665,7 @@ namespace TEN::Renderer
|
|||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetInputLayout(_inputLayout.Get());
|
||||
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
|
||||
Matrix world = objectInfo->World;
|
||||
_stStatic.World = world;
|
||||
|
@ -3704,10 +3704,10 @@ namespace TEN::Renderer
|
|||
SetDepthState(DepthState::Write);
|
||||
|
||||
// Common vertex shader to all full screen effects
|
||||
BindShader(_sPostProcess);
|
||||
_shaderManager.Bind(Shader::PostProcess);
|
||||
|
||||
// SSAO pixel shader
|
||||
BindShader(_sSSAO);
|
||||
_shaderManager.Bind(Shader::SSAO);
|
||||
|
||||
_context->ClearRenderTargetView(_SSAORenderTarget.RenderTargetView.Get(), Colors::White);
|
||||
_context->OMSetRenderTargets(1, _SSAORenderTarget.RenderTargetView.GetAddressOf(), nullptr);
|
||||
|
@ -3751,7 +3751,7 @@ namespace TEN::Renderer
|
|||
DrawTriangles(3, 0);
|
||||
|
||||
// Blur step
|
||||
BindShader(_sSSAOBlur);
|
||||
_shaderManager.Bind(Shader::SSAOBlur);
|
||||
|
||||
_context->ClearRenderTargetView(_SSAOBlurredRenderTarget.RenderTargetView.Get(), Colors::Black);
|
||||
_context->OMSetRenderTargets(1, _SSAOBlurredRenderTarget.RenderTargetView.GetAddressOf(), nullptr);
|
||||
|
|
|
@ -132,8 +132,8 @@ namespace TEN::Renderer
|
|||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetIndexBuffer(bar.IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
BindShader(_sHUD);
|
||||
BindShader(_sHUDTexture);
|
||||
_shaderManager.Bind(Shader::HUD);
|
||||
_shaderManager.Bind(Shader::HUDTexture);
|
||||
|
||||
SetBlendMode(BlendMode::Opaque);
|
||||
SetDepthState(DepthState::None);
|
||||
|
@ -161,8 +161,8 @@ namespace TEN::Renderer
|
|||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetIndexBuffer(bar.InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
BindShader(_sHUD);
|
||||
BindShader(_sHUDBarColor);
|
||||
_shaderManager.Bind(Shader::HUD);
|
||||
_shaderManager.Bind(Shader::HUDBarColor);
|
||||
|
||||
_stHUDBar.Percent = percent;
|
||||
_stHUDBar.Poisoned = isPoisoned;
|
||||
|
@ -195,8 +195,8 @@ namespace TEN::Renderer
|
|||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetIndexBuffer(g_LoadingBar->IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
BindShader(_sHUD);
|
||||
BindShader(_sHUDTexture);
|
||||
_shaderManager.Bind(Shader::HUD);
|
||||
_shaderManager.Bind(Shader::HUDTexture);
|
||||
|
||||
SetBlendMode(BlendMode::Opaque);
|
||||
SetDepthState(DepthState::None);
|
||||
|
@ -220,8 +220,8 @@ namespace TEN::Renderer
|
|||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetIndexBuffer(g_LoadingBar->InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
BindShader(_sHUD);
|
||||
BindShader(_sHUDBarColor);
|
||||
_shaderManager.Bind(Shader::HUD);
|
||||
_shaderManager.Bind(Shader::HUDBarColor);
|
||||
|
||||
_stHUDBar.Percent = percentage / 100.0f;
|
||||
_stHUDBar.Poisoned = false;
|
||||
|
@ -305,7 +305,7 @@ namespace TEN::Renderer
|
|||
vertices[3].UV.y = 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->IASetInputLayout(_inputLayout.Get());
|
||||
|
@ -341,7 +341,7 @@ namespace TEN::Renderer
|
|||
if (renderView.DisplaySpritesToDraw.empty())
|
||||
return;
|
||||
|
||||
BindShader(_sFullScreenQuad);
|
||||
_shaderManager.Bind(Shader::FullScreenQuad);
|
||||
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_context->IASetInputLayout(_inputLayout.Get());
|
||||
|
@ -463,7 +463,7 @@ namespace TEN::Renderer
|
|||
vertices[3].UV.y = uvEnd.y;
|
||||
vertices[3].Color = colorVec4;
|
||||
|
||||
BindShader(_sFullScreenQuad);
|
||||
_shaderManager.Bind(Shader::FullScreenQuad);
|
||||
|
||||
_context->PSSetShaderResources(0, 1, &texture);
|
||||
|
||||
|
@ -540,7 +540,7 @@ namespace TEN::Renderer
|
|||
vertices[3].UV.y = uvEnd.y;
|
||||
vertices[3].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
||||
|
||||
BindShader(_sFullScreenQuad);
|
||||
_shaderManager.Bind(Shader::FullScreenQuad);
|
||||
|
||||
_context->PSSetShaderResources(0, 1, &texture);
|
||||
auto* sampler = _renderStates->AnisotropicClamp();
|
||||
|
|
|
@ -1022,7 +1022,7 @@ namespace TEN::Renderer
|
|||
if (!settings.MuzzleFlash)
|
||||
return false;
|
||||
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
unsigned int offset = 0;
|
||||
|
@ -1143,7 +1143,7 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer::DrawBaddyGunflashes(RenderView& view)
|
||||
{
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
unsigned int offset = 0;
|
||||
|
@ -1369,7 +1369,7 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer::DrawEffects(RenderView& view, RendererPass rendererPass)
|
||||
{
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
unsigned int offset = 0;
|
||||
|
@ -1410,7 +1410,7 @@ namespace TEN::Renderer
|
|||
|
||||
if (activeDebrisExist)
|
||||
{
|
||||
BindShader(_sStatics);
|
||||
_shaderManager.Bind(Shader::Statics);
|
||||
|
||||
SetCullMode(CullMode::None);
|
||||
|
||||
|
|
|
@ -816,7 +816,7 @@ namespace TEN::Renderer
|
|||
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
// Set shaders.
|
||||
BindShader(_sInventory);
|
||||
_shaderManager.Bind(Shader::Inventory);
|
||||
|
||||
// Set matrices.
|
||||
CCameraMatrixBuffer hudCamera;
|
||||
|
@ -1009,7 +1009,7 @@ namespace TEN::Renderer
|
|||
_context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
// Set shaders
|
||||
BindShader(_sInventory);
|
||||
_shaderManager.Bind(Shader::Inventory);
|
||||
|
||||
if (CurrentLevel == 0)
|
||||
{
|
||||
|
|
|
@ -19,11 +19,6 @@ extern GameConfiguration g_Configuration;
|
|||
|
||||
using namespace TEN::Renderer::Utils;
|
||||
|
||||
static std::wstring GetAssetPath(const wchar_t* fileName)
|
||||
{
|
||||
return TEN::Utils::ToWString(g_GameFlow->GetGameDir()) + fileName;
|
||||
}
|
||||
|
||||
namespace TEN::Renderer
|
||||
{
|
||||
void Renderer::Initialize(int w, int h, bool windowed, HWND handle)
|
||||
|
@ -36,13 +31,12 @@ namespace TEN::Renderer
|
|||
InitializeScreen(w, h, handle, false);
|
||||
InitializeCommonTextures();
|
||||
|
||||
// Load shaders
|
||||
_shaderManager.LoadAllShaders(w, h);
|
||||
|
||||
// Initialize render states
|
||||
_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.
|
||||
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 }
|
||||
};
|
||||
|
||||
_sRooms = CompileOrLoadShader("Rooms", "", ShaderType::PixelAndVertex);
|
||||
Utils::throwIfFailed(_device->CreateInputLayout(inputLayoutItems, 12, _sRooms.Vertex.Blob->GetBufferPointer(), _sRooms.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]);
|
||||
auto& roomShader = _shaderManager.Get(Shader::Rooms);
|
||||
Utils::throwIfFailed(_device->CreateInputLayout(inputLayoutItems, 12, roomShader.Vertex.Blob->GetBufferPointer(), roomShader.Vertex.Blob->GetBufferSize(), &_inputLayout));
|
||||
|
||||
// Initialize constant buffers
|
||||
_cbCameraMatrices = CreateConstantBuffer<CCameraMatrixBuffer>();
|
||||
|
@ -220,7 +182,7 @@ namespace TEN::Renderer
|
|||
shadowSamplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
|
||||
shadowSamplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
|
||||
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 = {};
|
||||
|
||||
|
@ -285,8 +247,6 @@ namespace TEN::Renderer
|
|||
|
||||
_fullscreenTriangleVertexBuffer = VertexBuffer<PostProcessVertex>(_device.Get(), 3, &vertices[0]);
|
||||
|
||||
_sPostProcess = CompileOrLoadShader("PostProcess", "", ShaderType::PixelAndVertex);
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC postProcessInputLayoutItems[] =
|
||||
{
|
||||
{ "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 }
|
||||
};
|
||||
|
||||
auto& ppShader = _shaderManager.Get(Shader::PostProcess);
|
||||
Utils::throwIfFailed(_device->CreateInputLayout(postProcessInputLayoutItems, 3,
|
||||
_sPostProcess.Vertex.Blob->GetBufferPointer(), _sPostProcess.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);
|
||||
ppShader.Vertex.Blob->GetBufferPointer(), ppShader.Vertex.Blob->GetBufferSize(), &_fullscreenTriangleInputLayout));
|
||||
}
|
||||
|
||||
void Renderer::CreateSSAONoiseTexture()
|
||||
|
@ -382,8 +337,9 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer::InitializeSky()
|
||||
{
|
||||
Vertex vertices[SKY_VERTICES_COUNT];
|
||||
int indices[SKY_INDICES_COUNT];
|
||||
std::vector<Vertex> vertices(SKY_VERTICES_COUNT);
|
||||
std::vector<int> indices(SKY_INDICES_COUNT);
|
||||
|
||||
int size = SKY_SIZE;
|
||||
|
||||
int lastVertex = 0;
|
||||
|
@ -452,8 +408,8 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
_skyVertexBuffer = VertexBuffer<Vertex>(_device.Get(), SKY_VERTICES_COUNT, vertices);
|
||||
_skyIndexBuffer = IndexBuffer(_device.Get(), SKY_INDICES_COUNT, indices);
|
||||
_skyVertexBuffer = VertexBuffer<Vertex>(_device.Get(), SKY_VERTICES_COUNT, vertices.data());
|
||||
_skyIndexBuffer = IndexBuffer(_device.Get(), SKY_INDICES_COUNT, indices.data());
|
||||
}
|
||||
|
||||
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);
|
||||
_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);
|
||||
|
||||
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()
|
||||
|
@ -641,6 +563,9 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
Utils::throwIfFailed(res);
|
||||
|
||||
// Initialize shader manager
|
||||
_shaderManager.Initialize(_device, _context);
|
||||
}
|
||||
|
||||
void Renderer::ToggleFullScreen(bool force)
|
||||
|
@ -676,152 +601,4 @@ namespace TEN::Renderer
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ namespace TEN::Renderer
|
|||
_cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get());
|
||||
|
||||
// Common vertex shader to all fullscreen effects.
|
||||
BindShader(_sPostProcess);
|
||||
_shaderManager.Bind(Shader::PostProcess);
|
||||
|
||||
// Draw fullscreen triangle.
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -71,7 +71,7 @@ namespace TEN::Renderer
|
|||
_context->ClearRenderTargetView(_postProcessRenderTarget[destRenderTarget].RenderTargetView.Get(), clearColor);
|
||||
_context->OMSetRenderTargets(1, _postProcessRenderTarget[destRenderTarget].RenderTargetView.GetAddressOf(), nullptr);
|
||||
|
||||
BindShader(_sPostProcessLensFlare);
|
||||
_shaderManager.Bind(Shader::PostProcessLensFlare);
|
||||
|
||||
for (int i = 0; i < view.LensFlaresToDraw.size(); i++)
|
||||
{
|
||||
|
@ -97,15 +97,15 @@ namespace TEN::Renderer
|
|||
switch (_postProcessMode)
|
||||
{
|
||||
case PostProcessMode::Monochrome:
|
||||
BindShader(_sPostProcessMonochrome);
|
||||
_shaderManager.Bind(Shader::PostProcessMonochrome);
|
||||
break;
|
||||
|
||||
case PostProcessMode::Negative:
|
||||
BindShader(_sPostProcessNegative);
|
||||
_shaderManager.Bind(Shader::PostProcessNegative);
|
||||
break;
|
||||
|
||||
case PostProcessMode::Exclusion:
|
||||
BindShader(_sPostProcessExclusion);
|
||||
_shaderManager.Bind(Shader::PostProcessExclusion);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -120,7 +120,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
// Do final pass.
|
||||
BindShader(_sPostProcessFinalPass);
|
||||
_shaderManager.Bind(Shader::PostProcessFinalPass);
|
||||
|
||||
_context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black);
|
||||
_context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr);
|
||||
|
@ -172,7 +172,7 @@ namespace TEN::Renderer
|
|||
ResetScissor();
|
||||
|
||||
// Common vertex shader to all fullscreen effects
|
||||
BindShader(_sPostProcess);
|
||||
_shaderManager.Bind(Shader::PostProcess);
|
||||
|
||||
// We draw a fullscreen triangle
|
||||
_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
|
|
@ -279,7 +279,7 @@ namespace TEN::Renderer
|
|||
SetDepthState(DepthState::Read);
|
||||
SetCullMode(CullMode::None);
|
||||
|
||||
BindShader(_sInstancedSprites);
|
||||
_shaderManager.Bind(Shader::InstancedSprites);
|
||||
|
||||
// Set up vertex buffer and parameters.
|
||||
unsigned int stride = sizeof(Vertex);
|
||||
|
@ -340,7 +340,7 @@ namespace TEN::Renderer
|
|||
SetDepthState(DepthState::Read);
|
||||
SetCullMode(CullMode::None);
|
||||
|
||||
BindShader(_sSprites);
|
||||
_shaderManager.Bind(Shader::Sprites);
|
||||
|
||||
wasGPUSet = true;
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(object->Sprite->BlendMode);
|
||||
SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
BindShader(_sInstancedSprites);
|
||||
_shaderManager.Bind(Shader::InstancedSprites);
|
||||
|
||||
// Set up vertex buffer and parameters.
|
||||
UINT stride = sizeof(Vertex);
|
||||
|
@ -456,7 +456,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(object->Sprite->BlendMode);
|
||||
SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
BindShader(_sSprites);
|
||||
_shaderManager.Bind(Shader::Sprites);
|
||||
|
||||
_stSprite.IsSoftParticle = object->Sprite->SoftParticle ? 1 : 0;
|
||||
_stSprite.RenderType = (int)object->Sprite->renderType;
|
||||
|
@ -501,7 +501,7 @@ namespace TEN::Renderer
|
|||
UINT stride = sizeof(Vertex);
|
||||
UINT offset = 0;
|
||||
|
||||
BindShader(_sSprites);
|
||||
_shaderManager.Bind(Shader::Sprites);
|
||||
|
||||
_sortedPolygonsVertexBuffer.Update(_context.Get(), _sortedPolygonsVertices.data(), 0, (int)_sortedPolygonsVertices.size());
|
||||
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
#include <wrl/client.h>
|
||||
|
||||
#include "Renderer/Renderer.h"
|
||||
#include "Renderer/Structures/RendererShader.h"
|
||||
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
||||
#include "Specific/trutils.h"
|
||||
#include "Structures/RendererShader.h"
|
||||
|
||||
namespace TEN::Renderer::Utils
|
||||
{
|
||||
|
@ -42,4 +43,9 @@ namespace TEN::Renderer::Utils
|
|||
throw std::runtime_error("An error occured!");
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring GetAssetPath(const wchar_t* fileName)
|
||||
{
|
||||
return TEN::Utils::ToWString(g_GameFlow->GetGameDir()) + fileName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,4 +9,6 @@ namespace TEN::Renderer::Utils
|
|||
void throwIfFailed(const HRESULT& res);
|
||||
void throwIfFailed(const HRESULT& res, const std::string& info);
|
||||
void throwIfFailed(const HRESULT& res, const std::wstring& info);
|
||||
|
||||
std::wstring GetAssetPath(const wchar_t* fileName);
|
||||
}
|
||||
|
|
306
TombEngine/Renderer/ShaderManager/ShaderManager.cpp
Normal file
306
TombEngine/Renderer/ShaderManager/ShaderManager.cpp
Normal 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];
|
||||
}
|
||||
}
|
84
TombEngine/Renderer/ShaderManager/ShaderManager.h
Normal file
84
TombEngine/Renderer/ShaderManager/ShaderManager.h
Normal 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);
|
||||
};
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
#include <fstream>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <d3d11.h>
|
||||
#include <SimpleMath.h>
|
||||
|
||||
|
|
|
@ -651,6 +651,11 @@ namespace TEN::Input
|
|||
if ((KeyMap[KC_F10] || KeyMap[KC_F11]) && dbDebugPage)
|
||||
g_Renderer.SwitchDebugPage(KeyMap[KC_F10]);
|
||||
dbDebugPage = !(KeyMap[KC_F10] || KeyMap[KC_F11]);
|
||||
|
||||
// Reload shaders.
|
||||
static bool dbReloadShaders = true;
|
||||
if (KeyMap[KC_F9] && dbReloadShaders)
|
||||
g_Renderer.ReloadShaders();
|
||||
}
|
||||
|
||||
static void UpdateRumble()
|
||||
|
|
|
@ -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\Renderer.h" />
|
||||
<ClInclude Include="Renderer\RendererEnums.h" />
|
||||
<ClInclude Include="Renderer\ShaderManager\ShaderManager.h" />
|
||||
<ClInclude Include="Renderer\Structures\RendererMirror.h" />
|
||||
<ClInclude Include="Renderer\RendererSprite2D.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\RendererUtils.cpp" />
|
||||
<ClCompile Include="Renderer\RenderView.cpp" />
|
||||
<ClCompile Include="Renderer\ShaderManager\ShaderManager.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\LuaHandler.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\ScriptAssert.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\ScriptInterfaceState.cpp" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue