1 #include <Engine/Data/ShaderConfigFactory.hpp>
2 #include <Engine/Data/ShaderConfiguration.hpp>
3 #include <Engine/Rendering/ForwardRenderer.hpp>
5 #include <Core/Containers/MakeShared.hpp>
6 #include <Core/Geometry/TopologicalMesh.hpp>
7 #include <Core/Utils/Color.hpp>
8 #include <Core/Utils/Log.hpp>
10 #include <Engine/Data/LambertianMaterial.hpp>
11 #include <Engine/Data/Material.hpp>
12 #include <Engine/Data/RenderParameters.hpp>
13 #include <Engine/Data/ShaderProgramManager.hpp>
14 #include <Engine/Data/Texture.hpp>
15 #include <Engine/Data/ViewingParameters.hpp>
16 #include <Engine/OpenGL.hpp>
17 #include <Engine/Rendering/DebugRender.hpp>
18 #include <Engine/Rendering/RenderObject.hpp>
19 #include <Engine/Scene/DefaultLightManager.hpp>
20 #include <Engine/Scene/Light.hpp>
21 #include <globjects/Framebuffer.h>
24 #include <Core/RaCore.hpp>
25 #include <Engine/Data/ShaderProgram.hpp>
26 #include <Engine/Scene/GeometryComponent.hpp>
28 #include <Engine/Scene/SystemDisplay.hpp>
32 #include <globjects/Texture.h>
36 using namespace Core::Utils;
41 const GLenum buffers[] = { GL_COLOR_ATTACHMENT0,
48 GL_COLOR_ATTACHMENT7 };
51 ForwardRenderer::ForwardRenderer() : Renderer() {}
53 ForwardRenderer::~ForwardRenderer() =
default;
55 void ForwardRenderer::initializeInternal() {
60 Ra::Engine::RadiumEngine::getInstance()->registerSystem(
"DefaultLightManager", lightManager );
61 m_lightmanagers.push_back( lightManager );
63 if ( !DebugRender::getInstance() ) {
64 DebugRender::createInstance();
65 DebugRender::getInstance()->initialize();
69 void ForwardRenderer::initShaders() {
71 auto resourcesRootDir { RadiumEngine::getInstance()->getResourcesDir() };
72 m_shaderProgramManager->addShaderProgram(
74 resourcesRootDir +
"Shaders/2DShaders/Basic2D.vert.glsl",
75 resourcesRootDir +
"Shaders/2DShaders/Hdr2Ldr.frag.glsl" } );
76 m_shaderProgramManager->addShaderProgram(
78 resourcesRootDir +
"Shaders/2DShaders/Basic2D.vert.glsl",
79 resourcesRootDir +
"Shaders/2DShaders/ComposeOIT.frag.glsl" } );
81 Data::ShaderConfiguration wireframe { {
"Wireframe" },
82 resourcesRootDir +
"Shaders/Lines/Wireframe.vert.glsl",
83 resourcesRootDir +
"Shaders/Lines/Wireframe.frag.glsl" };
84 wireframe.addShader( Data::ShaderType::ShaderType_GEOMETRY,
85 resourcesRootDir +
"Shaders/Lines/Wireframe.geom.glsl" );
86 Data::ShaderConfigurationFactory::addConfiguration( wireframe );
87 m_shaderProgramManager->addShaderProgram( wireframe );
90 void ForwardRenderer::initBuffers() {
91 m_fbo = std::make_unique<globjects::Framebuffer>();
92 m_oitFbo = std::make_unique<globjects::Framebuffer>();
93 m_postprocessFbo = std::make_unique<globjects::Framebuffer>();
94 m_uiXrayFbo = std::make_unique<globjects::Framebuffer>();
95 m_volumeFbo = std::make_unique<globjects::Framebuffer>();
98 Data::TextureParameters texparams;
99 texparams.width = m_width;
100 texparams.height = m_height;
101 texparams.target = GL_TEXTURE_2D;
104 texparams.minFilter = GL_NEAREST;
105 texparams.magFilter = GL_NEAREST;
106 texparams.internalFormat = GL_DEPTH_COMPONENT24;
107 texparams.format = GL_DEPTH_COMPONENT;
108 texparams.type = GL_UNSIGNED_INT;
109 texparams.name =
"Depth (fw renderer)";
110 m_textures[RendererTextures_Depth] = std::make_unique<Data::Texture>( texparams );
113 texparams.internalFormat = GL_RGBA32F;
114 texparams.format = GL_RGBA;
115 texparams.type = GL_SCALAR;
116 texparams.minFilter = GL_LINEAR;
117 texparams.magFilter = GL_LINEAR;
119 texparams.name =
"HDR";
120 m_textures[RendererTextures_HDR] = std::make_unique<Data::Texture>( texparams );
122 texparams.name =
"Normal";
123 m_textures[RendererTextures_Normal] = std::make_unique<Data::Texture>( texparams );
125 texparams.name =
"Diffuse";
126 m_textures[RendererTextures_Diffuse] = std::make_unique<Data::Texture>( texparams );
128 texparams.name =
"Specular";
129 m_textures[RendererTextures_Specular] = std::make_unique<Data::Texture>( texparams );
131 texparams.name =
"OIT Accum";
132 m_textures[RendererTextures_OITAccum] = std::make_unique<Data::Texture>( texparams );
134 texparams.name =
"OIT Revealage";
135 m_textures[RendererTextures_OITRevealage] = std::make_unique<Data::Texture>( texparams );
137 texparams.name =
"Volume";
138 m_textures[RendererTextures_Volume] = std::make_unique<Data::Texture>( texparams );
140 m_secondaryTextures[
"Depth (fw)"] = m_textures[RendererTextures_Depth].get();
141 m_secondaryTextures[
"HDR Texture"] = m_textures[RendererTextures_HDR].get();
142 m_secondaryTextures[
"Normal Texture"] = m_textures[RendererTextures_Normal].get();
143 m_secondaryTextures[
"Diffuse Texture"] = m_textures[RendererTextures_Diffuse].get();
144 m_secondaryTextures[
"Specular Texture"] = m_textures[RendererTextures_Specular].get();
145 m_secondaryTextures[
"OIT Accum"] = m_textures[RendererTextures_OITAccum].get();
146 m_secondaryTextures[
"OIT Revealage"] = m_textures[RendererTextures_OITRevealage].get();
149 m_secondaryTextures[
"Volume"] = m_textures[RendererTextures_Volume].get();
153 CORE_UNUSED( renderData );
158 m_transparentRenderObjects.clear();
159 m_volumetricRenderObjects.clear();
160 for (
auto it = m_fancyRenderObjects.begin(); it != m_fancyRenderObjects.end(); ) {
161 if ( ( *it )->isTransparent() ) {
162 m_transparentRenderObjects.push_back( *it );
163 it = m_fancyRenderObjects.erase( it );
166 auto material = ( *it )->getMaterial();
168 material->getMaterialAspect() == Data::Material::MaterialAspect::MAT_DENSITY ) {
169 m_volumetricRenderObjects.push_back( *it );
170 it = m_fancyRenderObjects.erase( it );
175 m_fancyTransparentCount = m_transparentRenderObjects.size();
176 m_fancyVolumetricCount = m_volumetricRenderObjects.size();
179 if ( m_fancyRenderObjects.size() < m_wireframes.size() ) { m_wireframes.clear(); }
182 template <
typename IndexContainerType>
184 IndexContainerType& other ) {
186 for (
const auto& index : other ) {
187 auto s = index.size();
188 for (
unsigned int i = 0; i < s; ++i ) {
190 int i2 = index[( i + 1 ) % s];
191 if ( i1 > i2 ) std::swap( i1, i2 );
192 indices.emplace_back( i1, i2 );
196 std::sort( indices.begin(),
198 [](
const Core::Geometry::LineMesh::IndexType& a,
199 const Core::Geometry::LineMesh::IndexType& b ) {
200 return a[0] < b[0] || ( a[0] == b[0] && a[1] < b[1] );
202 indices.erase( std::unique( indices.begin(), indices.end() ), indices.end() );
207 template <
typename CoreGeometry>
208 class VerticesUpdater
211 VerticesUpdater( std::shared_ptr<Data::LineMesh> disp, CoreGeometry& core ) :
212 m_disp { disp }, m_core { core } {};
214 void operator()() { m_disp->getCoreGeometry().setVertices( m_core.vertices() ); }
215 std::shared_ptr<Data::LineMesh> m_disp;
216 CoreGeometry& m_core;
219 template <
typename CoreGeometry>
223 IndicesUpdater( std::shared_ptr<Data::LineMesh> disp, CoreGeometry& core ) :
224 m_disp { disp }, m_core { core } {};
227 auto lineIndices = m_disp->getCoreGeometry().getIndicesWithLock();
228 computeIndices( lineIndices, m_core.getIndices() );
229 m_disp->getCoreGeometry().indicesUnlock();
231 std::shared_ptr<Data::LineMesh> m_disp;
232 CoreGeometry& m_core;
236 template <
typename CoreGeometry>
237 void setupLineMesh( std::shared_ptr<Data::LineMesh>& disp, CoreGeometry& core ) {
239 Core::Geometry::LineMesh lines;
240 Core::Geometry::LineMesh::IndexContainerType indices;
242 lines.setVertices( core.vertices() );
243 computeIndices( indices, core.getIndices() );
244 if ( indices.size() > 0 ) {
245 lines.setIndices( std::move( indices ) );
247 Ra::Core::make_shared<Data::LineMesh>( std::string(
"wireframe" ), std::move( lines ) );
251 auto handle = core.template getAttribHandle<typename CoreGeometry::Point>(
252 Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::VERTEX_POSITION ) );
253 core.vertexAttribs().getAttrib( handle ).attach( VerticesUpdater( disp, core ) );
254 core.attach( IndicesUpdater( disp, core ) );
256 else { disp.reset(); }
263 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
264 GL_ASSERT( glDepthMask( GL_TRUE ) );
265 GL_ASSERT( glColorMask( 1, 1, 1, 1 ) );
267 GL_ASSERT( glDrawBuffers( 4, buffers ) );
270 glEnable( GL_POLYGON_OFFSET_FILL );
271 glPolygonOffset( 1.f, 3.f );
274 else { glDisable( GL_POLYGON_OFFSET_FILL ); }
275 static const auto clearZeros = Core::Utils::Color::Black().cast<GL_SCALAR_PLAIN>().eval();
276 static const auto clearOnes = Core::Utils::Color::White().cast<GL_SCALAR_PLAIN>().eval();
277 static const float clearDepth { 1.0f };
280 auto bgColor = getBackgroundColor().cast<GL_SCALAR_PLAIN>().eval();
281 GL_ASSERT( glClearBufferfv( GL_COLOR, 0, bgColor.data() ) );
282 GL_ASSERT( glClearBufferfv( GL_COLOR, 1, clearZeros.data() ) );
283 GL_ASSERT( glClearBufferfv( GL_COLOR, 2, clearZeros.data() ) );
284 GL_ASSERT( glClearBufferfv( GL_COLOR, 3, clearZeros.data() ) );
285 GL_ASSERT( glClearBufferfv( GL_DEPTH, 0, &clearDepth ) );
288 renderBackground( renderData );
291 GL_ASSERT( glDepthFunc( GL_LESS ) );
292 GL_ASSERT( glDisable( GL_BLEND ) );
293 GL_ASSERT( glPointSize( 3.f ) );
298 for (
const auto& ro : m_fancyRenderObjects ) {
299 ro->render( {}, renderData, DefaultRenderingPasses::Z_PREPASS );
305 for (
const auto& ro : m_transparentRenderObjects ) {
306 ro->render( {}, renderData, DefaultRenderingPasses::Z_PREPASS );
311 GL_ASSERT( glDepthFunc( GL_LEQUAL ) );
312 GL_ASSERT( glDepthMask( GL_FALSE ) );
314 GL_ASSERT( glEnable( GL_BLEND ) );
315 GL_ASSERT( glBlendFunc( GL_ONE, GL_ONE ) );
317 GL_ASSERT( glDrawBuffers( 1, buffers ) );
322 if ( m_lightmanagers[0]->count() > 0 ) {
324 for (
size_t i = 0; i < m_lightmanagers[0]->count(); ++i ) {
325 const auto l = m_lightmanagers[0]->getLight( i );
326 for (
const auto& ro : m_fancyRenderObjects ) {
328 l->getRenderParameters(), renderData, DefaultRenderingPasses::LIGHTING_OPAQUE );
332 for (
const auto& ro : m_transparentRenderObjects ) {
334 l->getRenderParameters(), renderData, DefaultRenderingPasses::LIGHTING_OPAQUE );
338 else { LOG( logINFO ) <<
"Opaque : no light sources, unable to render"; }
341 if ( !m_transparentRenderObjects.empty() ) {
346 GL_ASSERT( glDrawBuffers( 2, buffers ) );
347 GL_ASSERT( glClearBufferfv( GL_COLOR, 0, clearZeros.data() ) );
348 GL_ASSERT( glClearBufferfv( GL_COLOR, 1, clearOnes.data() ) );
350 GL_ASSERT( glDepthFunc( GL_LESS ) );
351 GL_ASSERT( glEnable( GL_BLEND ) );
353 GL_ASSERT( glBlendEquation( GL_FUNC_ADD ) );
354 GL_ASSERT( glBlendFunci( 0, GL_ONE, GL_ONE ) );
355 GL_ASSERT( glBlendFunci( 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA ) );
357 if ( m_lightmanagers[0]->count() > 0 ) {
359 for (
size_t i = 0; i < m_lightmanagers[0]->count(); ++i ) {
360 const auto l = m_lightmanagers[0]->getLight( i );
362 for (
const auto& ro : m_transparentRenderObjects ) {
363 ro->render( l->getRenderParameters(),
365 DefaultRenderingPasses::LIGHTING_TRANSPARENT );
369 else { LOG( logINFO ) <<
"Transparent : no light sources, unable to render"; }
374 GL_ASSERT( glDrawBuffers( 1, buffers ) );
375 GL_ASSERT( glDisable( GL_DEPTH_TEST ) );
376 GL_ASSERT( glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA ) );
378 auto shader = m_shaderProgramManager->getShaderProgram(
"ComposeOIT" );
380 shader->setUniform(
"u_OITSumColor", m_textures[RendererTextures_OITAccum].get(), 0 );
382 "u_OITSumWeight", m_textures[RendererTextures_OITRevealage].get(), 1 );
384 m_quadMesh->render( shader );
386 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
393 if ( m_lightmanagers[0]->count() > 0 ) {
394 if ( !m_volumetricRenderObjects.empty() ) {
397 GL_ASSERT( glDrawBuffers( 1, buffers ) );
398 static const auto alpha = Core::Utils::Color::Alpha().cast<GL_SCALAR_PLAIN>().eval();
399 GL_ASSERT( glClearBufferfv( GL_COLOR, 0, alpha.data() ) );
400 GL_ASSERT( glDisable( GL_BLEND ) );
403 composeParams.
addParameter(
"imageColor", m_textures[RendererTextures_HDR].get() );
404 composeParams.
addParameter(
"imageDepth", m_textures[RendererTextures_Depth].get() );
406 passParams.
addParameter(
"compose_data", composeParams );
408 for (
size_t i = 0; i < m_lightmanagers[0]->count(); ++i ) {
409 const auto l = m_lightmanagers[0]->getLight( i );
411 passParams.
addParameter(
"light_source", l->getRenderParameters() );
413 for (
const auto& ro : m_volumetricRenderObjects ) {
415 passParams, renderData, DefaultRenderingPasses::LIGHTING_VOLUMETRIC );
418 m_volumeFbo->unbind();
420 GL_ASSERT( glDrawBuffers( 1, buffers ) );
421 GL_ASSERT( glDisable( GL_DEPTH_TEST ) );
422 GL_ASSERT( glEnable( GL_BLEND ) );
423 GL_ASSERT( glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA ) );
425 auto shader = m_shaderProgramManager->getShaderProgram(
"ComposeVolume" );
427 shader->setUniform(
"volumeImage", m_textures[RendererTextures_Volume].get(), 0 );
428 m_quadMesh->render( shader );
430 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
437 glDisable( GL_POLYGON_OFFSET_FILL );
438 GL_ASSERT( glDepthFunc( GL_LEQUAL ) );
439 GL_ASSERT( glEnable( GL_BLEND ) );
440 glBlendEquationSeparate( GL_FUNC_ADD, GL_FUNC_ADD );
441 glBlendFuncSeparate( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO );
442 GL_ASSERT( glDrawBuffers( 1, buffers ) );
444 auto drawWireframe = [
this, &renderData](
const auto& ro ) {
445 std::shared_ptr<Data::Displayable> wro;
447 WireMap::iterator it = m_wireframes.find( ro.get() );
448 if ( it == m_wireframes.end() ) {
449 std::shared_ptr<Data::LineMesh> disp;
455 auto displayable = ro->getMesh();
456 auto tm = std::dynamic_pointer_cast<trimesh>( displayable );
457 auto tp = std::dynamic_pointer_cast<polymesh>( displayable );
458 auto tq = std::dynamic_pointer_cast<quadmesh>( displayable );
460 auto processLineMesh = [](
auto cm, std::shared_ptr<Data::LineMesh>& lm ) {
461 if ( cm->getRenderMode() ==
462 Data::AttribArrayDisplayable::MeshRenderMode::RM_TRIANGLES ) {
463 setupLineMesh( lm, cm->getCoreGeometry() );
466 if ( tm ) { processLineMesh( tm, disp ); }
467 if ( tp ) { processLineMesh( tp, disp ); }
468 if ( tq ) { processLineMesh( tq, disp ); }
470 m_wireframes[ro.get()] = disp;
473 else { wro = it->second; }
476 m_shaderProgramManager->getShaderProgram(
"Wireframe" );
478 if ( shader && wro ) {
480 if ( ro->isVisible() ) {
483 Core::Matrix4 modelMatrix = ro->getTransformAsMatrix();
484 shader->
setUniform(
"transform.proj", renderData.projMatrix );
485 shader->
setUniform(
"transform.view", renderData.viewMatrix );
486 shader->
setUniform(
"transform.model", modelMatrix );
487 shader->
setUniform(
"viewport", Core::Vector2 { m_width, m_height } );
488 wro->render( shader );
495 for (
const auto& ro : m_fancyRenderObjects ) {
498 for (
const auto& ro : m_transparentRenderObjects ) {
504 GL_ASSERT( glDepthFunc( GL_LESS ) );
505 GL_ASSERT( glDisable( GL_BLEND ) );
512 m_postprocessFbo->bind();
513 GL_ASSERT( glDisable( GL_BLEND ) );
514 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
515 GL_ASSERT( glDepthMask( GL_FALSE ) );
516 GL_ASSERT( glDepthFunc( GL_LESS ) );
518 glDrawBuffers( 1, buffers );
519 for (
const auto& ro : m_debugRenderObjects ) {
520 ro->render( {}, renderData );
523 DebugRender::getInstance()->render( renderData.viewMatrix, renderData.projMatrix );
525 m_postprocessFbo->unbind();
529 GL_ASSERT( glDepthMask( GL_TRUE ) );
530 GL_ASSERT( glClear( GL_DEPTH_BUFFER_BIT ) );
532 xrayLightParams.
addParameter(
"light.color", Ra::Core::Utils::Color::Grey( 5.0 ) );
533 xrayLightParams.
addParameter(
"light.type", Scene::Light::LightType::DIRECTIONAL );
534 xrayLightParams.
addParameter(
"light.directional.direction", Core::Vector3( 0, -1, 0 ) );
535 for (
const auto& ro : m_xrayRenderObjects ) {
536 if ( ro->isVisible() ) { ro->render( xrayLightParams, renderData ); }
538 m_uiXrayFbo->unbind();
546 glDrawBuffers( 1, buffers );
548 GL_ASSERT( glDepthMask( GL_TRUE ) );
549 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
550 GL_ASSERT( glDepthFunc( GL_LESS ) );
551 GL_ASSERT( glClear( GL_DEPTH_BUFFER_BIT ) );
552 for (
const auto& ro : m_uiRenderObjects ) {
553 if ( ro->isVisible() ) {
554 auto shader = ro->getRenderTechnique()->getShader();
556 LOG( logERROR ) <<
"shader not found" << ro->getName() <<
" "
557 << ro->getRenderTechnique()->getConfiguration().getName();
564 Core::Matrix4 M = ro->getTransformAsMatrix();
565 Core::Matrix4 MV = renderData.viewMatrix * M;
566 Core::Vector3 V = MV.block<3, 1>( 0, 3 );
569 Core::Matrix4 S = Core::Matrix4::Identity();
570 S.coeffRef( 0, 0 ) = S.coeffRef( 1, 1 ) = S.coeffRef( 2, 2 ) = d;
574 shader->setUniform(
"transform.proj", renderData.projMatrix );
575 shader->setUniform(
"transform.view", renderData.viewMatrix );
576 shader->setUniform(
"transform.model", M );
578 auto shaderParameter = ro->getRenderTechnique()->getParametersProvider();
579 if ( shaderParameter !=
nullptr ) shaderParameter->getParameters().bind( shader );
582 ro->getMesh()->render( shader );
586 m_uiXrayFbo->unbind();
590 CORE_UNUSED( renderData );
592 m_postprocessFbo->bind();
594 GL_ASSERT( glDrawBuffers( 1, buffers ) );
596 GL_ASSERT( glDisable( GL_DEPTH_TEST ) );
597 GL_ASSERT( glDepthMask( GL_FALSE ) );
601 shader->
setUniform(
"screenTexture", m_textures[RendererTextures_HDR].get(), 0 );
602 m_quadMesh->render( shader );
604 GL_ASSERT( glDepthMask( GL_TRUE ) );
605 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
607 m_postprocessFbo->unbind();
610 void ForwardRenderer::resizeInternal() {
611 m_pingPongSize = std::pow( uint( 2 ), uint( std::log2( std::min( m_width, m_height ) ) ) );
613 m_textures[RendererTextures_Depth]->resize( m_width, m_height );
614 m_textures[RendererTextures_HDR]->resize( m_width, m_height );
615 m_textures[RendererTextures_Normal]->resize( m_width, m_height );
616 m_textures[RendererTextures_Diffuse]->resize( m_width, m_height );
617 m_textures[RendererTextures_Specular]->resize( m_width, m_height );
618 m_textures[RendererTextures_OITAccum]->resize( m_width, m_height );
619 m_textures[RendererTextures_OITRevealage]->resize( m_width, m_height );
620 m_textures[RendererTextures_Volume]->resize( m_width, m_height );
623 m_fbo->attachTexture( GL_DEPTH_ATTACHMENT, m_textures[RendererTextures_Depth]->texture() );
624 m_fbo->attachTexture( GL_COLOR_ATTACHMENT0, m_textures[RendererTextures_HDR]->texture() );
625 m_fbo->attachTexture( GL_COLOR_ATTACHMENT1, m_textures[RendererTextures_Normal]->texture() );
626 m_fbo->attachTexture( GL_COLOR_ATTACHMENT2, m_textures[RendererTextures_Diffuse]->texture() );
627 m_fbo->attachTexture( GL_COLOR_ATTACHMENT3, m_textures[RendererTextures_Specular]->texture() );
628 if ( m_fbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
629 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_fbo): " << m_fbo->checkStatus();
633 m_volumeFbo->attachTexture( GL_DEPTH_ATTACHMENT,
634 m_textures[RendererTextures_Depth]->texture() );
635 m_volumeFbo->attachTexture( GL_COLOR_ATTACHMENT0,
636 m_textures[RendererTextures_Volume]->texture() );
637 if ( m_volumeFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
638 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_volumeFbo) : "
639 << m_volumeFbo->checkStatus();
643 m_oitFbo->attachTexture( GL_DEPTH_ATTACHMENT, m_textures[RendererTextures_Depth]->texture() );
644 m_oitFbo->attachTexture( GL_COLOR_ATTACHMENT0,
645 m_textures[RendererTextures_OITAccum]->texture() );
646 m_oitFbo->attachTexture( GL_COLOR_ATTACHMENT1,
647 m_textures[RendererTextures_OITRevealage]->texture() );
648 if ( m_oitFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
649 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_oitFbo) : " << m_oitFbo->checkStatus();
652 m_postprocessFbo->bind();
653 m_postprocessFbo->attachTexture( GL_DEPTH_ATTACHMENT,
654 m_textures[RendererTextures_Depth]->texture() );
655 m_postprocessFbo->attachTexture( GL_COLOR_ATTACHMENT0, m_fancyTexture->texture() );
656 if ( m_postprocessFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
657 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_postprocessFbo) : "
658 << m_postprocessFbo->checkStatus();
666 m_uiXrayFbo->attachTexture( GL_DEPTH_ATTACHMENT, Renderer::m_depthTexture->texture() );
667 m_uiXrayFbo->attachTexture( GL_COLOR_ATTACHMENT0, m_fancyTexture->texture() );
668 if ( m_uiXrayFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
669 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_uiXrayFbo) : "
670 << m_uiXrayFbo->checkStatus();
673 globjects::Framebuffer::unbind();
686 PointCloudParameterProvider( std::shared_ptr<Data::Material> mat,
688 ShaderParameterProvider(), m_displayMaterial( mat ), m_component( pointCloud ) {}
689 ~PointCloudParameterProvider()
override =
default;
691 m_displayMaterial->updateGL();
692 auto& renderParameters = getParameters();
693 renderParameters.mergeReplaceParameters( m_displayMaterial->getParameters() );
694 renderParameters.addParameter(
"pointCloudSplatRadius", m_component->getSplatSize() );
698 std::shared_ptr<Data::Material> m_displayMaterial;
707 auto material = ro->getMaterial();
709 LOG( logWARNING ) <<
"ForwardRenderer : no material found when building RenderTechnique"
710 <<
" - adding red Lambertian material";
712 defMat->m_color = Ra::Core::Utils::Color::Red();
713 material.reset( defMat );
715 auto builder = EngineRenderTechniques::getDefaultTechnique( material->getMaterialName() );
716 auto rt = Core::make_shared<RenderTechnique>();
721 builder.second( *rt,
true );
723 auto RenderedGeometry = ro->getMesh().get();
731 if ( RenderedGeometry && RenderedGeometry->getNumFaces() == 0 ) {
734 auto addGeomShader = [&rt]( Core::Utils::Index pass ) {
735 if ( rt->hasConfiguration( pass ) ) {
737 config.
addShader( Data::ShaderType_GEOMETRY,
738 RadiumEngine::getInstance()->getResourcesDir() +
739 "Shaders/Points/PointCloud.geom.glsl" );
740 rt->setConfiguration( config, pass );
744 addGeomShader( DefaultRenderingPasses::LIGHTING_OPAQUE );
745 addGeomShader( DefaultRenderingPasses::LIGHTING_TRANSPARENT );
746 addGeomShader( DefaultRenderingPasses::Z_PREPASS );
748 auto pr = std::make_shared<PointCloudParameterProvider>( material, pointCloud );
749 rt->setParametersProvider( pr );
751 else { rt->setParametersProvider( material ); }
755 rt->setParametersProvider( material );
757 ro->setRenderTechnique( rt );
761 void ForwardRenderer::updateShadowMaps() {
An engine mesh owning CoreGeometry, with indices.
void addParameter(const std::string &name, T value, typename std::enable_if<!std::is_class< T > {}, bool >::type=true)
Add a parameter by value.
void addShader(ShaderType type, const std::string &name)
virtual void updateGL()=0
Update the OpenGL states used by the ShaderParameterProvider. These state could be the ones from an a...
void setUniform(const char *name, const T &value) const
Uniform setters.
DefaultLightManager. A simple Light Manager with a list of lights.
the set of viewing parameters extracted from the camera and given to the renderer