forked from mirrors/0ad
Makes the terrain and decals rendering code load effect once per usage.
This was SVN commit r26823.
This commit is contained in:
@@ -48,7 +48,8 @@ namespace
|
||||
struct SDecalBatch
|
||||
{
|
||||
CDecalRData* decal;
|
||||
CShaderTechniquePtr shaderTech;
|
||||
CStrIntern shaderEffect;
|
||||
CShaderDefines shaderDefines;
|
||||
CVertexBuffer::VBChunk* vertices;
|
||||
CVertexBuffer::VBChunk* indices;
|
||||
};
|
||||
@@ -57,8 +58,10 @@ struct SDecalBatchComparator
|
||||
{
|
||||
bool operator()(const SDecalBatch& lhs, const SDecalBatch& rhs) const
|
||||
{
|
||||
if (lhs.shaderTech != rhs.shaderTech)
|
||||
return lhs.shaderTech < rhs.shaderTech;
|
||||
if (lhs.shaderEffect != rhs.shaderEffect)
|
||||
return lhs.shaderEffect < rhs.shaderEffect;
|
||||
if (lhs.shaderDefines != rhs.shaderDefines)
|
||||
return lhs.shaderDefines < rhs.shaderDefines;
|
||||
const CMaterial& lhsMaterial = lhs.decal->GetDecal()->m_Decal.m_Material;
|
||||
const CMaterial& rhsMaterial = rhs.decal->GetDecal()->m_Decal.m_Material;
|
||||
if (lhsMaterial.GetDiffuseTexture() != rhsMaterial.GetDiffuseTexture())
|
||||
@@ -111,7 +114,7 @@ void CDecalRData::RenderDecals(
|
||||
|
||||
for (CDecalRData* decal : decals)
|
||||
{
|
||||
CMaterial &material = decal->m_Decal->m_Decal.m_Material;
|
||||
CMaterial& material = decal->m_Decal->m_Decal.m_Material;
|
||||
|
||||
if (material.GetShaderEffect().empty())
|
||||
{
|
||||
@@ -119,23 +122,13 @@ void CDecalRData::RenderDecals(
|
||||
continue;
|
||||
}
|
||||
|
||||
CShaderDefines defines = contextDecal;
|
||||
defines.SetMany(material.GetShaderDefines());
|
||||
CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect(
|
||||
material.GetShaderEffect(), defines);
|
||||
if (!techBase)
|
||||
{
|
||||
LOGERROR("Terrain renderer failed to load shader effect (%s)\n",
|
||||
material.GetShaderEffect().string().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (material.GetSamplers().empty() || !decal->m_VBDecals || !decal->m_VBDecalsIndices)
|
||||
continue;
|
||||
|
||||
SDecalBatch batch;
|
||||
batch.decal = decal;
|
||||
batch.shaderTech = techBase;
|
||||
batch.shaderEffect = material.GetShaderEffect();
|
||||
batch.shaderDefines = material.GetShaderDefines();
|
||||
batch.vertices = decal->m_VBDecals.Get();
|
||||
batch.indices = decal->m_VBDecalsIndices.Get();
|
||||
|
||||
@@ -150,12 +143,25 @@ void CDecalRData::RenderDecals(
|
||||
CVertexBuffer* lastIB = nullptr;
|
||||
for (auto itTechBegin = batches.begin(), itTechEnd = batches.begin(); itTechBegin != batches.end(); itTechBegin = itTechEnd)
|
||||
{
|
||||
while (itTechEnd != batches.end() && itTechBegin->shaderTech == itTechEnd->shaderTech)
|
||||
while (itTechEnd != batches.end() &&
|
||||
itTechBegin->shaderEffect == itTechEnd->shaderEffect &&
|
||||
itTechBegin->shaderDefines == itTechEnd->shaderDefines)
|
||||
{
|
||||
++itTechEnd;
|
||||
}
|
||||
|
||||
CShaderDefines defines = contextDecal;
|
||||
defines.SetMany(itTechBegin->shaderDefines);
|
||||
CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect(
|
||||
itTechBegin->shaderEffect, defines);
|
||||
if (!techBase)
|
||||
{
|
||||
LOGERROR("Terrain renderer failed to load shader effect (%s)\n",
|
||||
itTechBegin->shaderEffect.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
const CShaderTechniquePtr& techBase = itTechBegin->shaderTech;
|
||||
const int numPasses = techBase->GetNumPasses();
|
||||
|
||||
for (int pass = 0; pass < numPasses; ++pass)
|
||||
{
|
||||
Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc =
|
||||
|
||||
@@ -712,7 +712,7 @@ using VertexBufferBatches = PooledBatchMap<CVertexBuffer*, IndexBufferBatches>;
|
||||
using TextureBatches = PooledBatchMap<CTerrainTextureEntry*, VertexBufferBatches>;
|
||||
|
||||
// Group batches by shaders.
|
||||
using ShaderTechniqueBatches = PooledBatchMap<CShaderTechniquePtr, TextureBatches>;
|
||||
using ShaderTechniqueBatches = PooledBatchMap<std::pair<CStrIntern, CShaderDefines>, TextureBatches>;
|
||||
|
||||
void CPatchRData::RenderBases(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
@@ -740,15 +740,11 @@ void CPatchRData::RenderBases(
|
||||
LOGERROR("Terrain renderer failed to load shader effect.\n");
|
||||
continue;
|
||||
}
|
||||
CShaderDefines defines = context;
|
||||
defines.SetMany(material.GetShaderDefines());
|
||||
CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect(
|
||||
material.GetShaderEffect(), defines);
|
||||
|
||||
BatchElements& batch = PooledPairGet(
|
||||
PooledMapGet(
|
||||
PooledMapGet(
|
||||
PooledMapGet(batches, techBase, arena),
|
||||
PooledMapGet(batches, std::make_pair(material.GetShaderEffect(), material.GetShaderDefines()), arena),
|
||||
splat.m_Texture, arena
|
||||
),
|
||||
patch->m_VBBase->m_Owner, arena
|
||||
@@ -767,7 +763,11 @@ void CPatchRData::RenderBases(
|
||||
// Render each batch
|
||||
for (ShaderTechniqueBatches::iterator itTech = batches.begin(); itTech != batches.end(); ++itTech)
|
||||
{
|
||||
const CShaderTechniquePtr& techBase = itTech->first;
|
||||
CShaderDefines defines = context;
|
||||
defines.SetMany(itTech->first.second);
|
||||
CShaderTechniquePtr techBase = g_Renderer.GetShaderManager().LoadEffect(
|
||||
itTech->first.first, defines);
|
||||
|
||||
const int numPasses = techBase->GetNumPasses();
|
||||
for (int pass = 0; pass < numPasses; ++pass)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user