Switches from pipeline state descriptions to pipeline states.
Tested By: phosit, Stan Differential Revision: https://code.wildfiregames.com/D4850 This was SVN commit r27328.
This commit is contained in:
parent
0152c26b72
commit
4ed41d4a9a
@ -7,6 +7,7 @@
|
|||||||
<pass shader="arb/terrain_blend">
|
<pass shader="arb/terrain_blend">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<cull mode="FRONT"/>
|
<cull mode="FRONT"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -16,15 +17,18 @@
|
|||||||
<pass shader="glsl/terrain_blend">
|
<pass shader="glsl/terrain_blend">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<cull mode="FRONT"/>
|
<cull mode="FRONT"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
|
|
||||||
<technique>
|
<technique>
|
||||||
<require shaders="arb"/>
|
<require shaders="arb"/>
|
||||||
<require context="MODE_WIREFRAME"/>
|
<require context="MODE_WIREFRAME"/>
|
||||||
<pass shader="arb/terrain_blend">
|
<pass shader="arb/terrain_blend">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<polygon mode="LINE"/>
|
<polygon mode="LINE"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -34,6 +38,7 @@
|
|||||||
<pass shader="glsl/terrain_blend">
|
<pass shader="glsl/terrain_blend">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<polygon mode="LINE"/>
|
<polygon mode="LINE"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -42,6 +47,7 @@
|
|||||||
<require shaders="arb"/>
|
<require shaders="arb"/>
|
||||||
<pass shader="arb/terrain_blend">
|
<pass shader="arb/terrain_blend">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -49,6 +55,7 @@
|
|||||||
<require shaders="glsl"/>
|
<require shaders="glsl"/>
|
||||||
<pass shader="glsl/terrain_blend">
|
<pass shader="glsl/terrain_blend">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<pass shader="arb/terrain_decal">
|
<pass shader="arb/terrain_decal">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<cull mode="FRONT"/>
|
<cull mode="FRONT"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -16,6 +17,7 @@
|
|||||||
<pass shader="glsl/terrain_decal">
|
<pass shader="glsl/terrain_decal">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<cull mode="FRONT"/>
|
<cull mode="FRONT"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -26,6 +28,7 @@
|
|||||||
<pass shader="arb/terrain_decal">
|
<pass shader="arb/terrain_decal">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<polygon mode="LINE"/>
|
<polygon mode="LINE"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -35,6 +38,7 @@
|
|||||||
<pass shader="glsl/terrain_decal">
|
<pass shader="glsl/terrain_decal">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
<polygon mode="LINE"/>
|
<polygon mode="LINE"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -43,6 +47,7 @@
|
|||||||
<require shaders="arb"/>
|
<require shaders="arb"/>
|
||||||
<pass shader="arb/terrain_decal">
|
<pass shader="arb/terrain_decal">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
@ -50,6 +55,7 @@
|
|||||||
<require shaders="glsl"/>
|
<require shaders="glsl"/>
|
||||||
<pass shader="glsl/terrain_decal">
|
<pass shader="glsl/terrain_decal">
|
||||||
<depth mask="false"/>
|
<depth mask="false"/>
|
||||||
|
<blend src="src_alpha" dst="one_minus_src_alpha"/>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
// The canvas technique must be loaded because we can't render UI without it.
|
// The canvas technique must be loaded because we can't render UI without it.
|
||||||
ENSURE(Tech);
|
ENSURE(Tech);
|
||||||
DeviceCommandContext->SetGraphicsPipelineState(
|
DeviceCommandContext->SetGraphicsPipelineState(
|
||||||
Tech->GetGraphicsPipelineStateDesc());
|
Tech->GetGraphicsPipelineState());
|
||||||
DeviceCommandContext->BeginPass();
|
DeviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = Tech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = Tech->GetShader();
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::IDeviceCommandContext* devic
|
|||||||
deviceCommandContext->BeginFramebufferPass(m_SmoothFramebuffers[m_WhichTexture].get());
|
deviceCommandContext->BeginFramebufferPass(m_SmoothFramebuffers[m_WhichTexture].get());
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
m_SmoothTech->GetGraphicsPipelineStateDesc());
|
m_SmoothTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = m_SmoothTech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = m_SmoothTech->GetShader();
|
||||||
|
@ -282,6 +282,26 @@ CMiniMapTexture::CMiniMapTexture(CSimulation2& simulation)
|
|||||||
m_InstanceVertexArray.Upload();
|
m_InstanceVertexArray.Upload();
|
||||||
m_InstanceVertexArray.FreeBackingStore();
|
m_InstanceVertexArray.FreeBackingStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CShaderDefines baseDefines;
|
||||||
|
baseDefines.Add(str_MINIMAP_BASE, str_1);
|
||||||
|
|
||||||
|
m_TerritoryTechnique = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
str_minimap, baseDefines,
|
||||||
|
[](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
pipelineStateDesc.blendState.enabled = true;
|
||||||
|
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
||||||
|
Renderer::Backend::BlendOp::ADD;
|
||||||
|
pipelineStateDesc.blendState.colorWriteMask =
|
||||||
|
Renderer::Backend::ColorWriteMask::RED |
|
||||||
|
Renderer::Backend::ColorWriteMask::GREEN |
|
||||||
|
Renderer::Backend::ColorWriteMask::BLUE;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CMiniMapTexture::~CMiniMapTexture()
|
CMiniMapTexture::~CMiniMapTexture()
|
||||||
@ -480,7 +500,7 @@ void CMiniMapTexture::RenderFinalTexture(
|
|||||||
|
|
||||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, baseDefines);
|
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, baseDefines);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc());
|
tech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
shader = tech->GetShader();
|
shader = tech->GetShader();
|
||||||
|
|
||||||
@ -513,20 +533,9 @@ void CMiniMapTexture::RenderFinalTexture(
|
|||||||
DrawTexture(deviceCommandContext);
|
DrawTexture(deviceCommandContext);
|
||||||
deviceCommandContext->EndPass();
|
deviceCommandContext->EndPass();
|
||||||
|
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc();
|
m_TerritoryTechnique->GetGraphicsPipelineState());
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
shader = m_TerritoryTechnique->GetShader();
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
pipelineStateDesc.blendState.colorWriteMask =
|
|
||||||
Renderer::Backend::ColorWriteMask::RED |
|
|
||||||
Renderer::Backend::ColorWriteMask::GREEN |
|
|
||||||
Renderer::Backend::ColorWriteMask::BLUE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
// Draw territory boundaries
|
// Draw territory boundaries
|
||||||
@ -548,7 +557,7 @@ void CMiniMapTexture::RenderFinalTexture(
|
|||||||
|
|
||||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap_los, CShaderDefines());
|
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap_los, CShaderDefines());
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc());
|
tech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
shader = tech->GetShader();
|
shader = tech->GetShader();
|
||||||
|
|
||||||
@ -765,7 +774,7 @@ void CMiniMapTexture::DrawEntities(
|
|||||||
pointDefines.Add(str_USE_GPU_INSTANCING, str_1);
|
pointDefines.Add(str_USE_GPU_INSTANCING, str_1);
|
||||||
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, pointDefines);
|
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, pointDefines);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc());
|
tech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define INCLUDED_MINIMAPTEXTURE
|
#define INCLUDED_MINIMAPTEXTURE
|
||||||
|
|
||||||
#include "graphics/Color.h"
|
#include "graphics/Color.h"
|
||||||
|
#include "graphics/ShaderTechniquePtr.h"
|
||||||
#include "graphics/Texture.h"
|
#include "graphics/Texture.h"
|
||||||
#include "maths/Vector2D.h"
|
#include "maths/Vector2D.h"
|
||||||
#include "renderer/backend/IDeviceCommandContext.h"
|
#include "renderer/backend/IDeviceCommandContext.h"
|
||||||
@ -123,6 +124,8 @@ private:
|
|||||||
VertexArray m_InstanceVertexArray;
|
VertexArray m_InstanceVertexArray;
|
||||||
VertexArray::Attribute m_InstanceAttributePosition;
|
VertexArray::Attribute m_InstanceAttributePosition;
|
||||||
|
|
||||||
|
CShaderTechniquePtr m_TerritoryTechnique;
|
||||||
|
|
||||||
size_t m_EntitiesDrawn = 0;
|
size_t m_EntitiesDrawn = 0;
|
||||||
|
|
||||||
double m_PingDuration = 25.0;
|
double m_PingDuration = 25.0;
|
||||||
|
@ -116,7 +116,8 @@ CShaderTechniquePtr CShaderManager::LoadEffect(CStrIntern name, const CShaderDef
|
|||||||
|
|
||||||
// First time we've seen this key, so construct a new effect:
|
// First time we've seen this key, so construct a new effect:
|
||||||
const VfsPath xmlFilename = L"shaders/effects/" + wstring_from_utf8(name.string()) + L".xml";
|
const VfsPath xmlFilename = L"shaders/effects/" + wstring_from_utf8(name.string()) + L".xml";
|
||||||
CShaderTechniquePtr tech(new CShaderTechnique(xmlFilename, defines));
|
CShaderTechniquePtr tech = std::make_shared<CShaderTechnique>(
|
||||||
|
xmlFilename, defines, PipelineStateDescCallback{});
|
||||||
if (!LoadTechnique(tech))
|
if (!LoadTechnique(tech))
|
||||||
{
|
{
|
||||||
LOGERROR("Failed to load effect '%s'", name.c_str());
|
LOGERROR("Failed to load effect '%s'", name.c_str());
|
||||||
@ -127,6 +128,20 @@ CShaderTechniquePtr CShaderManager::LoadEffect(CStrIntern name, const CShaderDef
|
|||||||
return tech;
|
return tech;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CShaderTechniquePtr CShaderManager::LoadEffect(
|
||||||
|
CStrIntern name, const CShaderDefines& defines, const PipelineStateDescCallback& callback)
|
||||||
|
{
|
||||||
|
// We don't cache techniques with callbacks.
|
||||||
|
const VfsPath xmlFilename = L"shaders/effects/" + wstring_from_utf8(name.string()) + L".xml";
|
||||||
|
CShaderTechniquePtr technique = std::make_shared<CShaderTechnique>(xmlFilename, defines, callback);
|
||||||
|
if (!LoadTechnique(technique))
|
||||||
|
{
|
||||||
|
LOGERROR("Failed to load effect '%s'", name.c_str());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return technique;
|
||||||
|
}
|
||||||
|
|
||||||
bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
|
bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
|
||||||
{
|
{
|
||||||
PROFILE2("loading technique");
|
PROFILE2("loading technique");
|
||||||
@ -144,9 +159,14 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
|
|||||||
// By default we assume that we have techinques for every dummy shader.
|
// By default we assume that we have techinques for every dummy shader.
|
||||||
if (device->GetBackend() == Renderer::Backend::Backend::DUMMY)
|
if (device->GetBackend() == Renderer::Backend::Backend::DUMMY)
|
||||||
{
|
{
|
||||||
const Renderer::Backend::GraphicsPipelineStateDesc passPipelineStateDesc =
|
CShaderProgramPtr shaderProgram = LoadProgram("dummy", tech->GetShaderDefines());
|
||||||
|
std::vector<CShaderPass> techPasses;
|
||||||
|
Renderer::Backend::SGraphicsPipelineStateDesc passPipelineStateDesc =
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc();
|
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc();
|
||||||
tech->SetPasses({{passPipelineStateDesc, LoadProgram("dummy", tech->GetShaderDefines())}});
|
passPipelineStateDesc.shaderProgram = shaderProgram->GetBackendShaderProgram();
|
||||||
|
techPasses.emplace_back(
|
||||||
|
device->CreateGraphicsPipelineState(passPipelineStateDesc), shaderProgram);
|
||||||
|
tech->SetPasses(std::move(techPasses));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +287,7 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
|
|||||||
{
|
{
|
||||||
CShaderDefines passDefines = techDefines;
|
CShaderDefines passDefines = techDefines;
|
||||||
|
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc passPipelineStateDesc =
|
Renderer::Backend::SGraphicsPipelineStateDesc passPipelineStateDesc =
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc();
|
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc();
|
||||||
|
|
||||||
XERO_ITER_EL(Child, Element)
|
XERO_ITER_EL(Child, Element)
|
||||||
@ -410,7 +430,11 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
|
|||||||
{
|
{
|
||||||
for (const VfsPath& shaderProgramPath : shaderProgram->GetFileDependencies())
|
for (const VfsPath& shaderProgramPath : shaderProgram->GetFileDependencies())
|
||||||
AddTechniqueFileDependency(tech, shaderProgramPath);
|
AddTechniqueFileDependency(tech, shaderProgramPath);
|
||||||
techPasses.emplace_back(passPipelineStateDesc, shaderProgram);
|
if (tech->GetPipelineStateDescCallback())
|
||||||
|
tech->GetPipelineStateDescCallback()(passPipelineStateDesc);
|
||||||
|
passPipelineStateDesc.shaderProgram = shaderProgram->GetBackendShaderProgram();
|
||||||
|
techPasses.emplace_back(
|
||||||
|
device->CreateGraphicsPipelineState(passPipelineStateDesc), shaderProgram);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@
|
|||||||
#include "graphics/ShaderDefines.h"
|
#include "graphics/ShaderDefines.h"
|
||||||
#include "graphics/ShaderProgram.h"
|
#include "graphics/ShaderProgram.h"
|
||||||
#include "graphics/ShaderTechnique.h"
|
#include "graphics/ShaderTechnique.h"
|
||||||
|
#include "renderer/backend/PipelineState.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -48,10 +50,18 @@ public:
|
|||||||
CShaderTechniquePtr LoadEffect(CStrIntern name, const CShaderDefines& defines);
|
CShaderTechniquePtr LoadEffect(CStrIntern name, const CShaderDefines& defines);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a shader effect, with default system defines (from CRenderer::GetSystemShaderDefines).
|
* Load a shader effect, with empty defines.
|
||||||
*/
|
*/
|
||||||
CShaderTechniquePtr LoadEffect(CStrIntern name);
|
CShaderTechniquePtr LoadEffect(CStrIntern name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a shader effect with the pipeline state description overwriting.
|
||||||
|
* TODO: we should set all needed states in XML.
|
||||||
|
*/
|
||||||
|
using PipelineStateDescCallback = CShaderTechnique::PipelineStateDescCallback;
|
||||||
|
CShaderTechniquePtr LoadEffect(
|
||||||
|
CStrIntern name, const CShaderDefines& defines, const PipelineStateDescCallback& callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of shader effects that are currently loaded.
|
* Returns the number of shader effects that are currently loaded.
|
||||||
*/
|
*/
|
||||||
@ -71,7 +81,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CShaderProgram contains expensive GL state, so we ought to cache it.
|
// A CShaderProgram contains expensive backend state, so we ought to cache it.
|
||||||
// The compiled state depends solely on the filename and list of defines,
|
// The compiled state depends solely on the filename and list of defines,
|
||||||
// so we store that in CacheKey.
|
// so we store that in CacheKey.
|
||||||
// TODO: is this cache useful when we already have an effect cache?
|
// TODO: is this cache useful when we already have an effect cache?
|
||||||
|
@ -20,17 +20,20 @@
|
|||||||
#include "ShaderTechnique.h"
|
#include "ShaderTechnique.h"
|
||||||
|
|
||||||
#include "graphics/ShaderProgram.h"
|
#include "graphics/ShaderProgram.h"
|
||||||
|
#include "renderer/backend/IDevice.h"
|
||||||
|
|
||||||
CShaderPass::CShaderPass(
|
CShaderPass::CShaderPass(
|
||||||
const Renderer::Backend::GraphicsPipelineStateDesc& pipelineStateDesc,
|
std::unique_ptr<Renderer::Backend::IGraphicsPipelineState> pipelineState,
|
||||||
const CShaderProgramPtr& shader)
|
const CShaderProgramPtr& shader)
|
||||||
: m_PipelineStateDesc(pipelineStateDesc), m_Shader(shader)
|
: m_Shader(shader), m_PipelineState(std::move(pipelineState))
|
||||||
{
|
{
|
||||||
m_PipelineStateDesc.shaderProgram = m_Shader->GetBackendShaderProgram();
|
ENSURE(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
CShaderTechnique::CShaderTechnique(const VfsPath& path, const CShaderDefines& defines)
|
CShaderTechnique::CShaderTechnique(
|
||||||
: m_Path(path), m_Defines(defines)
|
const VfsPath& path, const CShaderDefines& defines,
|
||||||
|
const PipelineStateDescCallback& callback)
|
||||||
|
: m_Path(path), m_Defines(defines), m_PipelineStateDescCallback(callback)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,14 +50,14 @@ int CShaderTechnique::GetNumPasses() const
|
|||||||
Renderer::Backend::IShaderProgram* CShaderTechnique::GetShader(int pass) const
|
Renderer::Backend::IShaderProgram* CShaderTechnique::GetShader(int pass) const
|
||||||
{
|
{
|
||||||
ENSURE(0 <= pass && pass < (int)m_Passes.size());
|
ENSURE(0 <= pass && pass < (int)m_Passes.size());
|
||||||
return m_Passes[pass].GetShader();
|
return m_Passes[pass].GetPipelineState()->GetShaderProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Renderer::Backend::GraphicsPipelineStateDesc&
|
Renderer::Backend::IGraphicsPipelineState*
|
||||||
CShaderTechnique::GetGraphicsPipelineStateDesc(int pass) const
|
CShaderTechnique::GetGraphicsPipelineState(int pass) const
|
||||||
{
|
{
|
||||||
ENSURE(0 <= pass && pass < static_cast<int>(m_Passes.size()));
|
ENSURE(0 <= pass && pass < static_cast<int>(m_Passes.size()));
|
||||||
return m_Passes[pass].GetPipelineStateDesc();
|
return m_Passes[pass].GetPipelineState();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CShaderTechnique::GetSortByDistance() const
|
bool CShaderTechnique::GetSortByDistance() const
|
||||||
|
@ -21,29 +21,35 @@
|
|||||||
#include "graphics/ShaderDefines.h"
|
#include "graphics/ShaderDefines.h"
|
||||||
#include "graphics/ShaderProgram.h"
|
#include "graphics/ShaderProgram.h"
|
||||||
#include "graphics/ShaderTechniquePtr.h"
|
#include "graphics/ShaderTechniquePtr.h"
|
||||||
|
#include "lib/code_annotation.h"
|
||||||
#include "lib/file/vfs/vfs_path.h"
|
#include "lib/file/vfs/vfs_path.h"
|
||||||
#include "renderer/backend/PipelineState.h"
|
#include "renderer/backend/PipelineState.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a render pass consisting of various GL state changes and a shader,
|
* Implements a render pass consisting of a pipeline state and a shader,
|
||||||
* used by CShaderTechnique.
|
* used by CShaderTechnique.
|
||||||
*/
|
*/
|
||||||
class CShaderPass
|
class CShaderPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CShaderPass(const Renderer::Backend::GraphicsPipelineStateDesc& pipelineStateDesc, const CShaderProgramPtr& shader);
|
CShaderPass(
|
||||||
|
std::unique_ptr<Renderer::Backend::IGraphicsPipelineState> pipelineState,
|
||||||
|
const CShaderProgramPtr& shader);
|
||||||
|
MOVABLE(CShaderPass);
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* GetShader() const { return m_Shader->GetBackendShaderProgram(); }
|
const CShaderProgramPtr& GetShaderProgram() const noexcept { return m_Shader; }
|
||||||
|
|
||||||
const Renderer::Backend::GraphicsPipelineStateDesc&
|
Renderer::Backend::IGraphicsPipelineState*
|
||||||
GetPipelineStateDesc() const { return m_PipelineStateDesc; }
|
GetPipelineState() const noexcept { return m_PipelineState.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CShaderProgramPtr m_Shader;
|
CShaderProgramPtr m_Shader;
|
||||||
|
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc m_PipelineStateDesc{};
|
std::unique_ptr<Renderer::Backend::IGraphicsPipelineState> m_PipelineState;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,7 +59,10 @@ private:
|
|||||||
class CShaderTechnique
|
class CShaderTechnique
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CShaderTechnique(const VfsPath& path, const CShaderDefines& defines);
|
using PipelineStateDescCallback =
|
||||||
|
std::function<void(Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)>;
|
||||||
|
|
||||||
|
CShaderTechnique(const VfsPath& path, const CShaderDefines& defines, const PipelineStateDescCallback& callback);
|
||||||
|
|
||||||
void SetPasses(std::vector<CShaderPass>&& passes);
|
void SetPasses(std::vector<CShaderPass>&& passes);
|
||||||
|
|
||||||
@ -61,8 +70,8 @@ public:
|
|||||||
|
|
||||||
Renderer::Backend::IShaderProgram* GetShader(int pass = 0) const;
|
Renderer::Backend::IShaderProgram* GetShader(int pass = 0) const;
|
||||||
|
|
||||||
const Renderer::Backend::GraphicsPipelineStateDesc&
|
Renderer::Backend::IGraphicsPipelineState*
|
||||||
GetGraphicsPipelineStateDesc(int pass = 0) const;
|
GetGraphicsPipelineState(int pass = 0) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this technique uses alpha blending that requires objects to be
|
* Whether this technique uses alpha blending that requires objects to be
|
||||||
@ -76,6 +85,8 @@ public:
|
|||||||
|
|
||||||
const CShaderDefines& GetShaderDefines() { return m_Defines; }
|
const CShaderDefines& GetShaderDefines() { return m_Defines; }
|
||||||
|
|
||||||
|
const PipelineStateDescCallback& GetPipelineStateDescCallback() const { return m_PipelineStateDescCallback; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CShaderPass> m_Passes;
|
std::vector<CShaderPass> m_Passes;
|
||||||
|
|
||||||
@ -84,6 +95,8 @@ private:
|
|||||||
// We need additional data to reload the technique.
|
// We need additional data to reload the technique.
|
||||||
VfsPath m_Path;
|
VfsPath m_Path;
|
||||||
CShaderDefines m_Defines;
|
CShaderDefines m_Defines;
|
||||||
|
|
||||||
|
PipelineStateDescCallback m_PipelineStateDescCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDED_SHADERTECHNIQUE
|
#endif // INCLUDED_SHADERTECHNIQUE
|
||||||
|
@ -164,6 +164,9 @@ X(sky_simple)
|
|||||||
X(solid)
|
X(solid)
|
||||||
X(sunColor)
|
X(sunColor)
|
||||||
X(sunDir)
|
X(sunDir)
|
||||||
|
X(terrain_base)
|
||||||
|
X(terrain_blend)
|
||||||
|
X(terrain_decal)
|
||||||
X(terrain_solid)
|
X(terrain_solid)
|
||||||
X(tex)
|
X(tex)
|
||||||
X(texSize)
|
X(texSize)
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "graphics/Color.h"
|
#include "graphics/Color.h"
|
||||||
#include "graphics/ShaderManager.h"
|
#include "graphics/ShaderManager.h"
|
||||||
#include "graphics/ShaderProgram.h"
|
#include "graphics/ShaderProgram.h"
|
||||||
|
#include "lib/hash.h"
|
||||||
#include "maths/BoundingBoxAligned.h"
|
#include "maths/BoundingBoxAligned.h"
|
||||||
#include "maths/Brush.h"
|
#include "maths/Brush.h"
|
||||||
#include "maths/Matrix3D.h"
|
#include "maths/Matrix3D.h"
|
||||||
@ -34,36 +35,6 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
void SetGraphicsPipelineStateFromTechAndColor(
|
|
||||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
|
|
||||||
const CShaderTechniquePtr& tech, const CColor& color, const bool depthTestEnabled = true,
|
|
||||||
const bool wireframe = false)
|
|
||||||
{
|
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc = tech->GetGraphicsPipelineStateDesc();
|
|
||||||
pipelineStateDesc.depthStencilState.depthTestEnabled = depthTestEnabled;
|
|
||||||
if (color.a != 1.0f)
|
|
||||||
{
|
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pipelineStateDesc.blendState.enabled = false;
|
|
||||||
if (wireframe)
|
|
||||||
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
|
||||||
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
void CDebugRenderer::DrawLine(
|
void CDebugRenderer::DrawLine(
|
||||||
const CVector3D& from, const CVector3D& to, const CColor& color,
|
const CVector3D& from, const CVector3D& to, const CColor& color,
|
||||||
const float width, const bool depthTestEnabled)
|
const float width, const bool depthTestEnabled)
|
||||||
@ -81,12 +52,13 @@ void CDebugRenderer::DrawLine(
|
|||||||
if (line.size() <= 1)
|
if (line.size() <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CShaderTechniquePtr debugLineTech =
|
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
|
||||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
||||||
g_Renderer.GetDeviceCommandContext();
|
g_Renderer.GetDeviceCommandContext();
|
||||||
SetGraphicsPipelineStateFromTechAndColor(
|
|
||||||
deviceCommandContext, debugLineTech, color, depthTestEnabled);
|
CShaderTechniquePtr debugLineTech =
|
||||||
|
GetShaderTechnique(str_debug_line, color, depthTestEnabled);
|
||||||
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
|
debugLineTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
const CCamera& viewCamera = g_Renderer.GetSceneRenderer().GetViewCamera();
|
const CCamera& viewCamera = g_Renderer.GetSceneRenderer().GetViewCamera();
|
||||||
@ -142,11 +114,13 @@ void CDebugRenderer::DrawLine(
|
|||||||
void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, const CColor& color)
|
void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, const CColor& color)
|
||||||
{
|
{
|
||||||
CShaderTechniquePtr debugCircleTech =
|
CShaderTechniquePtr debugCircleTech =
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
GetShaderTechnique(str_debug_line, color);
|
||||||
|
|
||||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
||||||
g_Renderer.GetDeviceCommandContext();
|
g_Renderer.GetDeviceCommandContext();
|
||||||
SetGraphicsPipelineStateFromTechAndColor(
|
|
||||||
deviceCommandContext, debugCircleTech, color);
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
|
debugCircleTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
const CCamera& camera = g_Renderer.GetSceneRenderer().GetViewCamera();
|
const CCamera& camera = g_Renderer.GetSceneRenderer().GetViewCamera();
|
||||||
@ -208,11 +182,12 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& colo
|
|||||||
}
|
}
|
||||||
|
|
||||||
CShaderTechniquePtr overlayTech =
|
CShaderTechniquePtr overlayTech =
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
GetShaderTechnique(str_debug_line, color, true, wireframe);
|
||||||
|
|
||||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
||||||
g_Renderer.GetDeviceCommandContext();
|
g_Renderer.GetDeviceCommandContext();
|
||||||
SetGraphicsPipelineStateFromTechAndColor(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
deviceCommandContext, overlayTech, color, true, wireframe);
|
overlayTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* overlayShader = overlayTech->GetShader();
|
Renderer::Backend::IShaderProgram* overlayShader = overlayTech->GetShader();
|
||||||
@ -311,11 +286,13 @@ void CDebugRenderer::DrawBoundingBox(
|
|||||||
const CBoundingBoxAligned& boundingBox, const CColor& color,
|
const CBoundingBoxAligned& boundingBox, const CColor& color,
|
||||||
const CMatrix3D& transform, bool wireframe)
|
const CMatrix3D& transform, bool wireframe)
|
||||||
{
|
{
|
||||||
CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
CShaderTechniquePtr shaderTech =
|
||||||
|
GetShaderTechnique(str_debug_line, color, true, wireframe);
|
||||||
|
|
||||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
||||||
g_Renderer.GetDeviceCommandContext();
|
g_Renderer.GetDeviceCommandContext();
|
||||||
SetGraphicsPipelineStateFromTechAndColor(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
deviceCommandContext, shaderTech, color, true, wireframe);
|
shaderTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader();
|
||||||
@ -360,11 +337,13 @@ void CDebugRenderer::DrawBoundingBox(
|
|||||||
|
|
||||||
void CDebugRenderer::DrawBrush(const CBrush& brush, const CColor& color, bool wireframe)
|
void CDebugRenderer::DrawBrush(const CBrush& brush, const CColor& color, bool wireframe)
|
||||||
{
|
{
|
||||||
CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
CShaderTechniquePtr shaderTech =
|
||||||
|
GetShaderTechnique(str_debug_line, color, true, wireframe);
|
||||||
|
|
||||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
|
||||||
g_Renderer.GetDeviceCommandContext();
|
g_Renderer.GetDeviceCommandContext();
|
||||||
SetGraphicsPipelineStateFromTechAndColor(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
deviceCommandContext, shaderTech, color, true, wireframe);
|
shaderTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader();
|
||||||
@ -412,3 +391,56 @@ void CDebugRenderer::DrawBrush(const CBrush& brush, const CColor& color, bool wi
|
|||||||
deviceCommandContext->EndPass();
|
deviceCommandContext->EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t CDebugRenderer::ShaderTechniqueKeyHash::operator()(
|
||||||
|
const ShaderTechniqueKey& key) const
|
||||||
|
{
|
||||||
|
size_t seed = 0;
|
||||||
|
hash_combine(seed, key.name.GetHash());
|
||||||
|
hash_combine(seed, key.transparent);
|
||||||
|
hash_combine(seed, key.depthTestEnabled);
|
||||||
|
hash_combine(seed, key.wireframe);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDebugRenderer::ShaderTechniqueKeyEqual::operator()(
|
||||||
|
const ShaderTechniqueKey& lhs, const ShaderTechniqueKey& rhs) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
lhs.name == rhs.name && lhs.transparent == rhs.transparent &&
|
||||||
|
lhs.depthTestEnabled == rhs.depthTestEnabled &&
|
||||||
|
lhs.wireframe == rhs.wireframe;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CShaderTechniquePtr& CDebugRenderer::GetShaderTechnique(
|
||||||
|
const CStrIntern name, const CColor& color, const bool depthTestEnabled,
|
||||||
|
const bool wireframe)
|
||||||
|
{
|
||||||
|
const ShaderTechniqueKey key{
|
||||||
|
name, color.a != 1.0f, depthTestEnabled, wireframe};
|
||||||
|
CShaderTechniquePtr& shaderTechnique = m_ShaderTechniqueMapping[key];
|
||||||
|
if (shaderTechnique)
|
||||||
|
return shaderTechnique;
|
||||||
|
|
||||||
|
shaderTechnique = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
name, {},
|
||||||
|
[key](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
pipelineStateDesc.depthStencilState.depthTestEnabled = key.depthTestEnabled;
|
||||||
|
if (key.transparent)
|
||||||
|
{
|
||||||
|
pipelineStateDesc.blendState.enabled = true;
|
||||||
|
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
||||||
|
Renderer::Backend::BlendOp::ADD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pipelineStateDesc.blendState.enabled = false;
|
||||||
|
if (key.wireframe)
|
||||||
|
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
||||||
|
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
||||||
|
});
|
||||||
|
return shaderTechnique;
|
||||||
|
}
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
#ifndef INCLUDED_DEBUGRENDERER
|
#ifndef INCLUDED_DEBUGRENDERER
|
||||||
#define INCLUDED_DEBUGRENDERER
|
#define INCLUDED_DEBUGRENDERER
|
||||||
|
|
||||||
|
#include "graphics/ShaderTechniquePtr.h"
|
||||||
|
#include "ps/CStrIntern.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class CBoundingBoxAligned;
|
class CBoundingBoxAligned;
|
||||||
@ -64,6 +68,29 @@ public:
|
|||||||
* Render the surfaces of the brush as triangles.
|
* Render the surfaces of the brush as triangles.
|
||||||
*/
|
*/
|
||||||
void DrawBrush(const CBrush& brush, const CColor& color, bool wireframe = false);
|
void DrawBrush(const CBrush& brush, const CColor& color, bool wireframe = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CShaderTechniquePtr& GetShaderTechnique(
|
||||||
|
const CStrIntern name, const CColor& color, const bool depthTestEnabled = true,
|
||||||
|
const bool wireframe = false);
|
||||||
|
|
||||||
|
struct ShaderTechniqueKey
|
||||||
|
{
|
||||||
|
CStrIntern name;
|
||||||
|
bool transparent;
|
||||||
|
bool depthTestEnabled;
|
||||||
|
bool wireframe;
|
||||||
|
};
|
||||||
|
struct ShaderTechniqueKeyHash
|
||||||
|
{
|
||||||
|
size_t operator()(const ShaderTechniqueKey& key) const;
|
||||||
|
};
|
||||||
|
struct ShaderTechniqueKeyEqual
|
||||||
|
{
|
||||||
|
bool operator()(const ShaderTechniqueKey& lhs, const ShaderTechniqueKey& rhs) const;
|
||||||
|
};
|
||||||
|
std::unordered_map<ShaderTechniqueKey, CShaderTechniquePtr, ShaderTechniqueKeyHash, ShaderTechniqueKeyEqual>
|
||||||
|
m_ShaderTechniqueMapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDED_DEBUGRENDERER
|
#endif // INCLUDED_DEBUGRENDERER
|
||||||
|
@ -152,8 +152,9 @@ void CDecalRData::RenderDecals(
|
|||||||
|
|
||||||
CShaderDefines defines = contextDecal;
|
CShaderDefines defines = contextDecal;
|
||||||
defines.SetMany(itTechBegin->shaderDefines);
|
defines.SetMany(itTechBegin->shaderDefines);
|
||||||
|
// TODO: move enabling blend to XML.
|
||||||
CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect(
|
CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
itTechBegin->shaderEffect, defines);
|
itTechBegin->shaderEffect == str_terrain_base ? str_terrain_decal : itTechBegin->shaderEffect, defines);
|
||||||
if (!techBase)
|
if (!techBase)
|
||||||
{
|
{
|
||||||
LOGERROR("Terrain renderer failed to load shader effect (%s)\n",
|
LOGERROR("Terrain renderer failed to load shader effect (%s)\n",
|
||||||
@ -164,17 +165,8 @@ void CDecalRData::RenderDecals(
|
|||||||
const int numPasses = techBase->GetNumPasses();
|
const int numPasses = techBase->GetNumPasses();
|
||||||
for (int pass = 0; pass < numPasses; ++pass)
|
for (int pass = 0; pass < numPasses; ++pass)
|
||||||
{
|
{
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
techBase->GetGraphicsPipelineStateDesc(pass);
|
techBase->GetGraphicsPipelineState(pass));
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
pipelineStateDesc.depthStencilState.depthWriteEnabled = false;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = techBase->GetShader(pass);
|
Renderer::Backend::IShaderProgram* shader = techBase->GetShader(pass);
|
||||||
|
@ -615,7 +615,7 @@ void ShaderModelRenderer::Render(
|
|||||||
for (int pass = 0; pass < currentTech->GetNumPasses(); ++pass)
|
for (int pass = 0; pass < currentTech->GetNumPasses(); ++pass)
|
||||||
{
|
{
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
currentTech->GetGraphicsPipelineStateDesc(pass));
|
currentTech->GetGraphicsPipelineState(pass));
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = currentTech->GetShader(pass);
|
Renderer::Backend::IShaderProgram* shader = currentTech->GetShader(pass);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "ps/CStrInternStatic.h"
|
#include "ps/CStrInternStatic.h"
|
||||||
#include "ps/Game.h"
|
#include "ps/Game.h"
|
||||||
#include "ps/Profile.h"
|
#include "ps/Profile.h"
|
||||||
|
#include "renderer/backend/PipelineState.h"
|
||||||
#include "renderer/DebugRenderer.h"
|
#include "renderer/DebugRenderer.h"
|
||||||
#include "renderer/Renderer.h"
|
#include "renderer/Renderer.h"
|
||||||
#include "renderer/SceneRenderer.h"
|
#include "renderer/SceneRenderer.h"
|
||||||
@ -47,12 +48,50 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
CShaderTechniquePtr GetOverlayLineShaderTechnique(const CShaderDefines& defines)
|
struct Shader
|
||||||
{
|
{
|
||||||
return g_Renderer.GetShaderManager().LoadEffect(str_overlay_line, defines);
|
CShaderTechniquePtr technique, techniqueWireframe;
|
||||||
|
|
||||||
|
const CShaderTechniquePtr& GetTechnique() const
|
||||||
|
{
|
||||||
|
return g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME
|
||||||
|
? techniqueWireframe : technique;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void AdjustOverlayGraphicsPipelineState(Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
pipelineStateDesc.depthStencilState.depthWriteEnabled = false;
|
||||||
|
pipelineStateDesc.blendState.enabled = true;
|
||||||
|
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
||||||
|
Renderer::Backend::BlendOp::ADD;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
Shader CreateShader(
|
||||||
|
const CStrIntern name, const CShaderDefines& defines)
|
||||||
|
{
|
||||||
|
Shader shader;
|
||||||
|
|
||||||
|
shader.technique = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
name, defines,
|
||||||
|
[](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
AdjustOverlayGraphicsPipelineState(pipelineStateDesc);
|
||||||
|
});
|
||||||
|
shader.techniqueWireframe = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
name, defines,
|
||||||
|
[](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
AdjustOverlayGraphicsPipelineState(pipelineStateDesc);
|
||||||
|
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
||||||
|
});
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key used to group quads into batches for more efficient rendering. Currently groups by the combination
|
* Key used to group quads into batches for more efficient rendering. Currently groups by the combination
|
||||||
@ -104,12 +143,16 @@ public:
|
|||||||
size_t m_NumRenderQuads;
|
size_t m_NumRenderQuads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
struct OverlayRendererInternals
|
struct OverlayRendererInternals
|
||||||
{
|
{
|
||||||
using QuadBatchMap = std::unordered_map<QuadBatchKey, QuadBatchData, QuadBatchHash>;
|
using QuadBatchMap = std::unordered_map<QuadBatchKey, QuadBatchData, QuadBatchHash>;
|
||||||
|
|
||||||
OverlayRendererInternals();
|
OverlayRendererInternals();
|
||||||
~OverlayRendererInternals(){ }
|
~OverlayRendererInternals() = default;
|
||||||
|
|
||||||
|
Renderer::Backend::IDevice* device = nullptr;
|
||||||
|
|
||||||
std::vector<SOverlayLine*> lines;
|
std::vector<SOverlayLine*> lines;
|
||||||
std::vector<SOverlayTexturedLine*> texlines;
|
std::vector<SOverlayTexturedLine*> texlines;
|
||||||
@ -139,6 +182,12 @@ struct OverlayRendererInternals
|
|||||||
CShaderDefines defsOverlayLineAlwaysVisible;
|
CShaderDefines defsOverlayLineAlwaysVisible;
|
||||||
CShaderDefines defsQuadOverlay;
|
CShaderDefines defsQuadOverlay;
|
||||||
|
|
||||||
|
Shader shaderTexLineNormal;
|
||||||
|
Shader shaderTexLineAlwaysVisible;
|
||||||
|
Shader shaderQuadOverlay;
|
||||||
|
Shader shaderForegroundOverlay;
|
||||||
|
Shader shaderOverlaySolid;
|
||||||
|
|
||||||
// Geometry for a unit sphere
|
// Geometry for a unit sphere
|
||||||
std::vector<float> sphereVertexes;
|
std::vector<float> sphereVertexes;
|
||||||
std::vector<u16> sphereIndexes;
|
std::vector<u16> sphereIndexes;
|
||||||
@ -202,6 +251,17 @@ void OverlayRendererInternals::Initialize()
|
|||||||
}
|
}
|
||||||
quadIndices.Upload();
|
quadIndices.Upload();
|
||||||
quadIndices.FreeBackingStore();
|
quadIndices.FreeBackingStore();
|
||||||
|
|
||||||
|
shaderTexLineNormal =
|
||||||
|
CreateShader(str_overlay_line, defsOverlayLineNormal);
|
||||||
|
shaderTexLineAlwaysVisible =
|
||||||
|
CreateShader(str_overlay_line, defsOverlayLineAlwaysVisible);
|
||||||
|
shaderQuadOverlay =
|
||||||
|
CreateShader(str_overlay_line, defsQuadOverlay);
|
||||||
|
shaderForegroundOverlay =
|
||||||
|
CreateShader(str_foreground_overlay, {});
|
||||||
|
shaderOverlaySolid =
|
||||||
|
CreateShader(str_overlay_solid, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayRenderer::OverlayRenderer()
|
OverlayRenderer::OverlayRenderer()
|
||||||
@ -407,25 +467,14 @@ void OverlayRenderer::RenderTexturedOverlayLines(Renderer::Backend::IDeviceComma
|
|||||||
|
|
||||||
CLOSTexture& los = g_Renderer.GetSceneRenderer().GetScene().GetLOSTexture();
|
CLOSTexture& los = g_Renderer.GetSceneRenderer().GetScene().GetLOSTexture();
|
||||||
|
|
||||||
CShaderTechniquePtr shaderTechTexLineNormal = GetOverlayLineShaderTechnique(m->defsOverlayLineNormal);
|
if (m->shaderTexLineNormal.technique)
|
||||||
if (shaderTechTexLineNormal)
|
|
||||||
{
|
{
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
const CShaderTechniquePtr& shaderTechnique = m->shaderTexLineNormal.GetTechnique();
|
||||||
shaderTechTexLineNormal->GetGraphicsPipelineStateDesc();
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
pipelineStateDesc.depthStencilState.depthWriteEnabled = false;
|
shaderTechnique->GetGraphicsPipelineState());
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME)
|
|
||||||
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shaderTexLineNormal = shaderTechTexLineNormal->GetShader();
|
Renderer::Backend::IShaderProgram* shaderTexLineNormal = shaderTechnique->GetShader();
|
||||||
|
|
||||||
deviceCommandContext->SetTexture(
|
deviceCommandContext->SetTexture(
|
||||||
shaderTexLineNormal->GetBindingSlot(str_losTex), los.GetTexture());
|
shaderTexLineNormal->GetBindingSlot(str_losTex), los.GetTexture());
|
||||||
@ -444,25 +493,15 @@ void OverlayRenderer::RenderTexturedOverlayLines(Renderer::Backend::IDeviceComma
|
|||||||
deviceCommandContext->EndPass();
|
deviceCommandContext->EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
CShaderTechniquePtr shaderTechTexLineAlwaysVisible = GetOverlayLineShaderTechnique(m->defsOverlayLineAlwaysVisible);
|
if (m->shaderTexLineAlwaysVisible.technique)
|
||||||
if (shaderTechTexLineAlwaysVisible)
|
|
||||||
{
|
{
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
const CShaderTechniquePtr& shaderTechnique = m->shaderTexLineAlwaysVisible.GetTechnique();
|
||||||
shaderTechTexLineAlwaysVisible->GetGraphicsPipelineStateDesc();
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
pipelineStateDesc.depthStencilState.depthWriteEnabled = false;
|
shaderTechnique->GetGraphicsPipelineState());
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME)
|
|
||||||
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shaderTexLineAlwaysVisible = shaderTechTexLineAlwaysVisible->GetShader();
|
Renderer::Backend::IShaderProgram* shaderTexLineAlwaysVisible =
|
||||||
|
shaderTechnique->GetShader();
|
||||||
|
|
||||||
// TODO: losTex and losTransform are unused in the always visible shader; see if these can be safely omitted
|
// TODO: losTex and losTransform are unused in the always visible shader; see if these can be safely omitted
|
||||||
deviceCommandContext->SetTexture(
|
deviceCommandContext->SetTexture(
|
||||||
@ -506,27 +545,15 @@ void OverlayRenderer::RenderQuadOverlays(
|
|||||||
if (m->quadBatchMap.empty())
|
if (m->quadBatchMap.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CShaderTechniquePtr shaderTech = GetOverlayLineShaderTechnique(m->defsQuadOverlay);
|
if (!m->shaderQuadOverlay.technique)
|
||||||
|
|
||||||
if (!shaderTech)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
const CShaderTechniquePtr& shaderTechnique = m->shaderQuadOverlay.GetTechnique();
|
||||||
shaderTech->GetGraphicsPipelineStateDesc();
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
pipelineStateDesc.depthStencilState.depthWriteEnabled = false;
|
shaderTechnique->GetGraphicsPipelineState());
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME)
|
|
||||||
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = shaderTechnique->GetShader();
|
||||||
|
|
||||||
CLOSTexture& los = g_Renderer.GetSceneRenderer().GetScene().GetLOSTexture();
|
CLOSTexture& los = g_Renderer.GetSceneRenderer().GetScene().GetLOSTexture();
|
||||||
|
|
||||||
@ -601,23 +628,12 @@ void OverlayRenderer::RenderForegroundOverlays(
|
|||||||
const CVector3D right = -viewCamera.GetOrientation().GetLeft();
|
const CVector3D right = -viewCamera.GetOrientation().GetLeft();
|
||||||
const CVector3D up = viewCamera.GetOrientation().GetUp();
|
const CVector3D up = viewCamera.GetOrientation().GetUp();
|
||||||
|
|
||||||
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_foreground_overlay);
|
const CShaderTechniquePtr& shaderTechnique = m->shaderForegroundOverlay.GetTechnique();
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc();
|
shaderTechnique->GetGraphicsPipelineState());
|
||||||
pipelineStateDesc.depthStencilState.depthTestEnabled = false;
|
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
if (g_Renderer.GetSceneRenderer().GetOverlayRenderMode() == WIREFRAME)
|
|
||||||
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = shaderTechnique->GetShader();
|
||||||
|
|
||||||
const CMatrix3D transform =
|
const CMatrix3D transform =
|
||||||
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
||||||
@ -750,27 +766,15 @@ void OverlayRenderer::RenderSphereOverlays(
|
|||||||
{
|
{
|
||||||
PROFILE3_GPU("overlays (spheres)");
|
PROFILE3_GPU("overlays (spheres)");
|
||||||
|
|
||||||
if (m->spheres.empty())
|
if (m->spheres.empty() || m->shaderOverlaySolid.technique)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = nullptr;
|
const CShaderTechniquePtr& shaderTechnique = m->shaderOverlaySolid.GetTechnique();
|
||||||
CShaderTechniquePtr tech;
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
|
shaderTechnique->GetGraphicsPipelineState());
|
||||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_overlay_solid);
|
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
|
||||||
tech->GetGraphicsPipelineStateDesc();
|
|
||||||
pipelineStateDesc.depthStencilState.depthWriteEnabled = false;
|
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
shader = tech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = shaderTechnique->GetShader();
|
||||||
|
|
||||||
const CMatrix3D transform =
|
const CMatrix3D transform =
|
||||||
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
||||||
|
@ -135,7 +135,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Helper method; renders all overlay lines currently registered in the internals. Batch-
|
* Helper method; renders all overlay lines currently registered in the internals. Batch-
|
||||||
* renders textured overlay lines batched according to their visibility status by delegating
|
* renders textured overlay lines batched according to their visibility status by delegating
|
||||||
* to RenderTexturedOverlayLines(CShaderProgramPtr, bool).
|
* to RenderTexturedOverlayLines(IShaderProgram, bool).
|
||||||
*/
|
*/
|
||||||
void RenderTexturedOverlayLines(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
|
void RenderTexturedOverlayLines(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ void ParticleRenderer::RenderParticles(
|
|||||||
if (lastTech)
|
if (lastTech)
|
||||||
deviceCommandContext->EndPass();
|
deviceCommandContext->EndPass();
|
||||||
lastTech = currentTech;
|
lastTech = currentTech;
|
||||||
deviceCommandContext->SetGraphicsPipelineState(lastTech->GetGraphicsPipelineStateDesc());
|
deviceCommandContext->SetGraphicsPipelineState(lastTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = lastTech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = lastTech->GetShader();
|
||||||
|
@ -772,7 +772,7 @@ void CPatchRData::RenderBases(
|
|||||||
for (int pass = 0; pass < numPasses; ++pass)
|
for (int pass = 0; pass < numPasses; ++pass)
|
||||||
{
|
{
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
techBase->GetGraphicsPipelineStateDesc(pass));
|
techBase->GetGraphicsPipelineState(pass));
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = techBase->GetShader(pass);
|
Renderer::Backend::IShaderProgram* shader = techBase->GetShader(pass);
|
||||||
TerrainRenderer::PrepareShader(deviceCommandContext, shader, shadow);
|
TerrainRenderer::PrepareShader(deviceCommandContext, shader, shadow);
|
||||||
@ -978,8 +978,12 @@ void CPatchRData::RenderBlends(
|
|||||||
{
|
{
|
||||||
CShaderDefines defines = contextBlend;
|
CShaderDefines defines = contextBlend;
|
||||||
defines.SetMany(bestTex->GetMaterial().GetShaderDefines());
|
defines.SetMany(bestTex->GetMaterial().GetShaderDefines());
|
||||||
|
// TODO: move enabling blend to XML.
|
||||||
|
const CStrIntern shaderEffect = bestTex->GetMaterial().GetShaderEffect();
|
||||||
|
if (shaderEffect != str_terrain_base)
|
||||||
|
ONCE(LOGWARNING("Shader effect '%s' doesn't support semi-transparent terrain rendering.", shaderEffect.c_str()));
|
||||||
layer.m_ShaderTech = g_Renderer.GetShaderManager().LoadEffect(
|
layer.m_ShaderTech = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
bestTex->GetMaterial().GetShaderEffect(), defines);
|
shaderEffect == str_terrain_base ? str_terrain_blend : shaderEffect, defines);
|
||||||
}
|
}
|
||||||
batches.push_back(layer);
|
batches.push_back(layer);
|
||||||
}
|
}
|
||||||
@ -997,16 +1001,8 @@ void CPatchRData::RenderBlends(
|
|||||||
const int numPasses = techBase->GetNumPasses();
|
const int numPasses = techBase->GetNumPasses();
|
||||||
for (int pass = 0; pass < numPasses; ++pass)
|
for (int pass = 0; pass < numPasses; ++pass)
|
||||||
{
|
{
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
techBase->GetGraphicsPipelineStateDesc(pass);
|
techBase->GetGraphicsPipelineState(pass));
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = techBase->GetShader(pass);
|
Renderer::Backend::IShaderProgram* shader = techBase->GetShader(pass);
|
||||||
|
@ -230,7 +230,7 @@ void CPostprocManager::ApplyBlurDownscale2x(
|
|||||||
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, defines);
|
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, defines);
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc());
|
tech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ void CPostprocManager::ApplyBlurGauss(
|
|||||||
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, defines2);
|
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, defines2);
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc());
|
tech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
||||||
deviceCommandContext->SetTexture(
|
deviceCommandContext->SetTexture(
|
||||||
@ -357,7 +357,7 @@ void CPostprocManager::ApplyBlurGauss(
|
|||||||
defines3.Add(str_BLOOM_PASS_V, str_1);
|
defines3.Add(str_BLOOM_PASS_V, str_1);
|
||||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, defines3);
|
tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, defines3);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc());
|
tech->GetGraphicsPipelineState());
|
||||||
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
shader = tech->GetShader();
|
shader = tech->GetShader();
|
||||||
@ -445,7 +445,7 @@ void CPostprocManager::ApplyEffect(
|
|||||||
deviceCommandContext->SetViewports(1, &viewportRect);
|
deviceCommandContext->SetViewports(1, &viewportRect);
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
shaderTech->GetGraphicsPipelineStateDesc(pass));
|
shaderTech->GetGraphicsPipelineState(pass));
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader(pass);
|
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader(pass);
|
||||||
|
|
||||||
|
@ -457,9 +457,6 @@ void CRenderer::RenderFrameImpl(const bool renderGUI, const bool renderLogger)
|
|||||||
{
|
{
|
||||||
g_Game->GetView()->Prepare(m->deviceCommandContext.get());
|
g_Game->GetView()->Prepare(m->deviceCommandContext.get());
|
||||||
|
|
||||||
m->deviceCommandContext->SetGraphicsPipelineState(
|
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc());
|
|
||||||
|
|
||||||
Renderer::Backend::IFramebuffer* framebuffer = nullptr;
|
Renderer::Backend::IFramebuffer* framebuffer = nullptr;
|
||||||
|
|
||||||
CPostprocManager& postprocManager = g_Renderer.GetPostprocManager();
|
CPostprocManager& postprocManager = g_Renderer.GetPostprocManager();
|
||||||
|
@ -575,8 +575,6 @@ void CSceneRenderer::RenderReflections(
|
|||||||
screenScissor.x2 = static_cast<int>(ceil((reflectionScissor[1].X * 0.5f + 0.5f) * vpWidth));
|
screenScissor.x2 = static_cast<int>(ceil((reflectionScissor[1].X * 0.5f + 0.5f) * vpWidth));
|
||||||
screenScissor.y2 = static_cast<int>(ceil((reflectionScissor[1].Y * 0.5f + 0.5f) * vpHeight));
|
screenScissor.y2 = static_cast<int>(ceil((reflectionScissor[1].Y * 0.5f + 0.5f) * vpHeight));
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc());
|
|
||||||
deviceCommandContext->BeginFramebufferPass(wm.m_ReflectionFramebuffer.get());
|
deviceCommandContext->BeginFramebufferPass(wm.m_ReflectionFramebuffer.get());
|
||||||
|
|
||||||
Renderer::Backend::IDeviceCommandContext::Rect viewportRect{};
|
Renderer::Backend::IDeviceCommandContext::Rect viewportRect{};
|
||||||
@ -652,8 +650,6 @@ void CSceneRenderer::RenderRefractions(
|
|||||||
screenScissor.x2 = static_cast<int>(ceil((refractionScissor[1].X * 0.5f + 0.5f) * vpWidth));
|
screenScissor.x2 = static_cast<int>(ceil((refractionScissor[1].X * 0.5f + 0.5f) * vpWidth));
|
||||||
screenScissor.y2 = static_cast<int>(ceil((refractionScissor[1].Y * 0.5f + 0.5f) * vpHeight));
|
screenScissor.y2 = static_cast<int>(ceil((refractionScissor[1].Y * 0.5f + 0.5f) * vpHeight));
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc());
|
|
||||||
deviceCommandContext->BeginFramebufferPass(wm.m_RefractionFramebuffer.get());
|
deviceCommandContext->BeginFramebufferPass(wm.m_RefractionFramebuffer.get());
|
||||||
|
|
||||||
Renderer::Backend::IDeviceCommandContext::Rect viewportRect{};
|
Renderer::Backend::IDeviceCommandContext::Rect viewportRect{};
|
||||||
@ -704,8 +700,6 @@ void CSceneRenderer::RenderSilhouettes(
|
|||||||
// inverted depth test so any behind an occluder will get drawn in a constant
|
// inverted depth test so any behind an occluder will get drawn in a constant
|
||||||
// color.
|
// color.
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc());
|
|
||||||
deviceCommandContext->ClearFramebuffer(false, true, true);
|
deviceCommandContext->ClearFramebuffer(false, true, true);
|
||||||
|
|
||||||
// Render occluders:
|
// Render occluders:
|
||||||
|
@ -586,9 +586,6 @@ void ShadowMapInternals::CreateTexture()
|
|||||||
void ShadowMap::BeginRender(
|
void ShadowMap::BeginRender(
|
||||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
|
Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
|
||||||
{
|
{
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc());
|
|
||||||
|
|
||||||
ENSURE(m->Framebuffer);
|
ENSURE(m->Framebuffer);
|
||||||
deviceCommandContext->BeginFramebufferPass(m->Framebuffer.get());
|
deviceCommandContext->BeginFramebufferPass(m->Framebuffer.get());
|
||||||
|
|
||||||
|
@ -469,15 +469,22 @@ void SilhouetteRenderer::RenderDebugOverlays(
|
|||||||
proj.SetOrtho(0.f, g_MaxCoord, 0.f, g_MaxCoord, -1.f, 1000.f);
|
proj.SetOrtho(0.f, g_MaxCoord, 0.f, g_MaxCoord, -1.f, 1000.f);
|
||||||
m = proj * m;
|
m = proj * m;
|
||||||
|
|
||||||
CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
if (!m_ShaderTech)
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
{
|
||||||
shaderTech->GetGraphicsPipelineStateDesc();
|
m_ShaderTech = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
deviceCommandContext->BeginPass();
|
str_solid, {},
|
||||||
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
[](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
{
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
||||||
|
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shader = shaderTech->GetShader();
|
deviceCommandContext->BeginPass();
|
||||||
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
|
m_ShaderTech->GetGraphicsPipelineState());
|
||||||
|
|
||||||
|
Renderer::Backend::IShaderProgram* shader = m_ShaderTech->GetShader();
|
||||||
deviceCommandContext->SetUniform(
|
deviceCommandContext->SetUniform(
|
||||||
shader->GetBindingSlot(str_transform), proj.AsFloatArray());
|
shader->GetBindingSlot(str_transform), proj.AsFloatArray());
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define INCLUDED_SILHOUETTERENDERER
|
#define INCLUDED_SILHOUETTERENDERER
|
||||||
|
|
||||||
#include "graphics/Overlay.h"
|
#include "graphics/Overlay.h"
|
||||||
|
#include "graphics/ShaderTechniquePtr.h"
|
||||||
#include "maths/BoundingBoxAligned.h"
|
#include "maths/BoundingBoxAligned.h"
|
||||||
#include "renderer/backend/IDeviceCommandContext.h"
|
#include "renderer/backend/IDeviceCommandContext.h"
|
||||||
|
|
||||||
@ -75,6 +76,8 @@ private:
|
|||||||
std::vector<DebugRect> m_DebugRects;
|
std::vector<DebugRect> m_DebugRects;
|
||||||
|
|
||||||
std::vector<SOverlaySphere> m_DebugSpheres;
|
std::vector<SOverlaySphere> m_DebugSpheres;
|
||||||
|
|
||||||
|
CShaderTechniquePtr m_ShaderTech;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDED_SILHOUETTERENDERER
|
#endif // INCLUDED_SILHOUETTERENDERER
|
||||||
|
@ -222,7 +222,7 @@ void SkyManager::RenderSky(
|
|||||||
CShaderTechniquePtr skytech =
|
CShaderTechniquePtr skytech =
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_sky_simple);
|
g_Renderer.GetShaderManager().LoadEffect(str_sky_simple);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
skytech->GetGraphicsPipelineStateDesc());
|
skytech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = skytech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = skytech->GetShader();
|
||||||
deviceCommandContext->SetTexture(
|
deviceCommandContext->SetTexture(
|
||||||
|
@ -39,9 +39,55 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// Global overlay list management:
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
static std::vector<std::pair<ITerrainOverlay*, int> > g_TerrainOverlayList;
|
// Global overlay list management:
|
||||||
|
std::vector<std::pair<ITerrainOverlay*, int>> g_TerrainOverlayList;
|
||||||
|
|
||||||
|
void AdjustOverlayGraphicsPipelineState(
|
||||||
|
Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc, const bool drawHidden)
|
||||||
|
{
|
||||||
|
pipelineStateDesc.depthStencilState.depthTestEnabled = !drawHidden;
|
||||||
|
pipelineStateDesc.blendState.enabled = true;
|
||||||
|
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
||||||
|
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||||
|
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
||||||
|
Renderer::Backend::BlendOp::ADD;
|
||||||
|
pipelineStateDesc.rasterizationState.cullMode =
|
||||||
|
drawHidden ? Renderer::Backend::CullMode::NONE : Renderer::Backend::CullMode::BACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
CShaderTechniquePtr CreateOverlayTileShaderTechnique(const bool drawHidden)
|
||||||
|
{
|
||||||
|
return g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
str_debug_line, {},
|
||||||
|
[drawHidden](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
AdjustOverlayGraphicsPipelineState(pipelineStateDesc, drawHidden);
|
||||||
|
// To ensure that outlines are drawn on top of the terrain correctly (and
|
||||||
|
// don't Z-fight and flicker nastily), use detph bias to pull them towards
|
||||||
|
// the camera.
|
||||||
|
pipelineStateDesc.rasterizationState.depthBiasEnabled = true;
|
||||||
|
pipelineStateDesc.rasterizationState.depthBiasConstantFactor = -1.0f;
|
||||||
|
pipelineStateDesc.rasterizationState.depthBiasSlopeFactor = -1.0f;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CShaderTechniquePtr CreateOverlayOutlineShaderTechnique(const bool drawHidden)
|
||||||
|
{
|
||||||
|
return g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
str_debug_line, {},
|
||||||
|
[drawHidden](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
AdjustOverlayGraphicsPipelineState(pipelineStateDesc, drawHidden);
|
||||||
|
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
ITerrainOverlay::ITerrainOverlay(int priority)
|
ITerrainOverlay::ITerrainOverlay(int priority)
|
||||||
{
|
{
|
||||||
@ -93,9 +139,15 @@ void ITerrainOverlay::RenderOverlaysAfterWater(
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TerrainOverlay::TerrainOverlay(const CSimContext& simContext, int priority /* = 100 */)
|
TerrainOverlay::TerrainOverlay(
|
||||||
|
const CSimContext& simContext, int priority /* = 100 */)
|
||||||
: ITerrainOverlay(priority), m_Terrain(&simContext.GetTerrain())
|
: ITerrainOverlay(priority), m_Terrain(&simContext.GetTerrain())
|
||||||
{
|
{
|
||||||
|
m_OverlayTechTile = CreateOverlayTileShaderTechnique(false);
|
||||||
|
m_OverlayTechTileHidden = CreateOverlayTileShaderTechnique(true);
|
||||||
|
|
||||||
|
m_OverlayTechOutline = CreateOverlayOutlineShaderTechnique(false);
|
||||||
|
m_OverlayTechOutlineHidden = CreateOverlayOutlineShaderTechnique(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerrainOverlay::StartRender()
|
void TerrainOverlay::StartRender()
|
||||||
@ -188,30 +240,12 @@ void TerrainOverlay::RenderTile(
|
|||||||
}
|
}
|
||||||
#undef ADD
|
#undef ADD
|
||||||
|
|
||||||
CShaderTechniquePtr overlayTech =
|
const CShaderTechniquePtr& shaderTechnique = drawHidden ? m_OverlayTechTileHidden : m_OverlayTechTile;
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
shaderTechnique->GetGraphicsPipelineState());
|
||||||
overlayTech->GetGraphicsPipelineStateDesc();
|
|
||||||
pipelineStateDesc.depthStencilState.depthTestEnabled = !drawHidden;
|
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
pipelineStateDesc.rasterizationState.cullMode =
|
|
||||||
drawHidden ? Renderer::Backend::CullMode::NONE : Renderer::Backend::CullMode::BACK;
|
|
||||||
// To ensure that outlines are drawn on top of the terrain correctly (and
|
|
||||||
// don't Z-fight and flicker nastily), use detph bias to pull them towards
|
|
||||||
// the camera.
|
|
||||||
pipelineStateDesc.rasterizationState.depthBiasEnabled = true;
|
|
||||||
pipelineStateDesc.rasterizationState.depthBiasConstantFactor = -1.0f;
|
|
||||||
pipelineStateDesc.rasterizationState.depthBiasSlopeFactor = -1.0f;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* overlayShader = overlayTech->GetShader();
|
Renderer::Backend::IShaderProgram* overlayShader = shaderTechnique->GetShader();
|
||||||
|
|
||||||
const CMatrix3D transform =
|
const CMatrix3D transform =
|
||||||
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
||||||
@ -260,25 +294,12 @@ void TerrainOverlay::RenderTileOutline(
|
|||||||
ADD(i, j + 1);
|
ADD(i, j + 1);
|
||||||
#undef ADD
|
#undef ADD
|
||||||
|
|
||||||
CShaderTechniquePtr overlayTech =
|
const CShaderTechniquePtr& shaderTechnique = drawHidden ? m_OverlayTechOutlineHidden : m_OverlayTechOutline;
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
shaderTechnique->GetGraphicsPipelineState());
|
||||||
overlayTech->GetGraphicsPipelineStateDesc();
|
|
||||||
pipelineStateDesc.depthStencilState.depthTestEnabled = !drawHidden;
|
|
||||||
pipelineStateDesc.blendState.enabled = true;
|
|
||||||
pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor =
|
|
||||||
Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
|
||||||
pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp =
|
|
||||||
Renderer::Backend::BlendOp::ADD;
|
|
||||||
pipelineStateDesc.rasterizationState.cullMode =
|
|
||||||
drawHidden ? Renderer::Backend::CullMode::NONE : Renderer::Backend::CullMode::BACK;
|
|
||||||
pipelineStateDesc.rasterizationState.polygonMode = Renderer::Backend::PolygonMode::LINE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* overlayShader = overlayTech->GetShader();
|
Renderer::Backend::IShaderProgram* overlayShader = shaderTechnique->GetShader();
|
||||||
|
|
||||||
const CMatrix3D transform =
|
const CMatrix3D transform =
|
||||||
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
||||||
|
@ -23,8 +23,10 @@
|
|||||||
#ifndef INCLUDED_TERRAINOVERLAY
|
#ifndef INCLUDED_TERRAINOVERLAY
|
||||||
#define INCLUDED_TERRAINOVERLAY
|
#define INCLUDED_TERRAINOVERLAY
|
||||||
|
|
||||||
|
#include "graphics/ShaderTechniquePtr.h"
|
||||||
#include "renderer/backend/ITexture.h"
|
#include "renderer/backend/ITexture.h"
|
||||||
#include "renderer/backend/IDeviceCommandContext.h"
|
#include "renderer/backend/IDeviceCommandContext.h"
|
||||||
|
#include "renderer/backend/PipelineState.h"
|
||||||
|
|
||||||
struct CColor;
|
struct CColor;
|
||||||
struct SColor4ub;
|
struct SColor4ub;
|
||||||
@ -179,6 +181,9 @@ private:
|
|||||||
ssize_t m_i, m_j;
|
ssize_t m_i, m_j;
|
||||||
|
|
||||||
CTerrain* m_Terrain;
|
CTerrain* m_Terrain;
|
||||||
|
|
||||||
|
CShaderTechniquePtr m_OverlayTechTile, m_OverlayTechTileHidden;
|
||||||
|
CShaderTechniquePtr m_OverlayTechOutline, m_OverlayTechOutlineHidden;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "ps/Profile.h"
|
#include "ps/Profile.h"
|
||||||
#include "ps/World.h"
|
#include "ps/World.h"
|
||||||
#include "renderer/backend/IDevice.h"
|
#include "renderer/backend/IDevice.h"
|
||||||
|
#include "renderer/backend/PipelineState.h"
|
||||||
#include "renderer/DecalRData.h"
|
#include "renderer/DecalRData.h"
|
||||||
#include "renderer/PatchRData.h"
|
#include "renderer/PatchRData.h"
|
||||||
#include "renderer/Renderer.h"
|
#include "renderer/Renderer.h"
|
||||||
@ -50,6 +51,8 @@
|
|||||||
#include "renderer/VertexArray.h"
|
#include "renderer/VertexArray.h"
|
||||||
#include "renderer/WaterManager.h"
|
#include "renderer/WaterManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TerrainRenderer keeps track of which phase it is in, to detect
|
* TerrainRenderer keeps track of which phase it is in, to detect
|
||||||
* when Submit, PrepareForRendering etc. are called in the wrong order.
|
* when Submit, PrepareForRendering etc. are called in the wrong order.
|
||||||
@ -78,6 +81,8 @@ struct TerrainRendererInternals
|
|||||||
/// Fancy water shader
|
/// Fancy water shader
|
||||||
CShaderTechniquePtr fancyWaterTech;
|
CShaderTechniquePtr fancyWaterTech;
|
||||||
|
|
||||||
|
CShaderTechniquePtr shaderTechniqueSolid, shaderTechniqueSolidDepthTest;
|
||||||
|
|
||||||
CSimulation2* simulation;
|
CSimulation2* simulation;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -173,7 +178,7 @@ void TerrainRenderer::RenderTerrainOverlayTexture(
|
|||||||
CShaderTechniquePtr debugOverlayTech =
|
CShaderTechniquePtr debugOverlayTech =
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_debug_overlay);
|
g_Renderer.GetShaderManager().LoadEffect(str_debug_overlay);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
debugOverlayTech->GetGraphicsPipelineStateDesc());
|
debugOverlayTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* debugOverlayShader = debugOverlayTech->GetShader();
|
Renderer::Backend::IShaderProgram* debugOverlayShader = debugOverlayTech->GetShader();
|
||||||
|
|
||||||
@ -284,15 +289,22 @@ void TerrainRenderer::RenderTerrainShader(
|
|||||||
if (visiblePatches.empty() && visibleDecals.empty())
|
if (visiblePatches.empty() && visibleDecals.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!m->shaderTechniqueSolid)
|
||||||
|
{
|
||||||
|
m->shaderTechniqueSolid = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
str_solid, {},
|
||||||
|
[](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// render the solid black sides of the map first
|
// render the solid black sides of the map first
|
||||||
CShaderTechniquePtr techSolid = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc solidPipelineStateDesc =
|
m->shaderTechniqueSolid->GetGraphicsPipelineState());
|
||||||
techSolid->GetGraphicsPipelineStateDesc();
|
|
||||||
solidPipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(solidPipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* shaderSolid = techSolid->GetShader();
|
Renderer::Backend::IShaderProgram* shaderSolid = m->shaderTechniqueSolid->GetShader();
|
||||||
const CMatrix3D transform =
|
const CMatrix3D transform =
|
||||||
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
g_Renderer.GetSceneRenderer().GetViewCamera().GetViewProjection();
|
||||||
deviceCommandContext->SetUniform(
|
deviceCommandContext->SetUniform(
|
||||||
@ -328,7 +340,7 @@ void TerrainRenderer::RenderPatches(
|
|||||||
|
|
||||||
CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_terrain_solid, defines);
|
CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_terrain_solid, defines);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
solidTech->GetGraphicsPipelineStateDesc());
|
solidTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* solidShader = solidTech->GetShader();
|
Renderer::Backend::IShaderProgram* solidShader = solidTech->GetShader();
|
||||||
@ -436,7 +448,7 @@ bool TerrainRenderer::RenderFancyWater(
|
|||||||
const float repeatPeriod = waterManager.m_RepeatPeriod;
|
const float repeatPeriod = waterManager.m_RepeatPeriod;
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
m->fancyWaterTech->GetGraphicsPipelineStateDesc());
|
m->fancyWaterTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* fancyWaterShader = m->fancyWaterTech->GetShader();
|
Renderer::Backend::IShaderProgram* fancyWaterShader = m->fancyWaterTech->GetShader();
|
||||||
|
|
||||||
@ -622,7 +634,7 @@ void TerrainRenderer::RenderSimpleWater(
|
|||||||
CShaderTechniquePtr waterSimpleTech =
|
CShaderTechniquePtr waterSimpleTech =
|
||||||
g_Renderer.GetShaderManager().LoadEffect(str_water_simple, context);
|
g_Renderer.GetShaderManager().LoadEffect(str_water_simple, context);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
waterSimpleTech->GetGraphicsPipelineStateDesc());
|
waterSimpleTech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* waterSimpleShader = waterSimpleTech->GetShader();
|
Renderer::Backend::IShaderProgram* waterSimpleShader = waterSimpleTech->GetShader();
|
||||||
|
|
||||||
@ -680,21 +692,28 @@ void TerrainRenderer::RenderWaterFoamOccluders(
|
|||||||
if (!waterManager.WillRenderFancyWater())
|
if (!waterManager.WillRenderFancyWater())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!m->shaderTechniqueSolidDepthTest)
|
||||||
|
{
|
||||||
|
m->shaderTechniqueSolidDepthTest = g_Renderer.GetShaderManager().LoadEffect(
|
||||||
|
str_solid, {},
|
||||||
|
[](Renderer::Backend::SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
pipelineStateDesc.depthStencilState.depthTestEnabled = true;
|
||||||
|
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
GPU_SCOPED_LABEL(deviceCommandContext, "Render water foam occluders");
|
GPU_SCOPED_LABEL(deviceCommandContext, "Render water foam occluders");
|
||||||
|
|
||||||
// Render normals and foam to a framebuffer if we're using fancy effects.
|
// Render normals and foam to a framebuffer if we're using fancy effects.
|
||||||
deviceCommandContext->BeginFramebufferPass(waterManager.m_FancyEffectsFramebuffer.get());
|
deviceCommandContext->BeginFramebufferPass(waterManager.m_FancyEffectsFramebuffer.get());
|
||||||
|
|
||||||
// Overwrite waves that would be behind the ground.
|
// Overwrite waves that would be behind the ground.
|
||||||
CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
m->shaderTechniqueSolidDepthTest->GetGraphicsPipelineState());
|
||||||
dummyTech->GetGraphicsPipelineStateDesc();
|
|
||||||
pipelineStateDesc.depthStencilState.depthTestEnabled = true;
|
|
||||||
pipelineStateDesc.rasterizationState.cullMode = Renderer::Backend::CullMode::NONE;
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
|
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
|
|
||||||
Renderer::Backend::IShaderProgram* dummyShader = dummyTech->GetShader();
|
Renderer::Backend::IShaderProgram* dummyShader = m->shaderTechniqueSolidDepthTest->GetShader();
|
||||||
|
|
||||||
const CMatrix3D transform = sceneRenderer.GetViewCamera().GetViewProjection();
|
const CMatrix3D transform = sceneRenderer.GetViewCamera().GetViewProjection();
|
||||||
deviceCommandContext->SetUniform(
|
deviceCommandContext->SetUniform(
|
||||||
|
@ -840,13 +840,11 @@ void WaterManager::RenderWaves(
|
|||||||
|
|
||||||
GPU_SCOPED_LABEL(deviceCommandContext, "Render Waves");
|
GPU_SCOPED_LABEL(deviceCommandContext, "Render Waves");
|
||||||
|
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
|
||||||
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc());
|
|
||||||
deviceCommandContext->BeginFramebufferPass(m_FancyEffectsFramebuffer.get());
|
deviceCommandContext->BeginFramebufferPass(m_FancyEffectsFramebuffer.get());
|
||||||
|
|
||||||
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_water_waves);
|
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_water_waves);
|
||||||
deviceCommandContext->SetGraphicsPipelineState(
|
deviceCommandContext->SetGraphicsPipelineState(
|
||||||
tech->GetGraphicsPipelineStateDesc());
|
tech->GetGraphicsPipelineState());
|
||||||
deviceCommandContext->BeginPass();
|
deviceCommandContext->BeginPass();
|
||||||
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
Renderer::Backend::IShaderProgram* shader = tech->GetShader();
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "renderer/backend/IFramebuffer.h"
|
#include "renderer/backend/IFramebuffer.h"
|
||||||
#include "renderer/backend/IShaderProgram.h"
|
#include "renderer/backend/IShaderProgram.h"
|
||||||
#include "renderer/backend/ITexture.h"
|
#include "renderer/backend/ITexture.h"
|
||||||
|
#include "renderer/backend/PipelineState.h"
|
||||||
#include "scriptinterface/ScriptForward.h"
|
#include "scriptinterface/ScriptForward.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -74,6 +75,13 @@ public:
|
|||||||
|
|
||||||
virtual std::unique_ptr<IDeviceCommandContext> CreateCommandContext() = 0;
|
virtual std::unique_ptr<IDeviceCommandContext> CreateCommandContext() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a graphics pipeline state. It's a caller responsibility to
|
||||||
|
* guarantee a lifespan of IShaderProgram stored in the description.
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<IGraphicsPipelineState> CreateGraphicsPipelineState(
|
||||||
|
const SGraphicsPipelineStateDesc& pipelineStateDesc) = 0;
|
||||||
|
|
||||||
virtual std::unique_ptr<ITexture> CreateTexture(
|
virtual std::unique_ptr<ITexture> CreateTexture(
|
||||||
const char* name, const ITexture::Type type, const uint32_t usage,
|
const char* name, const ITexture::Type type, const uint32_t usage,
|
||||||
const Format format, const uint32_t width, const uint32_t height,
|
const Format format, const uint32_t width, const uint32_t height,
|
||||||
|
@ -40,7 +40,7 @@ class ITexture;
|
|||||||
class IDeviceCommandContext : public IDeviceObject<IDeviceCommandContext>
|
class IDeviceCommandContext : public IDeviceObject<IDeviceCommandContext>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void SetGraphicsPipelineState(const GraphicsPipelineStateDesc& pipelineStateDesc) = 0;
|
virtual void SetGraphicsPipelineState(IGraphicsPipelineState* pipelineState) = 0;
|
||||||
|
|
||||||
virtual void BlitFramebuffer(
|
virtual void BlitFramebuffer(
|
||||||
IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) = 0;
|
IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) = 0;
|
||||||
|
@ -27,9 +27,9 @@ namespace Renderer
|
|||||||
namespace Backend
|
namespace Backend
|
||||||
{
|
{
|
||||||
|
|
||||||
GraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc()
|
SGraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc()
|
||||||
{
|
{
|
||||||
GraphicsPipelineStateDesc desc{};
|
SGraphicsPipelineStateDesc desc{};
|
||||||
|
|
||||||
desc.shaderProgram = nullptr;
|
desc.shaderProgram = nullptr;
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "graphics/Color.h"
|
#include "graphics/Color.h"
|
||||||
#include "renderer/backend/CompareOp.h"
|
#include "renderer/backend/CompareOp.h"
|
||||||
|
#include "renderer/backend/IDeviceObject.h"
|
||||||
#include "renderer/backend/IShaderProgram.h"
|
#include "renderer/backend/IShaderProgram.h"
|
||||||
|
|
||||||
class CStr;
|
class CStr;
|
||||||
@ -53,7 +54,7 @@ enum class StencilOp
|
|||||||
DECREMENT_AND_WRAP
|
DECREMENT_AND_WRAP
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StencilOpState
|
struct SStencilOpState
|
||||||
{
|
{
|
||||||
StencilOp failOp;
|
StencilOp failOp;
|
||||||
StencilOp passOp;
|
StencilOp passOp;
|
||||||
@ -61,7 +62,7 @@ struct StencilOpState
|
|||||||
CompareOp compareOp;
|
CompareOp compareOp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DepthStencilStateDesc
|
struct SDepthStencilStateDesc
|
||||||
{
|
{
|
||||||
bool depthTestEnabled;
|
bool depthTestEnabled;
|
||||||
CompareOp depthCompareOp;
|
CompareOp depthCompareOp;
|
||||||
@ -70,8 +71,8 @@ struct DepthStencilStateDesc
|
|||||||
uint32_t stencilReadMask;
|
uint32_t stencilReadMask;
|
||||||
uint32_t stencilWriteMask;
|
uint32_t stencilWriteMask;
|
||||||
uint32_t stencilReference;
|
uint32_t stencilReference;
|
||||||
StencilOpState stencilFrontFace;
|
SStencilOpState stencilFrontFace;
|
||||||
StencilOpState stencilBackFace;
|
SStencilOpState stencilBackFace;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: add per constant description.
|
// TODO: add per constant description.
|
||||||
@ -118,7 +119,7 @@ constexpr uint8_t BLUE = 0x04;
|
|||||||
constexpr uint8_t ALPHA = 0x08;
|
constexpr uint8_t ALPHA = 0x08;
|
||||||
} // namespace ColorWriteMask
|
} // namespace ColorWriteMask
|
||||||
|
|
||||||
struct BlendStateDesc
|
struct SBlendStateDesc
|
||||||
{
|
{
|
||||||
bool enabled;
|
bool enabled;
|
||||||
BlendFactor srcColorBlendFactor;
|
BlendFactor srcColorBlendFactor;
|
||||||
@ -150,7 +151,7 @@ enum class FrontFace
|
|||||||
CLOCKWISE
|
CLOCKWISE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RasterizationStateDesc
|
struct SRasterizationStateDesc
|
||||||
{
|
{
|
||||||
PolygonMode polygonMode;
|
PolygonMode polygonMode;
|
||||||
CullMode cullMode;
|
CullMode cullMode;
|
||||||
@ -160,19 +161,19 @@ struct RasterizationStateDesc
|
|||||||
float depthBiasSlopeFactor;
|
float depthBiasSlopeFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GraphicsPipelineStateDesc
|
struct SGraphicsPipelineStateDesc
|
||||||
{
|
{
|
||||||
// It's a backend client reponsibility to keep the shader program alive
|
// It's a backend client reponsibility to keep the shader program alive
|
||||||
// while it's bound.
|
// while it's bound.
|
||||||
IShaderProgram* shaderProgram;
|
IShaderProgram* shaderProgram;
|
||||||
DepthStencilStateDesc depthStencilState;
|
SDepthStencilStateDesc depthStencilState;
|
||||||
BlendStateDesc blendState;
|
SBlendStateDesc blendState;
|
||||||
RasterizationStateDesc rasterizationState;
|
SRasterizationStateDesc rasterizationState;
|
||||||
};
|
};
|
||||||
|
|
||||||
// We don't provide additional helpers intentionally because all custom states
|
// We don't provide additional helpers intentionally because all custom states
|
||||||
// should be described with a related shader and should be switched together.
|
// should be described with a related shader and should be switched together.
|
||||||
GraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc();
|
SGraphicsPipelineStateDesc MakeDefaultGraphicsPipelineStateDesc();
|
||||||
|
|
||||||
StencilOp ParseStencilOp(const CStr& str);
|
StencilOp ParseStencilOp(const CStr& str);
|
||||||
|
|
||||||
@ -183,6 +184,15 @@ PolygonMode ParsePolygonMode(const CStr& str);
|
|||||||
CullMode ParseCullMode(const CStr& str);
|
CullMode ParseCullMode(const CStr& str);
|
||||||
FrontFace ParseFrontFace(const CStr& str);
|
FrontFace ParseFrontFace(const CStr& str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A holder for precompiled graphics pipeline description.
|
||||||
|
*/
|
||||||
|
class IGraphicsPipelineState : public IDeviceObject<IGraphicsPipelineState>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual IShaderProgram* GetShaderProgram() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Backend
|
} // namespace Backend
|
||||||
|
|
||||||
} // namespace Renderer
|
} // namespace Renderer
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "renderer/backend/dummy/Buffer.h"
|
#include "renderer/backend/dummy/Buffer.h"
|
||||||
#include "renderer/backend/dummy/DeviceCommandContext.h"
|
#include "renderer/backend/dummy/DeviceCommandContext.h"
|
||||||
#include "renderer/backend/dummy/Framebuffer.h"
|
#include "renderer/backend/dummy/Framebuffer.h"
|
||||||
|
#include "renderer/backend/dummy/PipelineState.h"
|
||||||
#include "renderer/backend/dummy/ShaderProgram.h"
|
#include "renderer/backend/dummy/ShaderProgram.h"
|
||||||
#include "renderer/backend/dummy/Texture.h"
|
#include "renderer/backend/dummy/Texture.h"
|
||||||
#include "scriptinterface/JSON.h"
|
#include "scriptinterface/JSON.h"
|
||||||
@ -73,6 +74,12 @@ std::unique_ptr<IDeviceCommandContext> CDevice::CreateCommandContext()
|
|||||||
return CDeviceCommandContext::Create(this);
|
return CDeviceCommandContext::Create(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IGraphicsPipelineState> CDevice::CreateGraphicsPipelineState(
|
||||||
|
const SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
return CGraphicsPipelineState::Create(this, pipelineStateDesc);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ITexture> CDevice::CreateTexture(
|
std::unique_ptr<ITexture> CDevice::CreateTexture(
|
||||||
const char* UNUSED(name), const CTexture::Type type, const uint32_t usage,
|
const char* UNUSED(name), const CTexture::Type type, const uint32_t usage,
|
||||||
const Format format, const uint32_t width, const uint32_t height,
|
const Format format, const uint32_t width, const uint32_t height,
|
||||||
|
@ -21,6 +21,10 @@
|
|||||||
#include "renderer/backend/dummy/DeviceForward.h"
|
#include "renderer/backend/dummy/DeviceForward.h"
|
||||||
#include "renderer/backend/IDevice.h"
|
#include "renderer/backend/IDevice.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class CShaderDefines;
|
class CShaderDefines;
|
||||||
|
|
||||||
namespace Renderer
|
namespace Renderer
|
||||||
@ -51,6 +55,9 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<IDeviceCommandContext> CreateCommandContext() override;
|
std::unique_ptr<IDeviceCommandContext> CreateCommandContext() override;
|
||||||
|
|
||||||
|
std::unique_ptr<IGraphicsPipelineState> CreateGraphicsPipelineState(
|
||||||
|
const SGraphicsPipelineStateDesc& pipelineStateDesc) override;
|
||||||
|
|
||||||
std::unique_ptr<ITexture> CreateTexture(
|
std::unique_ptr<ITexture> CreateTexture(
|
||||||
const char* name, const ITexture::Type type, const uint32_t usage,
|
const char* name, const ITexture::Type type, const uint32_t usage,
|
||||||
const Format format, const uint32_t width, const uint32_t height,
|
const Format format, const uint32_t width, const uint32_t height,
|
||||||
|
@ -52,7 +52,7 @@ IDevice* CDeviceCommandContext::GetDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CDeviceCommandContext::SetGraphicsPipelineState(
|
void CDeviceCommandContext::SetGraphicsPipelineState(
|
||||||
const GraphicsPipelineStateDesc&)
|
IGraphicsPipelineState*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
|
|
||||||
IDevice* GetDevice() override;
|
IDevice* GetDevice() override;
|
||||||
|
|
||||||
void SetGraphicsPipelineState(const GraphicsPipelineStateDesc& pipelineStateDesc) override;
|
void SetGraphicsPipelineState(IGraphicsPipelineState* pipelineState) override;
|
||||||
|
|
||||||
void BlitFramebuffer(IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) override;
|
void BlitFramebuffer(IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) override;
|
||||||
|
|
||||||
|
52
source/renderer/backend/dummy/PipelineState.cpp
Normal file
52
source/renderer/backend/dummy/PipelineState.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* Copyright (C) 2022 Wildfire Games.
|
||||||
|
* This file is part of 0 A.D.
|
||||||
|
*
|
||||||
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 0 A.D. is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "PipelineState.h"
|
||||||
|
|
||||||
|
#include "renderer/backend/dummy/Device.h"
|
||||||
|
|
||||||
|
namespace Renderer
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Backend
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Dummy
|
||||||
|
{
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::unique_ptr<CGraphicsPipelineState> CGraphicsPipelineState::Create(
|
||||||
|
CDevice* device, const SGraphicsPipelineStateDesc& desc)
|
||||||
|
{
|
||||||
|
std::unique_ptr<CGraphicsPipelineState> pipelineState{new CGraphicsPipelineState()};
|
||||||
|
pipelineState->m_Device = device;
|
||||||
|
pipelineState->m_Desc = desc;
|
||||||
|
return pipelineState;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDevice* CGraphicsPipelineState::GetDevice()
|
||||||
|
{
|
||||||
|
return m_Device;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dummy
|
||||||
|
|
||||||
|
} // namespace Backend
|
||||||
|
|
||||||
|
} // namespace Renderer
|
67
source/renderer/backend/dummy/PipelineState.h
Normal file
67
source/renderer/backend/dummy/PipelineState.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* Copyright (C) 2022 Wildfire Games.
|
||||||
|
* This file is part of 0 A.D.
|
||||||
|
*
|
||||||
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 0 A.D. is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_RENDERER_BACKEND_DUMMY_PIPELINESTATE
|
||||||
|
#define INCLUDED_RENDERER_BACKEND_DUMMY_PIPELINESTATE
|
||||||
|
|
||||||
|
#include "renderer/backend/PipelineState.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Renderer
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Backend
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Dummy
|
||||||
|
{
|
||||||
|
|
||||||
|
class CDevice;
|
||||||
|
|
||||||
|
class CGraphicsPipelineState final : public IGraphicsPipelineState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~CGraphicsPipelineState() override = default;
|
||||||
|
|
||||||
|
IDevice* GetDevice() override;
|
||||||
|
|
||||||
|
IShaderProgram* GetShaderProgram() const override { return m_Desc.shaderProgram; }
|
||||||
|
|
||||||
|
const SGraphicsPipelineStateDesc& GetDesc() const { return m_Desc; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class CDevice;
|
||||||
|
|
||||||
|
static std::unique_ptr<CGraphicsPipelineState> Create(
|
||||||
|
CDevice* device, const SGraphicsPipelineStateDesc& desc);
|
||||||
|
|
||||||
|
CGraphicsPipelineState() = default;
|
||||||
|
|
||||||
|
CDevice* m_Device = nullptr;
|
||||||
|
|
||||||
|
SGraphicsPipelineStateDesc m_Desc{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Dummy
|
||||||
|
|
||||||
|
} // namespace Backend
|
||||||
|
|
||||||
|
} // namespace Renderer
|
||||||
|
|
||||||
|
#endif // INCLUDED_RENDERER_BACKEND_DUMMY_PIPELINESTATE
|
@ -26,6 +26,7 @@
|
|||||||
#include "ps/ConfigDB.h"
|
#include "ps/ConfigDB.h"
|
||||||
#include "ps/Profile.h"
|
#include "ps/Profile.h"
|
||||||
#include "renderer/backend/gl/DeviceCommandContext.h"
|
#include "renderer/backend/gl/DeviceCommandContext.h"
|
||||||
|
#include "renderer/backend/gl/PipelineState.h"
|
||||||
#include "renderer/backend/gl/Texture.h"
|
#include "renderer/backend/gl/Texture.h"
|
||||||
#include "scriptinterface/JSON.h"
|
#include "scriptinterface/JSON.h"
|
||||||
#include "scriptinterface/Object.h"
|
#include "scriptinterface/Object.h"
|
||||||
@ -868,6 +869,12 @@ std::unique_ptr<IDeviceCommandContext> CDevice::CreateCommandContext()
|
|||||||
return commandContet;
|
return commandContet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IGraphicsPipelineState> CDevice::CreateGraphicsPipelineState(
|
||||||
|
const SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
return CGraphicsPipelineState::Create(this, pipelineStateDesc);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ITexture> CDevice::CreateTexture(
|
std::unique_ptr<ITexture> CDevice::CreateTexture(
|
||||||
const char* name, const ITexture::Type type, const uint32_t usage,
|
const char* name, const ITexture::Type type, const uint32_t usage,
|
||||||
const Format format, const uint32_t width, const uint32_t height,
|
const Format format, const uint32_t width, const uint32_t height,
|
||||||
|
@ -68,6 +68,9 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<IDeviceCommandContext> CreateCommandContext() override;
|
std::unique_ptr<IDeviceCommandContext> CreateCommandContext() override;
|
||||||
|
|
||||||
|
std::unique_ptr<IGraphicsPipelineState> CreateGraphicsPipelineState(
|
||||||
|
const SGraphicsPipelineStateDesc& pipelineStateDesc) override;
|
||||||
|
|
||||||
CDeviceCommandContext* GetActiveCommandContext() { return m_ActiveCommandContext; }
|
CDeviceCommandContext* GetActiveCommandContext() { return m_ActiveCommandContext; }
|
||||||
|
|
||||||
std::unique_ptr<ITexture> CreateTexture(
|
std::unique_ptr<ITexture> CreateTexture(
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "renderer/backend/gl/Device.h"
|
#include "renderer/backend/gl/Device.h"
|
||||||
#include "renderer/backend/gl/Framebuffer.h"
|
#include "renderer/backend/gl/Framebuffer.h"
|
||||||
#include "renderer/backend/gl/Mapping.h"
|
#include "renderer/backend/gl/Mapping.h"
|
||||||
|
#include "renderer/backend/gl/PipelineState.h"
|
||||||
#include "renderer/backend/gl/ShaderProgram.h"
|
#include "renderer/backend/gl/ShaderProgram.h"
|
||||||
#include "renderer/backend/gl/Texture.h"
|
#include "renderer/backend/gl/Texture.h"
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ namespace GL
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
bool operator==(const StencilOpState& lhs, const StencilOpState& rhs)
|
bool operator==(const SStencilOpState& lhs, const SStencilOpState& rhs)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
lhs.failOp == rhs.failOp &&
|
lhs.failOp == rhs.failOp &&
|
||||||
@ -51,7 +52,7 @@ bool operator==(const StencilOpState& lhs, const StencilOpState& rhs)
|
|||||||
lhs.depthFailOp == rhs.depthFailOp &&
|
lhs.depthFailOp == rhs.depthFailOp &&
|
||||||
lhs.compareOp == rhs.compareOp;
|
lhs.compareOp == rhs.compareOp;
|
||||||
}
|
}
|
||||||
bool operator!=(const StencilOpState& lhs, const StencilOpState& rhs)
|
bool operator!=(const SStencilOpState& lhs, const SStencilOpState& rhs)
|
||||||
{
|
{
|
||||||
return !operator==(lhs, rhs);
|
return !operator==(lhs, rhs);
|
||||||
}
|
}
|
||||||
@ -259,9 +260,17 @@ IDevice* CDeviceCommandContext::GetDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CDeviceCommandContext::SetGraphicsPipelineState(
|
void CDeviceCommandContext::SetGraphicsPipelineState(
|
||||||
const GraphicsPipelineStateDesc& pipelineStateDesc)
|
const SGraphicsPipelineStateDesc& pipelineState)
|
||||||
{
|
{
|
||||||
SetGraphicsPipelineStateImpl(pipelineStateDesc, false);
|
SetGraphicsPipelineStateImpl(pipelineState, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDeviceCommandContext::SetGraphicsPipelineState(
|
||||||
|
IGraphicsPipelineState* pipelineState)
|
||||||
|
{
|
||||||
|
ENSURE(pipelineState);
|
||||||
|
SetGraphicsPipelineStateImpl(
|
||||||
|
pipelineState->As<CGraphicsPipelineState>()->GetDesc(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeviceCommandContext::UploadTexture(
|
void CDeviceCommandContext::UploadTexture(
|
||||||
@ -556,7 +565,7 @@ void CDeviceCommandContext::ResetStates()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
|
void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
|
||||||
const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force)
|
const SGraphicsPipelineStateDesc& pipelineStateDesc, const bool force)
|
||||||
{
|
{
|
||||||
ENSURE(!m_InsidePass);
|
ENSURE(!m_InsidePass);
|
||||||
|
|
||||||
@ -589,8 +598,8 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
|
|||||||
m_ShaderProgram = nextShaderProgram;
|
m_ShaderProgram = nextShaderProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DepthStencilStateDesc& currentDepthStencilStateDesc = m_GraphicsPipelineStateDesc.depthStencilState;
|
const SDepthStencilStateDesc& currentDepthStencilStateDesc = m_GraphicsPipelineStateDesc.depthStencilState;
|
||||||
const DepthStencilStateDesc& nextDepthStencilStateDesc = pipelineStateDesc.depthStencilState;
|
const SDepthStencilStateDesc& nextDepthStencilStateDesc = pipelineStateDesc.depthStencilState;
|
||||||
if (force || currentDepthStencilStateDesc.depthTestEnabled != nextDepthStencilStateDesc.depthTestEnabled)
|
if (force || currentDepthStencilStateDesc.depthTestEnabled != nextDepthStencilStateDesc.depthTestEnabled)
|
||||||
{
|
{
|
||||||
if (nextDepthStencilStateDesc.depthTestEnabled)
|
if (nextDepthStencilStateDesc.depthTestEnabled)
|
||||||
@ -675,8 +684,8 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BlendStateDesc& currentBlendStateDesc = m_GraphicsPipelineStateDesc.blendState;
|
const SBlendStateDesc& currentBlendStateDesc = m_GraphicsPipelineStateDesc.blendState;
|
||||||
const BlendStateDesc& nextBlendStateDesc = pipelineStateDesc.blendState;
|
const SBlendStateDesc& nextBlendStateDesc = pipelineStateDesc.blendState;
|
||||||
if (force || currentBlendStateDesc.enabled != nextBlendStateDesc.enabled)
|
if (force || currentBlendStateDesc.enabled != nextBlendStateDesc.enabled)
|
||||||
{
|
{
|
||||||
if (nextBlendStateDesc.enabled)
|
if (nextBlendStateDesc.enabled)
|
||||||
@ -739,9 +748,9 @@ void CDeviceCommandContext::SetGraphicsPipelineStateImpl(
|
|||||||
ApplyColorMask(nextBlendStateDesc.colorWriteMask);
|
ApplyColorMask(nextBlendStateDesc.colorWriteMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
const RasterizationStateDesc& currentRasterizationStateDesc =
|
const SRasterizationStateDesc& currentRasterizationStateDesc =
|
||||||
m_GraphicsPipelineStateDesc.rasterizationState;
|
m_GraphicsPipelineStateDesc.rasterizationState;
|
||||||
const RasterizationStateDesc& nextRasterizationStateDesc =
|
const SRasterizationStateDesc& nextRasterizationStateDesc =
|
||||||
pipelineStateDesc.rasterizationState;
|
pipelineStateDesc.rasterizationState;
|
||||||
if (force ||
|
if (force ||
|
||||||
currentRasterizationStateDesc.polygonMode != nextRasterizationStateDesc.polygonMode)
|
currentRasterizationStateDesc.polygonMode != nextRasterizationStateDesc.polygonMode)
|
||||||
@ -867,6 +876,9 @@ void CDeviceCommandContext::ClearFramebuffer(const bool color, const bool depth,
|
|||||||
|
|
||||||
void CDeviceCommandContext::BeginFramebufferPass(IFramebuffer* framebuffer)
|
void CDeviceCommandContext::BeginFramebufferPass(IFramebuffer* framebuffer)
|
||||||
{
|
{
|
||||||
|
SetGraphicsPipelineStateImpl(
|
||||||
|
MakeDefaultGraphicsPipelineStateDesc(), false);
|
||||||
|
|
||||||
ENSURE(!m_InsideFramebufferPass);
|
ENSURE(!m_InsideFramebufferPass);
|
||||||
m_InsideFramebufferPass = true;
|
m_InsideFramebufferPass = true;
|
||||||
ENSURE(framebuffer);
|
ENSURE(framebuffer);
|
||||||
|
@ -53,7 +53,9 @@ public:
|
|||||||
|
|
||||||
IDevice* GetDevice() override;
|
IDevice* GetDevice() override;
|
||||||
|
|
||||||
void SetGraphicsPipelineState(const GraphicsPipelineStateDesc& pipelineStateDesc) override;
|
void SetGraphicsPipelineState(const SGraphicsPipelineStateDesc& pipelineState);
|
||||||
|
|
||||||
|
void SetGraphicsPipelineState(IGraphicsPipelineState* pipelineState) override;
|
||||||
|
|
||||||
void BlitFramebuffer(IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) override;
|
void BlitFramebuffer(IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) override;
|
||||||
|
|
||||||
@ -155,14 +157,14 @@ private:
|
|||||||
void ResetStates();
|
void ResetStates();
|
||||||
|
|
||||||
void SetGraphicsPipelineStateImpl(
|
void SetGraphicsPipelineStateImpl(
|
||||||
const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force);
|
const SGraphicsPipelineStateDesc& pipelineStateDesc, const bool force);
|
||||||
|
|
||||||
void BindTexture(const uint32_t unit, const GLenum target, const GLuint handle);
|
void BindTexture(const uint32_t unit, const GLenum target, const GLuint handle);
|
||||||
void BindBuffer(const IBuffer::Type type, CBuffer* buffer);
|
void BindBuffer(const IBuffer::Type type, CBuffer* buffer);
|
||||||
|
|
||||||
CDevice* m_Device = nullptr;
|
CDevice* m_Device = nullptr;
|
||||||
|
|
||||||
GraphicsPipelineStateDesc m_GraphicsPipelineStateDesc{};
|
SGraphicsPipelineStateDesc m_GraphicsPipelineStateDesc{};
|
||||||
CFramebuffer* m_Framebuffer = nullptr;
|
CFramebuffer* m_Framebuffer = nullptr;
|
||||||
CShaderProgram* m_ShaderProgram = nullptr;
|
CShaderProgram* m_ShaderProgram = nullptr;
|
||||||
uint32_t m_ScissorCount = 0;
|
uint32_t m_ScissorCount = 0;
|
||||||
|
52
source/renderer/backend/gl/PipelineState.cpp
Normal file
52
source/renderer/backend/gl/PipelineState.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* Copyright (C) 2022 Wildfire Games.
|
||||||
|
* This file is part of 0 A.D.
|
||||||
|
*
|
||||||
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 0 A.D. is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "PipelineState.h"
|
||||||
|
|
||||||
|
#include "renderer/backend/gl/Device.h"
|
||||||
|
|
||||||
|
namespace Renderer
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Backend
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace GL
|
||||||
|
{
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::unique_ptr<CGraphicsPipelineState> CGraphicsPipelineState::Create(
|
||||||
|
CDevice* device, const SGraphicsPipelineStateDesc& desc)
|
||||||
|
{
|
||||||
|
std::unique_ptr<CGraphicsPipelineState> pipelineState{new CGraphicsPipelineState()};
|
||||||
|
pipelineState->m_Device = device;
|
||||||
|
pipelineState->m_Desc = desc;
|
||||||
|
return pipelineState;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDevice* CGraphicsPipelineState::GetDevice()
|
||||||
|
{
|
||||||
|
return m_Device;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace GL
|
||||||
|
|
||||||
|
} // namespace Backend
|
||||||
|
|
||||||
|
} // namespace Renderer
|
68
source/renderer/backend/gl/PipelineState.h
Normal file
68
source/renderer/backend/gl/PipelineState.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* Copyright (C) 2022 Wildfire Games.
|
||||||
|
* This file is part of 0 A.D.
|
||||||
|
*
|
||||||
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 0 A.D. is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_RENDERER_BACKEND_GL_PIPELINESTATE
|
||||||
|
#define INCLUDED_RENDERER_BACKEND_GL_PIPELINESTATE
|
||||||
|
|
||||||
|
#include "lib/ogl.h"
|
||||||
|
#include "renderer/backend/PipelineState.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Renderer
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace Backend
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace GL
|
||||||
|
{
|
||||||
|
|
||||||
|
class CDevice;
|
||||||
|
|
||||||
|
class CGraphicsPipelineState final : public IGraphicsPipelineState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~CGraphicsPipelineState() override = default;
|
||||||
|
|
||||||
|
IDevice* GetDevice() override;
|
||||||
|
|
||||||
|
IShaderProgram* GetShaderProgram() const override { return m_Desc.shaderProgram; }
|
||||||
|
|
||||||
|
const SGraphicsPipelineStateDesc& GetDesc() const { return m_Desc; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class CDevice;
|
||||||
|
|
||||||
|
static std::unique_ptr<CGraphicsPipelineState> Create(
|
||||||
|
CDevice* device, const SGraphicsPipelineStateDesc& desc);
|
||||||
|
|
||||||
|
CGraphicsPipelineState() = default;
|
||||||
|
|
||||||
|
CDevice* m_Device = nullptr;
|
||||||
|
|
||||||
|
SGraphicsPipelineStateDesc m_Desc{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace GL
|
||||||
|
|
||||||
|
} // namespace Backend
|
||||||
|
|
||||||
|
} // namespace Renderer
|
||||||
|
|
||||||
|
#endif // INCLUDED_RENDERER_BACKEND_GL_PIPELINESTATE
|
@ -79,6 +79,13 @@ std::unique_ptr<IDeviceCommandContext> CDevice::CreateCommandContext()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IGraphicsPipelineState> CDevice::CreateGraphicsPipelineState(
|
||||||
|
const SGraphicsPipelineStateDesc& pipelineStateDesc)
|
||||||
|
{
|
||||||
|
UNUSED2(pipelineStateDesc);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ITexture> CDevice::CreateTexture(
|
std::unique_ptr<ITexture> CDevice::CreateTexture(
|
||||||
const char* name, const ITexture::Type type, const uint32_t usage,
|
const char* name, const ITexture::Type type, const uint32_t usage,
|
||||||
const Format format, const uint32_t width, const uint32_t height,
|
const Format format, const uint32_t width, const uint32_t height,
|
||||||
|
@ -56,6 +56,9 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<IDeviceCommandContext> CreateCommandContext() override;
|
std::unique_ptr<IDeviceCommandContext> CreateCommandContext() override;
|
||||||
|
|
||||||
|
std::unique_ptr<IGraphicsPipelineState> CreateGraphicsPipelineState(
|
||||||
|
const SGraphicsPipelineStateDesc& pipelineStateDesc) override;
|
||||||
|
|
||||||
std::unique_ptr<ITexture> CreateTexture(
|
std::unique_ptr<ITexture> CreateTexture(
|
||||||
const char* name, const ITexture::Type type, const uint32_t usage,
|
const char* name, const ITexture::Type type, const uint32_t usage,
|
||||||
const Format format, const uint32_t width, const uint32_t height,
|
const Format format, const uint32_t width, const uint32_t height,
|
||||||
|
Loading…
Reference in New Issue
Block a user