Removed GlowPassCmd singleton, now use new CommandBuffer class to render glow

This commit is contained in:
Elderme
2015-11-20 22:16:58 +01:00
parent ea7fc05af4
commit db52543655
10 changed files with 143 additions and 199 deletions

View File

@@ -221,29 +221,8 @@ GlowCommandBuffer::GlowCommandBuffer()
void GlowCommandBuffer::fill(MeshMap *mesh_map)
{
clearMeshes();
GlowInstanceData *glow_instance_buffer;
if (CVS->supportsAsyncInstanceUpload())
{
glow_instance_buffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER,
VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
glow_instance_buffer =
(GlowInstanceData*)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);
}
fillMaterial( 0, mesh_map, glow_instance_buffer);
unmapBuffers();
fillInstanceData<GlowInstanceData>(mesh_map,
createVector<int>(0),
InstanceTypeGlow);
unmapBuffers();
} //GlowCommandBuffer::fill

View File

@@ -225,7 +225,7 @@ public:
{
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
}
};
}; //CommandBuffer
class SolidCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADERTYPE_COUNT)>
@@ -361,7 +361,7 @@ public:
sizeof(DrawElementsIndirectCommand));
}
} // multidrawNormals
};
}; //SolidCommandBuffer
class ShadowCommandBuffer: public CommandBuffer<4*static_cast<int>(Material::SHADERTYPE_COUNT)>
{
@@ -416,7 +416,7 @@ public:
} // multidrawShadow
};
}; //ShadowCommandBuffer
class ReflectiveShadowMapCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADERTYPE_COUNT)>
{
@@ -435,7 +435,6 @@ public:
InstanceTypeRSM));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
@@ -465,13 +464,56 @@ public:
}
} // multidraw
};
}; //ReflectiveShadowMapCommandBuffer
// ============================================================================
class InstancedColorizeShader : public Shader<InstancedColorizeShader>
{
public:
InstancedColorizeShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "utils/getworldmatrix.vert",
GL_VERTEX_SHADER, "glow_object.vert",
GL_FRAGMENT_SHADER, "glow_object.frag");
assignUniforms();
} // InstancedColorizeShader
}; // InstancedColorizeShader
class GlowCommandBuffer: public CommandBuffer<1>
{
public:
GlowCommandBuffer();
void fill(MeshMap *mesh_map);
void drawIndirect() const
{
InstancedColorizeShader::getInstance()->use();
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(irr::video::EVT_STANDARD,
InstanceTypeGlow));
for (unsigned i = 0; i < m_meshes[0].size(); i++)
{
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[0] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirect
void multidraw() const
{
InstancedColorizeShader::getInstance()->use();
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(irr::video::EVT_STANDARD,
InstanceTypeGlow));
if (m_size[0])
{
glMultiDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)(m_offset[0] * sizeof(DrawElementsIndirectCommand)),
(int) m_size[0],
sizeof(DrawElementsIndirectCommand));
}
} // multidraw
};
#endif //HEADER_COMMAND_BUFFER_HPP

View File

@@ -476,15 +476,10 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
if (!CVS->supportsIndirectInstancingRendering())
return;
GlowInstanceData *GlowInstanceBuffer;
DrawElementsIndirectCommand *GlowCmdBuffer;
int enableOpenMP = 0;
if (CVS->supportsAsyncInstanceUpload())
{
GlowInstanceBuffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
GlowCmdBuffer = GlowPassCmd::getInstance()->Ptr;
enableOpenMP = 1;
}
@@ -498,7 +493,6 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
//TODO: split command upload in separate functions
size_t SolidPoly = 0, ShadowPoly = 0, MiscPoly = 0;
PROFILER_PUSH_CPU_MARKER("- Draw Command upload", 0xFF, 0x0, 0xFF);
@@ -511,37 +505,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
}
#pragma omp section
{
size_t offset = 0, current_cmd = 0;
if (!CVS->supportsAsyncInstanceUpload())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
GlowInstanceBuffer = (GlowInstanceData*)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, GlowPassCmd::getInstance()->drawindirectcmd);
GlowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Glow
if (CVS->supportsIndirectInstancingRendering())
GlowPassCmd::getInstance()->Offset = offset; // Store command buffer offset
auto It = m_glow_pass_mesh.begin(), E = m_glow_pass_mesh.end();//TODO
for (; It != E; ++It)
{
size_t Polycnt = 0;
FillInstances_impl<GlowInstanceData>(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd, Polycnt);
if (!CVS->isAZDOEnabled())
ListInstancedGlow::getInstance()->push_back(It->second.front().first);
}
if (CVS->isAZDOEnabled())
GlowPassCmd::getInstance()->Size = current_cmd - GlowPassCmd::getInstance()->Offset;
if (!CVS->supportsAsyncInstanceUpload())
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
m_glow_cmd_buffer.fill(&m_glow_pass_mesh);
}
#pragma omp section
{
@@ -701,3 +665,14 @@ void DrawCalls::multidrawReflectiveShadowMaps(const core::matrix4 &rsm_matrix) c
m_reflective_shadow_map_cmd_buffer.multidraw<DetailMat>(rsm_matrix);
}
// ----------------------------------------------------------------------------
void DrawCalls::drawIndirectGlow() const
{
m_glow_cmd_buffer.drawIndirect();
}
// ----------------------------------------------------------------------------
void DrawCalls::multidrawGlow() const
{
m_glow_cmd_buffer.multidraw();
}

