diff --git a/src/graphics/command_buffer.cpp b/src/graphics/command_buffer.cpp index 649e2d278..13b18c305 100644 --- a/src/graphics/command_buffer.cpp +++ b/src/graphics/command_buffer.cpp @@ -88,7 +88,7 @@ void CommandBuffer::fillMaterial(int material_id, std::vector &instanced_list, T *instance_buffer) { - m_offset[material_id] = m_instance_buffer_offset; + m_offset[material_id] = m_command_buffer_offset; FillInstances(mesh_map[material_id], instanced_list, instance_buffer, diff --git a/src/graphics/command_buffer.hpp b/src/graphics/command_buffer.hpp index 7629c54e4..13a00dc3f 100644 --- a/src/graphics/command_buffer.hpp +++ b/src/graphics/command_buffer.hpp @@ -110,7 +110,7 @@ protected: GLuint m_draw_indirect_cmd_id; DrawElementsIndirectCommand *m_draw_indirect_cmd; size_t *m_offset; - size_t *m_size; + size_t *m_size; size_t m_poly_count; size_t m_instance_buffer_offset; size_t m_command_buffer_offset; @@ -127,6 +127,9 @@ public: inline size_t getPolyCount() const {return m_poly_count;} + inline bool isEmpty(Material::ShaderType shader_type) const + { return m_size[static_cast(shader_type)] == 0;} + inline void bind() const { glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id); diff --git a/src/graphics/draw_calls.hpp b/src/graphics/draw_calls.hpp index 4eb18e7b7..c3edacc14 100644 --- a/src/graphics/draw_calls.hpp +++ b/src/graphics/draw_calls.hpp @@ -98,6 +98,8 @@ public: void renderParticlesList() const; inline void bindSolidCmd() const { m_solid_cmd_buffer.bind(); } + inline bool isSolidCmdEmpty(Material::ShaderType shader_type) const + { return m_solid_cmd_buffer.isEmpty(shader_type); } void drawIndirectSolidCmd(Material::ShaderType shader_type, int i) const; void multidrawIndirectSolidCmd(Material::ShaderType shader_type) const; }; diff --git a/src/graphics/geometry_passes.cpp b/src/graphics/geometry_passes.cpp index 47d4495e6..ab747f4a6 100644 --- a/src/graphics/geometry_passes.cpp +++ b/src/graphics/geometry_passes.cpp @@ -981,7 +981,7 @@ using namespace RenderGeometry; // ---------------------------------------------------------------------------- template -void renderMeshes1stPass() +void renderMeshes1stPass(const DrawCalls& draw_calls) { auto &meshes = T::List::getInstance()->SolidPass; T::FirstPassShader::getInstance()->use(); @@ -989,8 +989,6 @@ void renderMeshes1stPass() glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType)); for (unsigned i = 0; i < meshes.size(); i++) { - std::vector Textures; - std::vector Handles; GLMesh &mesh = *(STK::tuple_get<0>(meshes.at(i))); if (!CVS->isARBBaseInstanceUsable()) glBindVertexArray(mesh.vao); @@ -1012,14 +1010,13 @@ void renderMeshes1stPass() // ---------------------------------------------------------------------------- template -void renderInstancedMeshes1stPass(Args...args) +void renderInstancedMeshes1stPass(const DrawCalls& draw_calls, Args...args) { std::vector &meshes = T::InstancedList::getInstance()->SolidPass; T::InstancedFirstPassShader::getInstance()->use(); glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance)); for (unsigned i = 0; i < meshes.size(); i++) { - std::vector Textures; GLMesh *mesh = meshes[i]; #ifdef DEBUG if (mesh->VAOType != T::VertexType) @@ -1032,23 +1029,20 @@ void renderInstancedMeshes1stPass(Args...args) TexExpander::template expandTex(*mesh, T::FirstPassTextures); T::InstancedFirstPassShader::getInstance()->setUniforms(args...); - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand))); + draw_calls.drawIndirectSolidCmd(T::MaterialType, i); } } // renderInstancedMeshes1stPass // ---------------------------------------------------------------------------- template -void multidraw1stPass(Args...args) +void multidraw1stPass(const DrawCalls& draw_calls, Args...args) { T::InstancedFirstPassShader::getInstance()->use(); glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance)); - if (SolidPassCmd::getInstance()->Size[T::MaterialType]) + if (!draw_calls.isSolidCmdEmpty(T::MaterialType)) { T::InstancedFirstPassShader::getInstance()->setUniforms(args...); - glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)(SolidPassCmd::getInstance()->Offset[T::MaterialType] * sizeof(DrawElementsIndirectCommand)), - (int)SolidPassCmd::getInstance()->Size[T::MaterialType], - sizeof(DrawElementsIndirectCommand)); + draw_calls.multidrawIndirectSolidCmd(T::MaterialType); } } // multidraw1stPass @@ -1064,7 +1058,7 @@ void GeometryPasses::renderSolidFirstPass(const DrawCalls& draw_calls) m_wind_dir = getWindDir(); //TODO: why this function instead of Wind::getWind()? if (CVS->supportsIndirectInstancingRendering()) - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd); + draw_calls.bindSolidCmd(); { ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SOLID_PASS1)); @@ -1073,35 +1067,35 @@ void GeometryPasses::renderSolidFirstPass(const DrawCalls& draw_calls) draw_calls.renderImmediateDrawList(); //TODO: is it useful if AZDO enabled? - renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); - renderMeshes1stPass(); + renderMeshes1stPass(draw_calls); + renderMeshes1stPass(draw_calls); + renderMeshes1stPass(draw_calls); + renderMeshes1stPass(draw_calls); + renderMeshes1stPass(draw_calls); + renderMeshes1stPass(draw_calls); + renderMeshes1stPass(draw_calls); + renderMeshes1stPass(draw_calls); if (CVS->isAZDOEnabled()) { - multidraw1stPass(); - multidraw1stPass(); - multidraw1stPass(); - multidraw1stPass(); - multidraw1stPass(m_wind_dir); + multidraw1stPass(draw_calls); + multidraw1stPass(draw_calls); + multidraw1stPass(draw_calls); + multidraw1stPass(draw_calls); + multidraw1stPass(draw_calls, m_wind_dir); - multidraw1stPass(); - multidraw1stPass(); + multidraw1stPass(draw_calls); + multidraw1stPass(draw_calls); } else if (CVS->supportsIndirectInstancingRendering()) { - renderInstancedMeshes1stPass(); - renderInstancedMeshes1stPass(); - renderInstancedMeshes1stPass(); - renderInstancedMeshes1stPass(); - renderInstancedMeshes1stPass(m_wind_dir); - renderInstancedMeshes1stPass(); - renderInstancedMeshes1stPass(); + renderInstancedMeshes1stPass(draw_calls); + renderInstancedMeshes1stPass(draw_calls); + renderInstancedMeshes1stPass(draw_calls); + renderInstancedMeshes1stPass(draw_calls); + renderInstancedMeshes1stPass(draw_calls, m_wind_dir); + renderInstancedMeshes1stPass(draw_calls); + renderInstancedMeshes1stPass(draw_calls); } } } // renderSolidFirstPass @@ -1147,7 +1141,7 @@ void renderMeshes2ndPass( const std::vector &Prefilled_Handle, // ---------------------------------------------------------------------------- template -void renderInstancedMeshes2ndPass(const std::vector &Prefilled_tex, Args...args) +void renderInstancedMeshes2ndPass(const DrawCalls& draw_calls, const std::vector &Prefilled_tex, Args...args) { std::vector &meshes = T::InstancedList::getInstance()->SolidPass; T::InstancedSecondPassShader::getInstance()->use(); @@ -1160,31 +1154,25 @@ void renderInstancedMeshes2ndPass(const std::vector &Prefilled_tex, Args expandTex(*mesh, T::SecondPassTextures, Prefilled_tex[0], Prefilled_tex[1], Prefilled_tex[2]); T::InstancedSecondPassShader::getInstance()->setUniforms(args...); - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) - * sizeof(DrawElementsIndirectCommand))); + draw_calls.drawIndirectSolidCmd(T::MaterialType, i); } } // renderInstancedMeshes2ndPass // ---------------------------------------------------------------------------- template -void multidraw2ndPass(const std::vector &Handles, Args... args) +void multidraw2ndPass(const DrawCalls& draw_calls, const std::vector &Handles, Args... args) { T::InstancedSecondPassShader::getInstance()->use(); glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance)); uint64_t nulltex[10] = {}; - if (SolidPassCmd::getInstance()->Size[T::MaterialType]) + if (!draw_calls.isSolidCmdEmpty(T::MaterialType)) { HandleExpander::template expand(nulltex, T::SecondPassTextures, Handles[0], Handles[1], Handles[2]); T::InstancedSecondPassShader::getInstance()->setUniforms(args...); - glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)(SolidPassCmd::getInstance()->Offset[T::MaterialType] - * sizeof(DrawElementsIndirectCommand)), - (int)SolidPassCmd::getInstance()->Size[T::MaterialType], - (int)sizeof(DrawElementsIndirectCommand)); + draw_calls.multidrawIndirectSolidCmd(T::MaterialType); } } // multidraw2ndPass @@ -1225,9 +1213,8 @@ void GeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls, } if (CVS->supportsIndirectInstancingRendering()) - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, - SolidPassCmd::getInstance()->drawindirectcmd); - + draw_calls.bindSolidCmd(); + { ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SOLID_PASS2)); @@ -1252,12 +1239,12 @@ void GeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls, if (CVS->isAZDOEnabled()) { - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0, 0)); + multidraw2ndPass(draw_calls, createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); + multidraw2ndPass(draw_calls, createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); + multidraw2ndPass(draw_calls, createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); + multidraw2ndPass(draw_calls, createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); + multidraw2ndPass(draw_calls, createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); + multidraw2ndPass(draw_calls, createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0, 0)); // template does not work with template due to extra depth texture { @@ -1265,29 +1252,25 @@ void GeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls, glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(GrassMat::VertexType, GrassMat::Instance)); uint64_t nulltex[10] = {}; - if (SolidPassCmd::getInstance()->Size[GrassMat::MaterialType]) + if (!draw_calls.isSolidCmdEmpty(GrassMat::MaterialType)) { HandleExpander ::expand(nulltex, GrassMat::SecondPassTextures, DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle); GrassMat::InstancedSecondPassShader::getInstance()->setUniforms(m_wind_dir, irr_driver->getSunDirection()); - glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)(SolidPassCmd::getInstance()->Offset[GrassMat::MaterialType] - * sizeof(DrawElementsIndirectCommand)), - (int)SolidPassCmd::getInstance()->Size[GrassMat::MaterialType], - (int)sizeof(DrawElementsIndirectCommand)); + draw_calls.multidrawIndirectSolidCmd(GrassMat::MaterialType); } } } else if (CVS->supportsIndirectInstancingRendering()) { - renderInstancedMeshes2ndPass(DiffSpecSSAOTex); - renderInstancedMeshes2ndPass(DiffSpecSSAOTex); - renderInstancedMeshes2ndPass(DiffSpecSSAOTex); - renderInstancedMeshes2ndPass(DiffSpecSSAOTex); - renderInstancedMeshes2ndPass(DiffSpecSSAOTex); - renderInstancedMeshes2ndPass(DiffSpecSSAOTex); + renderInstancedMeshes2ndPass(draw_calls, DiffSpecSSAOTex); + renderInstancedMeshes2ndPass(draw_calls, DiffSpecSSAOTex); + renderInstancedMeshes2ndPass(draw_calls, DiffSpecSSAOTex); + renderInstancedMeshes2ndPass(draw_calls, DiffSpecSSAOTex); + renderInstancedMeshes2ndPass(draw_calls, DiffSpecSSAOTex); + renderInstancedMeshes2ndPass(draw_calls, DiffSpecSSAOTex); // template does not work with template due to extra depth texture { @@ -1304,9 +1287,7 @@ void GeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls, irr_driver->getDepthStencilTexture()); GrassMat::InstancedSecondPassShader::getInstance() ->setUniforms(m_wind_dir, irr_driver->getSunDirection()); - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)((SolidPassCmd::getInstance()->Offset[GrassMat::MaterialType] + i) - * sizeof(DrawElementsIndirectCommand))); + draw_calls.drawIndirectSolidCmd(GrassMat::MaterialType, i); } } } @@ -1315,7 +1296,7 @@ void GeometryPasses::renderSolidSecondPass( const DrawCalls& draw_calls, // ---------------------------------------------------------------------------- template -static void renderInstancedMeshNormals() +static void renderInstancedMeshNormals(const DrawCalls& draw_calls) { std::vector &meshes = T::InstancedList::getInstance()->SolidPass; NormalVisualizer::getInstance()->use(); @@ -1323,47 +1304,42 @@ static void renderInstancedMeshNormals() for (unsigned i = 0; i < meshes.size(); i++) { NormalVisualizer::getInstance()->setUniforms(video::SColor(255, 0, 255, 0)); - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) - * sizeof(DrawElementsIndirectCommand))); + draw_calls.drawIndirectSolidCmd(T::MaterialType, i); } } // renderInstancedMeshNormals // ---------------------------------------------------------------------------- template -static void renderMultiMeshNormals() +static void renderMultiMeshNormals(const DrawCalls& draw_calls) { NormalVisualizer::getInstance()->use(); glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance)); - if (SolidPassCmd::getInstance()->Size[T::MaterialType]) + if (!draw_calls.isSolidCmdEmpty(T::MaterialType)) { NormalVisualizer::getInstance()->setUniforms(video::SColor(255, 0, 255, 0)); - glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)(SolidPassCmd::getInstance()->Offset[T::MaterialType] * sizeof(DrawElementsIndirectCommand)), - (int)SolidPassCmd::getInstance()->Size[T::MaterialType], - (int)sizeof(DrawElementsIndirectCommand)); + draw_calls.multidrawIndirectSolidCmd(T::MaterialType); } } // renderMultiMeshNormals // ---------------------------------------------------------------------------- -void GeometryPasses::renderNormalsVisualisation() +void GeometryPasses::renderNormalsVisualisation(const DrawCalls& draw_calls) { if (CVS->isAZDOEnabled()) { - renderMultiMeshNormals(); - renderMultiMeshNormals(); - renderMultiMeshNormals(); - renderMultiMeshNormals(); - renderMultiMeshNormals(); - renderMultiMeshNormals(); + renderMultiMeshNormals(draw_calls); + renderMultiMeshNormals(draw_calls); + renderMultiMeshNormals(draw_calls); + renderMultiMeshNormals(draw_calls); + renderMultiMeshNormals(draw_calls); + renderMultiMeshNormals(draw_calls); } else if (CVS->supportsIndirectInstancingRendering()) { - renderInstancedMeshNormals(); - renderInstancedMeshNormals(); - renderInstancedMeshNormals(); - renderInstancedMeshNormals(); - renderInstancedMeshNormals(); - renderInstancedMeshNormals(); + renderInstancedMeshNormals(draw_calls); + renderInstancedMeshNormals(draw_calls); + renderInstancedMeshNormals(draw_calls); + renderInstancedMeshNormals(draw_calls); + renderInstancedMeshNormals(draw_calls); + renderInstancedMeshNormals(draw_calls); } } // renderNormalsVisualisation diff --git a/src/graphics/geometry_passes.hpp b/src/graphics/geometry_passes.hpp index e960d24e5..c354f0952 100644 --- a/src/graphics/geometry_passes.hpp +++ b/src/graphics/geometry_passes.hpp @@ -39,7 +39,7 @@ public: unsigned render_target_diffuse, unsigned render_target_specular, unsigned render_target_half_red); - void renderNormalsVisualisation(); + void renderNormalsVisualisation(const DrawCalls& draw_calls); void renderTransparent(const DrawCalls& draw_calls, unsigned render_target); void renderShadows(const ShadowMatrices& shadow_matrices, diff --git a/src/graphics/shader_based_renderer.cpp b/src/graphics/shader_based_renderer.cpp index 89ddc0608..8913b469b 100644 --- a/src/graphics/shader_based_renderer.cpp +++ b/src/graphics/shader_based_renderer.cpp @@ -289,7 +289,7 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode, if (irr_driver->getNormals()) { rtts->getFBO(FBO_NORMAL_AND_DEPTHS).bind(); - m_geometry_passes.renderNormalsVisualisation(); + m_geometry_passes.renderNormalsVisualisation(m_draw_calls); rtts->getFBO(FBO_COLORS).bind(); } @@ -388,7 +388,7 @@ void ShaderBasedRenderer::renderParticles() glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - m_draw_calls.renderBillboardList(); + m_draw_calls.renderParticlesList(); // m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT); } @@ -491,17 +491,17 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera) ShaderBasedRenderer::ShaderBasedRenderer() { - /*if (CVS->isAZDOEnabled()) + if (CVS->isAZDOEnabled()) m_solid_first_pass = new AZDOSolidFirstPass(); else if (CVS->supportsIndirectInstancingRendering()) m_solid_first_pass = new IndirectInstancedSolidFirstPass(); else - m_solid_first_pass = new GL3SolidFirstPass();*/ + m_solid_first_pass = new GL3SolidFirstPass(); } ShaderBasedRenderer::~ShaderBasedRenderer() { - //delete m_solid_first_pass; + delete m_solid_first_pass; } void ShaderBasedRenderer::addSunLight(const core::vector3df &pos) { diff --git a/src/graphics/shader_based_renderer.hpp b/src/graphics/shader_based_renderer.hpp index 2dd25588e..0624e05e2 100644 --- a/src/graphics/shader_based_renderer.hpp +++ b/src/graphics/shader_based_renderer.hpp @@ -37,7 +37,7 @@ private: ShadowMatrices m_shadow_matrices; irr::core::vector3df m_wind_dir; - //SolidFirstPass *m_solid_first_pass; + SolidFirstPass *m_solid_first_pass; void compressPowerUpTextures(); void setOverrideMaterial();