Removed duplicate code in CommandBuffer class, and replaced singleton ShadowPassCmd by the new ShadowCommandBuffer class

This commit is contained in:
Elderme 2015-11-16 22:28:22 +01:00
parent 5c02c58ded
commit e36ba066fb
7 changed files with 282 additions and 424 deletions

View File

@ -17,6 +17,7 @@
#include "graphics/command_buffer.hpp"
#include "graphics/central_settings.hpp"
#include "utils/cpp2011.hpp"
template<>
@ -60,6 +61,30 @@
prefilled_tex[1], prefilled_tex[2], prefilled_tex[3]);
}
template<int N>
void CommandBuffer<N>::clearMeshes()
{
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
for(int i=0;i<N;i++)
{
m_meshes[i].clear();
}
}
template<int N>
void CommandBuffer<N>::unmapBuffers()
{
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}
template<int N>
CommandBuffer<N>::CommandBuffer():
m_poly_count(0)
@ -90,235 +115,102 @@ CommandBuffer<N>::~CommandBuffer()
glDeleteBuffers(1, &m_draw_indirect_cmd_id);
}
SolidCommandBuffer::SolidCommandBuffer(): CommandBuffer()
{
}
void SolidCommandBuffer::fill(MeshMap *mesh_map)
{
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
clearMeshes();
//clear meshes
for(int i=0;i<Material::SHADERTYPE_COUNT;i++)
{
m_meshes[i].clear();
}
//Dual textures materials
InstanceDataDualTex *instance_buffer_dual_tex;
if (CVS->supportsAsyncInstanceUpload())
{
instance_buffer_dual_tex =
(InstanceDataDualTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDualTex);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDualTex));
instance_buffer_dual_tex =
(InstanceDataDualTex*) glMapBufferRange(GL_ARRAY_BUFFER, 0,
10000 * sizeof(InstanceDataDualTex),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
std::vector<int> dual_tex_material_list =
createVector<int>(Material::SHADERTYPE_SOLID,
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_SPHERE_MAP,
Material::SHADERTYPE_VEGETATION);
fillInstanceData<InstanceDataDualTex>(mesh_map,
dual_tex_material_list,
InstanceTypeDualTex);
std::vector<int> three_tex_material_list =
createVector<int>(Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_NORMAL_MAP);
fillInstanceData<InstanceDataThreeTex>(mesh_map,
three_tex_material_list,
InstanceTypeThreeTex);
m_draw_indirect_cmd =
(DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
10000 * sizeof(DrawElementsIndirectCommand),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
Material::ShaderType dual_tex_materials[5] =
{
Material::SHADERTYPE_SOLID,
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_SPHERE_MAP,
Material::SHADERTYPE_VEGETATION
};
int material_id;
for(int i=0;i<5;i++)
{
material_id = static_cast<int>(dual_tex_materials[i]);
fillMaterial( material_id,
mesh_map,
instance_buffer_dual_tex);
}
//Three textures materials
InstanceDataThreeTex *instance_buffer_three_tex;
if (CVS->supportsAsyncInstanceUpload())
{
instance_buffer_three_tex =
(InstanceDataThreeTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeThreeTex);
}
else
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeThreeTex));
instance_buffer_three_tex =
(InstanceDataThreeTex*) glMapBufferRange(GL_ARRAY_BUFFER, 0,
10000 * sizeof(InstanceDataSingleTex), //TODO: why single?
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
Material::ShaderType three_tex_materials[2] =
{
Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_NORMAL_MAP
};
for(int i=0;i<2;i++)
{
material_id = static_cast<int>(three_tex_materials[i]);
fillMaterial( material_id,
mesh_map,
instance_buffer_three_tex);
}
unmapBuffers();
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
} //SolidCommandBuffer::fill
ShadowCommandBuffer::ShadowCommandBuffer(): CommandBuffer()
{
}
//void ShadowCommandBuffer::fill(std::array<MeshMap,Material::SHADERTYPE_COUNT> mesh_map)
void ShadowCommandBuffer::fill(MeshMap *mesh_map)
{
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
clearMeshes();
//clear meshes
for(int i=0;i<4*Material::SHADERTYPE_COUNT;i++)
std::vector<int> shadow_tex_material_list;
/* createVector<Material::ShaderType>(Material::SHADERTYPE_SOLID,
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_NORMAL_MAP,
Material::SHADERTYPE_SPHERE_MAP,
Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_VEGETATION);*/
for(int cascade=0; cascade<4; cascade++)
{
m_meshes[i].clear();
}
InstanceDataSingleTex *shadow_instance_buffer;
if (CVS->supportsAsyncInstanceUpload())
{
shadow_instance_buffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
shadow_instance_buffer =
(InstanceDataSingleTex*) glMapBufferRange(GL_ARRAY_BUFFER, 0,
10000 * sizeof(InstanceDataDualTex),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
m_draw_indirect_cmd =
(DrawElementsIndirectCommand*) glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
10000 * sizeof(DrawElementsIndirectCommand),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_SOLID);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_ALPHA_TEST);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_SOLID_UNLIT);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_NORMAL_MAP);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_SPHERE_MAP);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_DETAIL_MAP);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_VEGETATION);
}
fillInstanceData<InstanceDataSingleTex>(mesh_map, shadow_tex_material_list, InstanceTypeShadow);
//fillInstanceData<InstanceDataSingleTex>(mesh_map.data(), shadow_tex_material_list, InstanceTypeShadow);
Material::ShaderType materials[7] =
{
Material::SHADERTYPE_SOLID,
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_NORMAL_MAP,
Material::SHADERTYPE_SPHERE_MAP,
Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_VEGETATION
};
int material_id;
for(int cascade=0;cascade<4;cascade++)
{
for(int i=0;i<7;i++)
{
material_id = cascade * 7 + static_cast<int>(materials[i]);
fillMaterial( material_id,
mesh_map,
shadow_instance_buffer);
}
}
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
unmapBuffers();
} //ShadowCommandBuffer::fill
ReflectiveShadowMapCommandBuffer::ReflectiveShadowMapCommandBuffer(): CommandBuffer()
ReflectiveShadowMapCommandBuffer::ReflectiveShadowMapCommandBuffer()
{
}
void ReflectiveShadowMapCommandBuffer::fill(MeshMap *mesh_map)
{
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
clearMeshes();
//clear meshes
for(int i=0;i<Material::SHADERTYPE_COUNT;i++)
{
m_meshes[i].clear();
}
InstanceDataSingleTex *rsm_instance_buffer;
if (CVS->supportsAsyncInstanceUpload())
{
rsm_instance_buffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER,
VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
rsm_instance_buffer =
(InstanceDataSingleTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0,
10000 * sizeof(InstanceDataDualTex),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
m_draw_indirect_cmd =
(DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
10000 * sizeof(DrawElementsIndirectCommand),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
Material::ShaderType materials[5] =
{
Material::SHADERTYPE_SOLID,
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_NORMAL_MAP
};
int material_id;
for(int i=0;i<5;i++)
{
material_id = static_cast<int>(materials[i]);
fillMaterial( material_id,
mesh_map,
rsm_instance_buffer);
}
std::vector<int> rsm_material_list =
createVector<int>(Material::SHADERTYPE_SOLID,
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_NORMAL_MAP);
fillInstanceData<InstanceDataSingleTex>(mesh_map,
rsm_material_list,
InstanceTypeRSM);
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
unmapBuffers();
} //ReflectiveShadowMapCommandBuffer::fill
@ -328,11 +220,7 @@ GlowCommandBuffer::GlowCommandBuffer()
void GlowCommandBuffer::fill(MeshMap *mesh_map)
{
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
m_meshes[0].clear();
clearMeshes();
GlowInstanceData *glow_instance_buffer;
@ -359,9 +247,5 @@ void GlowCommandBuffer::fill(MeshMap *mesh_map)
mesh_map,
glow_instance_buffer);
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
unmapBuffers();
} //GlowCommandBuffer::fill

View File

@ -84,7 +84,7 @@ void FillInstances_impl(InstanceList instance_list,
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
CurrentCommand.baseInstance = initial_offset;
CurrentCommand.instanceCount = instance_buffer_offset - initial_offset;
poly_count += (instance_buffer_offset - initial_offset) * mesh->IndexCount / 3;
}
@ -126,14 +126,19 @@ class CommandBuffer
protected:
GLuint m_draw_indirect_cmd_id;
DrawElementsIndirectCommand *m_draw_indirect_cmd;
std::vector<GLMesh *> m_meshes[N];
size_t m_offset[N];
size_t m_size[N];
std::array<std::vector<GLMesh *>, N> m_meshes;
std::array<size_t,N> m_offset;
std::array<size_t,N> m_size;
size_t m_poly_count;
size_t m_instance_buffer_offset;
size_t m_command_buffer_offset;
void clearMeshes();
void unmapBuffers();
template<typename T>
void fillMaterial(int material_id,
MeshMap *mesh_map,
@ -142,15 +147,60 @@ protected:
m_offset[material_id] = m_command_buffer_offset;
for(auto& instance_list : mesh_map[material_id])
{
FillInstances_impl<T>(instance_list.second, instance_buffer, m_draw_indirect_cmd, m_instance_buffer_offset, m_command_buffer_offset, m_poly_count);
FillInstances_impl<T>(instance_list.second,
instance_buffer,
m_draw_indirect_cmd,
m_instance_buffer_offset,
m_command_buffer_offset,
m_poly_count);
if (!CVS->isAZDOEnabled())
m_meshes[material_id].push_back(instance_list.second.front().first);
}
m_size[material_id] = m_command_buffer_offset - m_instance_buffer_offset;
m_size[material_id] = m_command_buffer_offset - m_offset[material_id];
}
template<typename InstanceData>
void fillInstanceData(MeshMap *mesh_map,
const std::vector<int> &material_list,
InstanceType instance_type)
{
InstanceData *instance_buffer;
if (CVS->supportsAsyncInstanceUpload())
{
instance_buffer = (InstanceData*)VAOManager::getInstance()->
getInstanceBufferPtr(instance_type);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER,
VAOManager::getInstance()->getInstanceBuffer(instance_type));
instance_buffer = (InstanceData*)
glMapBufferRange(GL_ARRAY_BUFFER, 0,
10000 * sizeof(InstanceDataDualTex),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER,
m_draw_indirect_cmd_id);
m_draw_indirect_cmd = (DrawElementsIndirectCommand*)
glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
10000 * sizeof(DrawElementsIndirectCommand),
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
for(int material_id: material_list)
{
fillMaterial( material_id,
mesh_map,
instance_buffer);
}
}
public:
CommandBuffer();
virtual ~CommandBuffer();
@ -164,82 +214,6 @@ public:
{
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
}
template<typename T, typename...Uniforms>
void drawIndirectFirstPass(Uniforms...uniforms) const
{
T::InstancedFirstPassShader::getInstance()->use();
T::InstancedFirstPassShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
T::Instance));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
#ifdef DEBUG
if (mesh->VAOType != T::VertexType)
{
Log::error("CommandBuffer", "Wrong instanced vertex format (hint : %s)",
mesh->textures[0]->getName().getPath().c_str());
continue;
}
#endif
TexExpander<typename T::InstancedFirstPassShader>::template expandTex(*mesh, T::FirstPassTextures);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirectFirstPass
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirectSecondPass(const std::vector<GLuint> &prefilled_tex,
Uniforms...uniforms ) const
{
T::InstancedSecondPassShader::getInstance()->use();
T::InstancedSecondPassShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
T::Instance));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
expandTexSecondPass<T>(*mesh, prefilled_tex);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirectSecondPass
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirectReflectiveShadowMap(Uniforms ...uniforms) const
{
T::InstancedRSMShader::getInstance()->use();
T::InstancedRSMShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
InstanceTypeRSM));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
TexExpander<typename T::InstancedRSMShader>::template expandTex(*mesh, T::RSMTextures);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirectReflectiveShadowMap
/** Draw the i-th mesh with the specified material
@ -274,6 +248,56 @@ public:
SolidCommandBuffer();
void fill(MeshMap *mesh_map);
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirectFirstPass(Uniforms...uniforms) const
{
T::InstancedFirstPassShader::getInstance()->use();
T::InstancedFirstPassShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
T::Instance));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
#ifdef DEBUG
if (mesh->VAOType != T::VertexType)
{
Log::error("CommandBuffer", "Wrong instanced vertex format (hint : %s)",
mesh->textures[0]->getName().getPath().c_str());
continue;
}
#endif
TexExpander<typename T::InstancedFirstPassShader>::template
expandTex(*mesh, T::FirstPassTextures);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirectFirstPass
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirectSecondPass(const std::vector<GLuint> &prefilled_tex,
Uniforms...uniforms ) const
{
T::InstancedSecondPassShader::getInstance()->use();
T::InstancedSecondPassShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
T::Instance));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
expandTexSecondPass<T>(*mesh, prefilled_tex);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirectSecondPass
};
@ -282,6 +306,31 @@ class ShadowCommandBuffer: public CommandBuffer<4*static_cast<int>(Material::SHA
public:
ShadowCommandBuffer();
void fill(MeshMap *mesh_map);
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirect(Uniforms ...uniforms, unsigned cascade) const
{
T::InstancedShadowPassShader::getInstance()->use();
T::InstancedShadowPassShader::getInstance()->setUniforms(uniforms..., cascade);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
InstanceTypeShadow));
int material_id = T::MaterialType + cascade * Material::SHADERTYPE_COUNT;
for (unsigned i = 0; i < m_meshes[material_id].size(); i++)
{
GLMesh *mesh = m_meshes[material_id][i];
TexExpander<typename T::InstancedShadowPassShader>::template
expandTex(*mesh, T::ShadowTextures);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[material_id] + i)
* sizeof(DrawElementsIndirectCommand)));
} // for i
} // renderInstancedShadow
};
class ReflectiveShadowMapCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADERTYPE_COUNT)>
@ -289,6 +338,28 @@ class ReflectiveShadowMapCommandBuffer: public CommandBuffer<static_cast<int>(Ma
public:
ReflectiveShadowMapCommandBuffer();
void fill(MeshMap *mesh_map);
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirect(Uniforms ...uniforms) const
{
T::InstancedRSMShader::getInstance()->use();
T::InstancedRSMShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
InstanceTypeRSM));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
TexExpander<typename T::InstancedRSMShader>::template expandTex(*mesh, T::RSMTextures);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirectReflectiveShadowMap
};
class GlowCommandBuffer: public CommandBuffer<1>

View File

@ -79,7 +79,7 @@ void DrawCalls::genDrawCalls(unsigned cascade,
if (CVS->supportsIndirectInstancingRendering())
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
FillInstances<T>(m_shadow_pass_mesh[Mat][cascade],
FillInstances<T>(m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat],
InstancedList,
InstanceBuffer,
CommandBuffer,
@ -275,7 +275,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
for (GLMesh *mesh : node->MeshSolidMaterial[Mat])
{
if (Mat != Material::SHADERTYPE_SPLATTING)
m_shadow_pass_mesh[Mat][cascade][mesh->mb].emplace_back(mesh, Node);
m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].emplace_back(mesh, Node);
else
{
core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
@ -438,7 +438,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
m_solid_pass_mesh[Mat].clear();
m_reflective_shadow_map_mesh[Mat].clear();
for (unsigned i = 0; i < 4; i++)
m_shadow_pass_mesh[Mat][i].clear();
m_shadow_pass_mesh[i * Material::SHADERTYPE_COUNT + Mat].clear();
}
m_glow_pass_mesh.clear();
@ -578,82 +578,13 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
}
#pragma omp section
{
//m_shadow_cmd_buffer.fill(m_shadow_pass_mesh);
irr_driver->setPhase(SHADOW_PASS);
size_t offset = 0, current_cmd = 0;
if (!CVS->supportsAsyncInstanceUpload())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
ShadowInstanceBuffer = (InstanceDataSingleTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataDualTex), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
ShadowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
for (unsigned i = 0; i < 4; i++)
{
// Mat default
genDrawCalls<Material::SHADERTYPE_SOLID>(i, ListInstancedMatDefault::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat AlphaRef
genDrawCalls<Material::SHADERTYPE_ALPHA_TEST>(i, ListInstancedMatAlphaRef::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Unlit
genDrawCalls<Material::SHADERTYPE_SOLID_UNLIT>(i, ListInstancedMatUnlit::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat NormalMap
genDrawCalls<Material::SHADERTYPE_NORMAL_MAP>(i, ListInstancedMatNormalMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Spheremap
genDrawCalls<Material::SHADERTYPE_SPHERE_MAP>(i, ListInstancedMatSphereMap::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Detail
genDrawCalls<Material::SHADERTYPE_DETAIL_MAP>(i, ListInstancedMatDetails::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
// Mat Grass
genDrawCalls<Material::SHADERTYPE_VEGETATION>(i, ListInstancedMatGrass::getInstance()->Shadows[i], ShadowInstanceBuffer, ShadowCmdBuffer, offset, current_cmd, ShadowPoly);
}
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
m_shadow_cmd_buffer.fill(m_shadow_pass_mesh);
}
#pragma omp section
if (!shadow_matrices.isRSMMapAvail())
{
m_reflective_shadow_map_cmd_buffer.fill(m_reflective_shadow_map_mesh);
/*size_t offset = 0, current_cmd = 0;
if (!CVS->supportsAsyncInstanceUpload())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
RSMInstanceBuffer = (InstanceDataSingleTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataDualTex), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
RSMCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Default Material
RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_SOLID] = current_cmd;
FillInstances(m_reflective_shadow_map_mesh[Material::SHADERTYPE_SOLID], ListInstancedMatDefault::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[Material::SHADERTYPE_SOLID] = current_cmd - RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_SOLID];
// Alpha Ref
RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_ALPHA_TEST] = current_cmd;
FillInstances(m_reflective_shadow_map_mesh[Material::SHADERTYPE_ALPHA_TEST], ListInstancedMatAlphaRef::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[Material::SHADERTYPE_ALPHA_TEST] = current_cmd - RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_ALPHA_TEST];
// Unlit
RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_SOLID_UNLIT] = current_cmd;
FillInstances(m_reflective_shadow_map_mesh[Material::SHADERTYPE_SOLID_UNLIT], ListInstancedMatUnlit::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[Material::SHADERTYPE_SOLID_UNLIT] = current_cmd - RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_SOLID_UNLIT];
// Detail
RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_DETAIL_MAP] = current_cmd;
FillInstances(m_reflective_shadow_map_mesh[Material::SHADERTYPE_DETAIL_MAP], ListInstancedMatDetails::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[Material::SHADERTYPE_DETAIL_MAP] = current_cmd - RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_DETAIL_MAP];
// Normal Map
RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_NORMAL_MAP] = current_cmd;
FillInstances(m_reflective_shadow_map_mesh[Material::SHADERTYPE_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly);
RSMPassCmd::getInstance()->Size[Material::SHADERTYPE_NORMAL_MAP] = current_cmd - RSMPassCmd::getInstance()->Offset[Material::SHADERTYPE_NORMAL_MAP];
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}*/
}
}
PROFILER_POP_CPU_MARKER();
@ -728,10 +659,20 @@ void DrawCalls::drawIndirectSolidSecondPass(const std::vector<GLuint> &prefilled
void DrawCalls::drawIndirectReflectiveShadowMaps(const core::matrix4 &rsm_matrix) const
{
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<DefaultMaterial>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<AlphaRef>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<UnlitMat>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<NormalMat>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<DetailMat>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirect<DefaultMaterial>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirect<AlphaRef>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirect<UnlitMat>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirect<NormalMat>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirect<DetailMat>(rsm_matrix);
}
void DrawCalls::drawIndirectShadows(unsigned cascade) const
{
m_shadow_cmd_buffer.drawIndirect<DefaultMaterial>(cascade);
m_shadow_cmd_buffer.drawIndirect<DetailMat>(cascade);
m_shadow_cmd_buffer.drawIndirect<AlphaRef>(cascade);
m_shadow_cmd_buffer.drawIndirect<UnlitMat>(cascade);
m_shadow_cmd_buffer.drawIndirect<GrassMat,irr::core::vector3df>(windDir, cascade);
m_shadow_cmd_buffer.drawIndirect<NormalMat>(cascade);
}

View File

@ -53,7 +53,7 @@ private:
irr::core::vector3df windDir; //TODO: same member in geometry_passes
MeshMap m_solid_pass_mesh [Material::SHADERTYPE_COUNT] ;
MeshMap m_shadow_pass_mesh [Material::SHADERTYPE_COUNT][4] ;
MeshMap m_shadow_pass_mesh [4 * Material::SHADERTYPE_COUNT] ;
MeshMap m_reflective_shadow_map_mesh[Material::SHADERTYPE_COUNT] ;
MeshMap m_glow_pass_mesh;
std::vector <STKMeshCommon *> m_deferred_update;
@ -98,6 +98,7 @@ public:
void renderParticlesList() const;
inline void bindSolidCmd() const { m_solid_cmd_buffer.bind(); }
inline void bindShadowCmd() const { m_shadow_cmd_buffer.bind(); }
inline void bindReflectiveShadowMapsCmd() const { m_reflective_shadow_map_cmd_buffer.bind(); }
@ -110,8 +111,8 @@ public:
void drawIndirectSolidFirstPass() const;
//void multidrawIndirectSolidCmd() const; //TODO
void drawIndirectSolidSecondPass(const std::vector<GLuint> &prefilled_tex) const;
void drawIndirectShadows(unsigned cascade) const;
void drawIndirectReflectiveShadowMaps(const core::matrix4 &rsm_matrix) const;
};