View File

@@ -91,6 +91,7 @@ public:
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(); }
inline void bindGlowCmd() const { m_glow_cmd_buffer.bind(); }
void drawIndirectSolidFirstPass() const;
void multidrawSolidFirstPass() const;
@@ -105,6 +106,9 @@ public:
void drawIndirectReflectiveShadowMaps(const core::matrix4 &rsm_matrix) const;
void multidrawReflectiveShadowMaps(const core::matrix4 &rsm_matrix) const;
void drawIndirectGlow() const;
void multidrawGlow() const;
};
#endif //HEADER_DRAW_CALLS_HPP

View File

@@ -27,6 +27,7 @@
#include "modes/world.hpp"
#include "utils/profiler.hpp"
#include "utils/tuple.hpp"
#include <SColor.h>
#include <S3DVertex.h>
@@ -339,6 +340,77 @@ void GeometryPasses::renderNormalsVisualisation(const DrawCalls& draw_calls)
}
} // renderNormalsVisualisation
// ----------------------------------------------------------------------------
void GeometryPasses::renderGlow(const DrawCalls& draw_calls, std::vector<GlowData>& glows)
{
irr_driver->getSceneManager()->setCurrentRendertime(scene::ESNRP_SOLID);
irr_driver->getRTT()->getFBO(FBO_TMP1_WITH_DS).bind();
glClearStencil(0);
glClearColor(0, 0, 0, 0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
const u32 glowcount = (int)glows.size();
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, ~0);
glEnable(GL_STENCIL_TEST);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
if (CVS->isARBBaseInstanceUsable())
glBindVertexArray(VAOManager::getInstance()->getVAO(irr::video::EVT_STANDARD));
for (u32 i = 0; i < glowcount; i++)
{
const GlowData &dat = glows[i];
scene::ISceneNode * cur = dat.node;
STKMeshSceneNode *node = static_cast<STKMeshSceneNode *>(cur);
node->setGlowColors(irr::video::SColor(0, (unsigned) (dat.b * 255.f), (unsigned)(dat.g * 255.f), (unsigned)(dat.r * 255.f)));
if (!CVS->supportsIndirectInstancingRendering())
node->render();
}
if (CVS->supportsIndirectInstancingRendering())
{
draw_calls.bindGlowCmd();
if (CVS->isAZDOEnabled())
{
draw_calls.multidrawGlow();
}
else
{
draw_calls.drawIndirectGlow();
}
}
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
// To half
FrameBuffer::Blit(irr_driver->getFBO(FBO_TMP1_WITH_DS), irr_driver->getFBO(FBO_HALF1), GL_COLOR_BUFFER_BIT, GL_LINEAR);
// To quarter
FrameBuffer::Blit(irr_driver->getFBO(FBO_HALF1), irr_driver->getFBO(FBO_QUARTER1), GL_COLOR_BUFFER_BIT, GL_LINEAR);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glStencilFunc(GL_EQUAL, 0, ~0);
glEnable(GL_STENCIL_TEST);
irr_driver->getRTT()->getFBO(FBO_COLORS).bind();
irr_driver->getPostProcessing()->renderGlow(irr_driver->getRTT()->getRenderTarget(RTT_QUARTER1));
glDisable(GL_STENCIL_TEST);
}
// ----------------------------------------------------------------------------
template<typename Shader, enum video::E_VERTEX_TYPE VertexType, int...List,
typename... TupleType>

View File

