242 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
243 GL_ASSERT( glDepthMask( GL_TRUE ) );
244 GL_ASSERT( glColorMask( 1, 1, 1, 1 ) );
246 GL_ASSERT( glDrawBuffers( 4, buffers ) );
249 glEnable( GL_POLYGON_OFFSET_FILL );
250 glPolygonOffset( 1.f, 3.f );
253 else { glDisable( GL_POLYGON_OFFSET_FILL ); }
254 static const auto clearZeros = Core::Utils::Color::Black().cast<GL_SCALAR_PLAIN>().eval();
255 static const auto clearOnes = Core::Utils::Color::White().cast<GL_SCALAR_PLAIN>().eval();
256 static const float clearDepth { 1.0f };
259 auto bgColor = getBackgroundColor().cast<GL_SCALAR_PLAIN>().eval();
260 GL_ASSERT( glClearBufferfv( GL_COLOR, 0, bgColor.data() ) );
261 GL_ASSERT( glClearBufferfv( GL_COLOR, 1, clearZeros.data() ) );
262 GL_ASSERT( glClearBufferfv( GL_COLOR, 2, clearZeros.data() ) );
263 GL_ASSERT( glClearBufferfv( GL_COLOR, 3, clearZeros.data() ) );
264 GL_ASSERT( glClearBufferfv( GL_DEPTH, 0, &clearDepth ) );
267 renderBackground( renderData );
270 GL_ASSERT( glDepthFunc( GL_LESS ) );
271 GL_ASSERT( glDisable( GL_BLEND ) );
272 GL_ASSERT( glPointSize( 3.f ) );
277 for (
const auto& ro : m_fancyRenderObjects ) {
278 ro->render( {}, renderData, DefaultRenderingPasses::Z_PREPASS );
284 for (
const auto& ro : m_transparentRenderObjects ) {
285 ro->render( {}, renderData, DefaultRenderingPasses::Z_PREPASS );
290 GL_ASSERT( glDepthFunc( GL_LEQUAL ) );
291 GL_ASSERT( glDepthMask( GL_FALSE ) );
293 GL_ASSERT( glEnable( GL_BLEND ) );
294 GL_ASSERT( glBlendFunc( GL_ONE, GL_ONE ) );
296 GL_ASSERT( glDrawBuffers( 1, buffers ) );
301 if ( m_lightmanagers[0]->count() > 0 ) {
303 for (
size_t i = 0; i < m_lightmanagers[0]->count(); ++i ) {
304 const auto l = m_lightmanagers[0]->getLight( i );
305 for (
const auto& ro : m_fancyRenderObjects ) {
307 l->getRenderParameters(), renderData, DefaultRenderingPasses::LIGHTING_OPAQUE );
311 for (
const auto& ro : m_transparentRenderObjects ) {
313 l->getRenderParameters(), renderData, DefaultRenderingPasses::LIGHTING_OPAQUE );
317 else { LOG( logINFO ) <<
"Opaque : no light sources, unable to render"; }
320 if ( !m_transparentRenderObjects.empty() ) {
325 GL_ASSERT( glDrawBuffers( 2, buffers ) );
326 GL_ASSERT( glClearBufferfv( GL_COLOR, 0, clearZeros.data() ) );
327 GL_ASSERT( glClearBufferfv( GL_COLOR, 1, clearOnes.data() ) );
329 GL_ASSERT( glDepthFunc( GL_LESS ) );
330 GL_ASSERT( glEnable( GL_BLEND ) );
332 GL_ASSERT( glBlendEquation( GL_FUNC_ADD ) );
333 GL_ASSERT( glBlendFunci( 0, GL_ONE, GL_ONE ) );
334 GL_ASSERT( glBlendFunci( 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA ) );
336 if ( m_lightmanagers[0]->count() > 0 ) {
338 for (
size_t i = 0; i < m_lightmanagers[0]->count(); ++i ) {
339 const auto l = m_lightmanagers[0]->getLight( i );
341 for (
const auto& ro : m_transparentRenderObjects ) {
342 ro->render( l->getRenderParameters(),
344 DefaultRenderingPasses::LIGHTING_TRANSPARENT );
348 else { LOG( logINFO ) <<
"Transparent : no light sources, unable to render"; }
353 GL_ASSERT( glDrawBuffers( 1, buffers ) );
354 GL_ASSERT( glDisable( GL_DEPTH_TEST ) );
355 GL_ASSERT( glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA ) );
357 auto shader = m_shaderProgramManager->getShaderProgram(
"ComposeOIT" );
359 shader->setUniform(
"u_OITSumColor", m_textures[RendererTextures_OITAccum].get(), 0 );
361 "u_OITSumWeight", m_textures[RendererTextures_OITRevealage].get(), 1 );
363 m_quadMesh->render( shader );
365 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
372 if ( m_lightmanagers[0]->count() > 0 ) {
373 if ( !m_volumetricRenderObjects.empty() ) {
376 GL_ASSERT( glDrawBuffers( 1, buffers ) );
377 static const auto alpha = Core::Utils::Color::Alpha().cast<GL_SCALAR_PLAIN>().eval();
378 GL_ASSERT( glClearBufferfv( GL_COLOR, 0, alpha.data() ) );
379 GL_ASSERT( glDisable( GL_BLEND ) );
382 composeParams.
setTexture(
"imageColor", m_textures[RendererTextures_HDR].get() );
383 composeParams.
setTexture(
"imageDepth", m_textures[RendererTextures_Depth].get() );
385 passParams.
setVariable(
"compose_data", composeParams );
387 for (
size_t i = 0; i < m_lightmanagers[0]->count(); ++i ) {
388 const auto l = m_lightmanagers[0]->getLight( i );
390 passParams.
setVariable(
"light_source", l->getRenderParameters() );
392 for (
const auto& ro : m_volumetricRenderObjects ) {
394 passParams, renderData, DefaultRenderingPasses::LIGHTING_VOLUMETRIC );
397 m_volumeFbo->unbind();
399 GL_ASSERT( glDrawBuffers( 1, buffers ) );
400 GL_ASSERT( glDisable( GL_DEPTH_TEST ) );
401 GL_ASSERT( glEnable( GL_BLEND ) );
402 GL_ASSERT( glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA ) );
404 auto shader = m_shaderProgramManager->getShaderProgram(
"ComposeVolume" );
406 shader->setUniform(
"volumeImage", m_textures[RendererTextures_Volume].get(), 0 );
407 m_quadMesh->render( shader );
409 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
416 glDisable( GL_POLYGON_OFFSET_FILL );
417 GL_ASSERT( glDepthFunc( GL_LEQUAL ) );
418 GL_ASSERT( glEnable( GL_BLEND ) );
419 glBlendEquationSeparate( GL_FUNC_ADD, GL_FUNC_ADD );
420 glBlendFuncSeparate( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO );
421 GL_ASSERT( glDrawBuffers( 1, buffers ) );
423 auto drawWireframe = [
this, &renderData](
const auto& ro ) {
426 WireMap::iterator it = m_wireframes.find( ro.get() );
427 if ( it == m_wireframes.end() ) {
434 auto displayable = ro->getMesh();
440 if ( cm->getRenderMode() ==
441 Data::AttribArrayDisplayable::MeshRenderMode::RM_TRIANGLES ) {
442 setupLineMesh( lm, cm->getCoreGeometry() );
445 if ( tm ) { processLineMesh( tm, disp ); }
446 if ( tp ) { processLineMesh( tp, disp ); }
447 if ( tq ) { processLineMesh( tq, disp ); }
449 m_wireframes[ro.get()] = disp;
452 else { wro = it->second; }
455 m_shaderProgramManager->getShaderProgram(
"Wireframe" );
457 if ( shader && wro ) {
459 if ( ro->isVisible() ) {
462 Core::Matrix4 modelMatrix = ro->getTransformAsMatrix();
463 shader->
setUniform(
"transform.proj", renderData.projMatrix );
464 shader->
setUniform(
"transform.view", renderData.viewMatrix );
465 shader->
setUniform(
"transform.model", modelMatrix );
466 shader->
setUniform(
"viewport", Core::Vector2 { m_width, m_height } );
467 wro->render( shader );
474 for (
const auto& ro : m_fancyRenderObjects ) {
477 for (
const auto& ro : m_transparentRenderObjects ) {
483 GL_ASSERT( glDepthFunc( GL_LESS ) );
484 GL_ASSERT( glDisable( GL_BLEND ) );
491 m_postprocessFbo->bind();
492 GL_ASSERT( glDisable( GL_BLEND ) );
493 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
494 GL_ASSERT( glDepthMask( GL_FALSE ) );
495 GL_ASSERT( glDepthFunc( GL_LESS ) );
497 glDrawBuffers( 1, buffers );
498 for (
const auto& ro : m_debugRenderObjects ) {
499 ro->render( {}, renderData );
502 DebugRender::getInstance()->render( renderData.viewMatrix, renderData.projMatrix );
504 m_postprocessFbo->unbind();
508 GL_ASSERT( glDepthMask( GL_TRUE ) );
509 GL_ASSERT( glClear( GL_DEPTH_BUFFER_BIT ) );
511 using namespace Core::VariableSetEnumManagement;
512 xrayLightParams.
setVariable(
"light.color", Ra::Core::Utils::Color::Grey( 5.0 ) );
513 setEnumVariable( xrayLightParams,
"light.type", Scene::Light::LightType::DIRECTIONAL );
514 xrayLightParams.
setVariable(
"light.directional.direction", Core::Vector3( 0, -1, 0 ) );
515 for (
const auto& ro : m_xrayRenderObjects ) {
516 if ( ro->isVisible() ) { ro->render( xrayLightParams, renderData ); }
518 m_uiXrayFbo->unbind();
526 glDrawBuffers( 1, buffers );
528 GL_ASSERT( glDepthMask( GL_TRUE ) );
529 GL_ASSERT( glEnable( GL_DEPTH_TEST ) );
530 GL_ASSERT( glDepthFunc( GL_LESS ) );
531 GL_ASSERT( glClear( GL_DEPTH_BUFFER_BIT ) );
532 for (
const auto& ro : m_uiRenderObjects ) {
533 if ( ro->isVisible() ) {
534 auto shader = ro->getRenderTechnique()->getShader();
536 LOG( logERROR ) <<
"shader not found" << ro->getName() <<
" "
537 << ro->getRenderTechnique()->getConfiguration().getName();
544 Core::Matrix4 M = ro->getTransformAsMatrix();
545 Core::Matrix4 MV = renderData.viewMatrix * M;
546 Core::Vector3 V = MV.block<3, 1>( 0, 3 );
549 Core::Matrix4 S = Core::Matrix4::Identity();
550 S.coeffRef( 0, 0 ) = S.coeffRef( 1, 1 ) = S.coeffRef( 2, 2 ) = d;
554 shader->setUniform(
"transform.proj", renderData.projMatrix );
555 shader->setUniform(
"transform.view", renderData.viewMatrix );
556 shader->setUniform(
"transform.model", M );
558 auto shaderParameter = ro->getRenderTechnique()->getParametersProvider();
559 if ( shaderParameter !=
nullptr ) shaderParameter->getParameters().bind( shader );
562 ro->getMesh()->render( shader );
566 m_uiXrayFbo->unbind();
590void ForwardRenderer::resizeInternal() {
591 m_pingPongSize =
std::pow( uint( 2 ), uint( std::log2(
std::min( m_width, m_height ) ) ) );
593 for (
auto& tex : m_textures ) {
594 tex->resize( m_width, m_height );
598 m_fbo->attachTexture( GL_DEPTH_ATTACHMENT,
599 m_textures[RendererTextures_Depth]->getGpuTexture() );
600 m_fbo->attachTexture( GL_COLOR_ATTACHMENT0, m_textures[RendererTextures_HDR]->getGpuTexture() );
601 m_fbo->attachTexture( GL_COLOR_ATTACHMENT1,
602 m_textures[RendererTextures_Normal]->getGpuTexture() );
603 m_fbo->attachTexture( GL_COLOR_ATTACHMENT2,
604 m_textures[RendererTextures_Diffuse]->getGpuTexture() );
605 m_fbo->attachTexture( GL_COLOR_ATTACHMENT3,
606 m_textures[RendererTextures_Specular]->getGpuTexture() );
607 if ( m_fbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
608 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_fbo): " << m_fbo->checkStatus();
612 m_volumeFbo->attachTexture( GL_DEPTH_ATTACHMENT,
613 m_textures[RendererTextures_Depth]->getGpuTexture() );
614 m_volumeFbo->attachTexture( GL_COLOR_ATTACHMENT0,
615 m_textures[RendererTextures_Volume]->getGpuTexture() );
616 if ( m_volumeFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
617 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_volumeFbo) : "
618 << m_volumeFbo->checkStatus();
622 m_oitFbo->attachTexture( GL_DEPTH_ATTACHMENT,
623 m_textures[RendererTextures_Depth]->getGpuTexture() );
624 m_oitFbo->attachTexture( GL_COLOR_ATTACHMENT0,
625 m_textures[RendererTextures_OITAccum]->getGpuTexture() );
626 m_oitFbo->attachTexture( GL_COLOR_ATTACHMENT1,
627 m_textures[RendererTextures_OITRevealage]->getGpuTexture() );
628 if ( m_oitFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
629 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_oitFbo) : " << m_oitFbo->checkStatus();
632 m_postprocessFbo->bind();
633 m_postprocessFbo->attachTexture( GL_DEPTH_ATTACHMENT,
634 m_textures[RendererTextures_Depth]->getGpuTexture() );
635 m_postprocessFbo->attachTexture( GL_COLOR_ATTACHMENT0, m_fancyTexture->getGpuTexture() );
636 if ( m_postprocessFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
637 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_postprocessFbo) : "
638 << m_postprocessFbo->checkStatus();
646 m_uiXrayFbo->attachTexture( GL_DEPTH_ATTACHMENT, Renderer::m_depthTexture->getGpuTexture() );
647 m_uiXrayFbo->attachTexture( GL_COLOR_ATTACHMENT0, m_fancyTexture->getGpuTexture() );
648 if ( m_uiXrayFbo->checkStatus() != GL_FRAMEBUFFER_COMPLETE ) {
649 LOG( logERROR ) <<
"FBO Error (ForwardRenderer::m_uiXrayFbo) : "
650 << m_uiXrayFbo->checkStatus();
653 globjects::Framebuffer::unbind();