View File

@ -164,33 +164,6 @@ void renderMeshes1stPass(const DrawCalls& draw_calls)
}
} // renderMeshes1stPass
// ----------------------------------------------------------------------------
template<typename T, typename...Args>
void renderInstancedMeshes1stPass(const DrawCalls& draw_calls, Args...args)
{
std::vector<GLMesh *> &meshes = T::InstancedList::getInstance()->SolidPass;
T::InstancedFirstPassShader::getInstance()->use();
T::InstancedFirstPassShader::getInstance()->setUniforms(args...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance));
for (unsigned i = 0; i < meshes.size(); i++)
{
GLMesh *mesh = meshes[i];
#ifdef DEBUG
if (mesh->VAOType != T::VertexType)
{
Log::error("RenderGeometry", "Wrong instanced vertex format (hint : %s)",
mesh->textures[0]->getName().getPath().c_str());
continue;
}
#endif
TexExpander<typename T::InstancedFirstPassShader>::template expandTex(*mesh, T::FirstPassTextures);
draw_calls.drawIndirectSolidCmd(T::MaterialType, i);
}
} // renderInstancedMeshes1stPass
// ----------------------------------------------------------------------------
template<typename T, typename...Args>
void multidraw1stPass(const DrawCalls& draw_calls, Args...args)
@ -291,25 +264,6 @@ void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
}
} // renderMeshes2ndPass
// ----------------------------------------------------------------------------
template<typename T, typename...Args>
void renderInstancedMeshes2ndPass(const DrawCalls& draw_calls, const std::vector<GLuint> &Prefilled_tex, Args...args)
{
std::vector<GLMesh *> &meshes = T::InstancedList::getInstance()->SolidPass;
T::InstancedSecondPassShader::getInstance()->use();
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
T::Instance));
for (unsigned i = 0; i < meshes.size(); i++)
{
GLMesh *mesh = meshes[i];
TexExpander<typename T::InstancedSecondPassShader>::template
expandTex(*mesh, T::SecondPassTextures, Prefilled_tex[0],
Prefilled_tex[1], Prefilled_tex[2]);
T::InstancedSecondPassShader::getInstance()->setUniforms(args...);
draw_calls.drawIndirectSolidCmd(T::MaterialType, i);
}
} // renderInstancedMeshes2ndPass
// ----------------------------------------------------------------------------
template<typename T, typename...Args>
void multidraw2ndPass(const DrawCalls& draw_calls, const std::vector<uint64_t> &Handles, Args... args)
@ -708,7 +662,8 @@ static void multidrawShadow(unsigned i, Args ...args)
// ----------------------------------------------------------------------------
void GeometryPasses::renderShadows(const ShadowMatrices& shadow_matrices,
void GeometryPasses::renderShadows(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer)
{
glDepthFunc(GL_LEQUAL);
@ -734,17 +689,19 @@ void GeometryPasses::renderShadows(const ShadowMatrices& shadow_matrices,
{
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SHADOWS_CASCADE0 + cascade));
renderShadow<DefaultMaterial, 1>(cascade);
/*renderShadow<DefaultMaterial, 1>(cascade);
renderShadow<SphereMap, 1>(cascade);
renderShadow<DetailMat, 1>(cascade);
renderShadow<SplattingMat, 1>(cascade);
renderShadow<NormalMat, 1>(cascade);
renderShadow<AlphaRef, 1>(cascade);
renderShadow<UnlitMat, 1>(cascade);
renderShadow<GrassMat, 3, 1>(cascade);
renderShadow<GrassMat, 3, 1>(cascade);*/
if (CVS->supportsIndirectInstancingRendering())
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
//glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
draw_calls.bindShadowCmd();
if (CVS->isAZDOEnabled())
{
@ -757,12 +714,14 @@ void GeometryPasses::renderShadows(const ShadowMatrices& shadow_matrices,
}
else if (CVS->supportsIndirectInstancingRendering())
{
renderInstancedShadow<DefaultMaterial>(cascade);
//if(cascade==0)
draw_calls.drawIndirectShadows(cascade);
/*renderInstancedShadow<DefaultMaterial>(cascade);
renderInstancedShadow<DetailMat>(cascade);
renderInstancedShadow<AlphaRef>(cascade);
renderInstancedShadow<UnlitMat>(cascade);
renderInstancedShadow<GrassMat>(cascade, m_wind_dir);
renderInstancedShadow<NormalMat>(cascade);
renderInstancedShadow<NormalMat>(cascade);*/
}
}

View File

@ -42,7 +42,8 @@ public:
void renderNormalsVisualisation(const DrawCalls& draw_calls);
void renderTransparent(const DrawCalls& draw_calls,
unsigned render_target);
void renderShadows(const ShadowMatrices& shadow_matrices,
void renderShadows(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer);
void renderReflectiveShadowMap(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices,

View File

@ -183,7 +183,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
CVS->isShadowEnabled() && hasShadow)
{
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
m_geometry_passes.renderShadows(m_shadow_matrices,
m_geometry_passes.renderShadows(m_draw_calls,
m_shadow_matrices,
irr_driver->getRTT()->getShadowFrameBuffer());
PROFILER_POP_CPU_MARKER();
if (CVS->isGlobalIlluminationEnabled())