@@ -40,6 +40,9 @@ public:
unsigned render_target_specular,
unsigned render_target_half_red);
void renderNormalsVisualisation(const DrawCalls& draw_calls);
void renderGlow(const DrawCalls& draw_calls, std::vector<GlowData>& glows);
void renderTransparent(const DrawCalls& draw_calls,
unsigned render_target);
void renderShadows(const DrawCalls& draw_calls,

View File

@@ -816,7 +816,6 @@ void IrrDriver::applyResolutionSettings()
// (we're sure to update main.cpp at some point and forget this one...)
ShaderBase::updateShaders();
VAOManager::getInstance()->kill();
GlowPassCmd::getInstance()->kill();
resetTextureTable();
// initDevice will drop the current device.
if (CVS->isGLSL())

View File

@@ -44,21 +44,6 @@
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
// ============================================================================
class InstancedColorizeShader : public Shader<InstancedColorizeShader>
{
public:
InstancedColorizeShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "utils/getworldmatrix.vert",
GL_VERTEX_SHADER, "glow_object.vert",
GL_FRAGMENT_SHADER, "glow_object.frag");
assignUniforms();
} // InstancedColorizeShader
}; // InstancedColorizeShader
// ----------------------------------------------------------------------------
void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
{
@@ -70,79 +55,4 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
// ----------------------------------------------------------------------------
void IrrDriver::renderGlow(std::vector<GlowData>& glows)
{
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
m_rtts->getFBO(FBO_TMP1_WITH_DS).bind();
glClearStencil(0);
glClearColor(0, 0, 0, 0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
const u32 glowcount = (int)glows.size();
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, ~0);
glEnable(GL_STENCIL_TEST);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
if (CVS->isARBBaseInstanceUsable())
glBindVertexArray(VAOManager::getInstance()->getVAO(EVT_STANDARD));
for (u32 i = 0; i < glowcount; i++)
{
const GlowData &dat = glows[i];
scene::ISceneNode * cur = dat.node;
STKMeshSceneNode *node = static_cast<STKMeshSceneNode *>(cur);
node->setGlowColors(SColor(0, (unsigned) (dat.b * 255.f), (unsigned)(dat.g * 255.f), (unsigned)(dat.r * 255.f)));
if (!CVS->supportsIndirectInstancingRendering())
node->render();
}
if (CVS->supportsIndirectInstancingRendering())
{
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
InstancedColorizeShader::getInstance()->use();
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeGlow));
if (CVS->isAZDOEnabled())
{
if (GlowPassCmd::getInstance()->Size)
{
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
(const void*)(GlowPassCmd::getInstance()->Offset * sizeof(DrawElementsIndirectCommand)),
(int)GlowPassCmd::getInstance()->Size,
sizeof(DrawElementsIndirectCommand));
}
}
else
{
for (unsigned i = 0; i < ListInstancedGlow::getInstance()->size(); i++)
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((GlowPassCmd::getInstance()->Offset + i) * sizeof(DrawElementsIndirectCommand)));
}
}
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDisable(GL_STENCIL_TEST);
glDisable(GL_BLEND);
// To half
FrameBuffer::Blit(irr_driver->getFBO(FBO_TMP1_WITH_DS), irr_driver->getFBO(FBO_HALF1), GL_COLOR_BUFFER_BIT, GL_LINEAR);
// To quarter
FrameBuffer::Blit(irr_driver->getFBO(FBO_HALF1), irr_driver->getFBO(FBO_QUARTER1), GL_COLOR_BUFFER_BIT, GL_LINEAR);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glStencilFunc(GL_EQUAL, 0, ~0);
glEnable(GL_STENCIL_TEST);
m_rtts->getFBO(FBO_COLORS).bind();
m_post_processing->renderGlow(m_rtts->getRenderTarget(RTT_QUARTER1));
glDisable(GL_STENCIL_TEST);
}

View File

@@ -347,7 +347,7 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
{
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GLOW));
irr_driver->setPhase(GLOW_PASS);
irr_driver->renderGlow(glows);
m_geometry_passes.renderGlow(m_draw_calls, glows);
} // end glow
PROFILER_POP_CPU_MARKER();

View File

@@ -27,46 +27,6 @@
#include "graphics/gpu_particles.hpp"
#include "graphics/stk_billboard.hpp"
#include "graphics/stk_mesh.hpp"
#include "utils/singleton.hpp"
template<typename T, int nb_cascades, int nb_materials>
class CommandBufferOld : public Singleton<T>
{
public:
GLuint drawindirectcmd;
DrawElementsIndirectCommand *Ptr;
//size_t Offset[nb_cascades][nb_materials];
//size_t Size[nb_cascades][nb_materials];
CommandBufferOld()
{
glGenBuffers(1, &drawindirectcmd);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
if (CVS->supportsAsyncInstanceUpload())
{
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
}
else
{
glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW);
}
}
void bind()
{
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
}
};
class GlowPassCmd : public CommandBufferOld<GlowPassCmd, 1, 1>
{
public:
size_t Offset, Size;
};
//TODO