// This switches the renderer for the main pass between rasterizer and raytracer. void SceneRendererPipeline::setSceneRenderer(const dp::sg::ui::SceneRendererSharedPtr &sceneRenderer) { m_sceneRenderer = sceneRenderer; // Do not separate the ViewState camera another time during the render() call issued inside the SceneRendererPipeline. m_sceneRenderer->setStereoViewStateProvider(m_monoViewStateProvider); if ( GetApp()->isBackdropEnabled() ) { updateEnvironment(); } // If the renderer is a SceneRendererGL2 reuse it for the highlighting to keep the number of RenderLists small. if ( m_sceneRenderer.isPtrTo<dp::sg::renderer::rix::gl::SceneRenderer>() ) { m_sceneRendererHighlight = m_sceneRenderer.staticCast<dp::sg::renderer::rix::gl::SceneRenderer>(); } else { Viewer* viewer = GetApp(); m_sceneRendererHighlight = dp::sg::renderer::rix::gl::SceneRenderer::create( viewer->getRenderEngine().c_str(), viewer->getShaderManagerType(), viewer->getCullingMode(), dp::sg::renderer::rix::gl::TransparencyMode::SORTED_BLENDED ); } }
// This is called from initializeGL(). bool SceneRendererPipeline::init(const dp::gl::RenderContextSharedPtr &renderContext, const dp::gl::RenderTargetSharedPtr &renderTarget) { m_renderTarget = renderTarget; DP_ASSERT( m_sceneRenderer ); m_sceneRenderer->setRenderTarget( renderTarget ); m_sceneRenderer->setEnvironmentRenderingEnabled( GetApp()->getPreferences()->getEnvironmentEnabled() ); // Create an FBO with 2D texture color attachment and depth stencil render buffers. // This one remains monoscopic, SceneRendererPipeline::doRender() works per eye. m_highlightFBO = dp::gl::RenderTargetFBO::create( renderContext ); // Set the defaults for the render pass. // This clear color actually doesn't take effect when using a SceneRenderer. The scene background color has precedence. m_highlightFBO->setClearColor(0.0f, 0.0f, 0.0f, 0.0f); m_highlightFBO->setClearDepth(1.0); m_highlightFBO->setClearStencil(0); // Make the OpenGL context on the renderContext current. It's needed for the create() operations. dp::gl::RenderContextStack rcglstack; rcglstack.push(renderContext); // Render to 2D texture. m_highlightFBO->setAttachment(dp::gl::RenderTargetFBO::AttachmentTarget::COLOR0, dp::gl::Texture2D::create(GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE)); // Depth and Stencil are Renderbuffers. dp::gl::RenderbufferSharedPtr depthStencil(dp::gl::Renderbuffer::create(GL_DEPTH24_STENCIL8)); // Shared depth stencil buffer between the tonemap and hightlight FBOs. m_highlightFBO->setAttachment(dp::gl::RenderTargetFBO::AttachmentTarget::DEPTH, depthStencil); m_highlightFBO->setAttachment(dp::gl::RenderTargetFBO::AttachmentTarget::STENCIL, depthStencil); std::vector<dp::gl::RenderTargetFBO::AttachmentTarget> drawBuffers; drawBuffers.push_back(dp::gl::RenderTargetFBO::AttachmentTarget::COLOR0); m_highlightFBO->setDrawBuffers(drawBuffers); rcglstack.pop(); // If there hasn't been a setSceneRender() we cannot reuse the m_sceneRenderer for the highlight rasterization. // Create the SceneRenderer used to render the highlighted objects of the scene into the highlightFBO stencil buffer. if (!m_sceneRendererHighlight) { Viewer * viewer = GetApp(); m_sceneRendererHighlight = dp::sg::renderer::rix::gl::SceneRenderer::create( viewer->getRenderEngine().c_str(), viewer->getShaderManagerType(), viewer->getCullingMode(), dp::sg::renderer::rix::gl::TransparencyMode::SORTED_BLENDED ); } if ( GetApp()->isTonemapperEnabled() ) { initTonemapper(); } if ( GetApp()->getPreferences()->getEnvironmentEnabled() ) { initBackdrop(); } // Create a full screen quad renderer for the stencil buffer to color attachment migration. m_rendererStencilToColor = dp::sg::renderer::rix::gl::FSQRenderer::create(m_highlightFBO); m_rendererStencilToColor->setPipeline( dp::sg::core::PipelineData::create( EffectLibrary::instance()->getEffectSpec( std::string("stencilToColor") ) ) ); // Create a full screen quad renderer for the final texture to framebuffer operation rendering the highlight outline. m_rendererHighlight = dp::sg::renderer::rix::gl::FSQRenderer::create(renderTarget); m_rendererHighlight->setPipeline( dp::sg::core::PipelineData::create( EffectLibrary::instance()->getEffectSpec( std::string("highlight") ) ) ); // m_rendererHighlight uses the previously rendered texture rectangle as input for the shader. const dp::gl::RenderTargetFBO::SharedAttachment &attachment = m_highlightFBO->getAttachment(dp::gl::RenderTargetFBO::AttachmentTarget::COLOR0); const dp::gl::RenderTargetFBO::SharedAttachmentTexture &texAtt = attachment.inplaceCast<dp::gl::RenderTargetFBO::AttachmentTexture>(); if (texAtt) { const dp::sg::gl::TextureGLSharedPtr texGL = dp::sg::gl::TextureGL::create( texAtt->getTexture() ); dp::sg::core::SamplerSharedPtr sampler = dp::sg::core::Sampler::create( texGL ); sampler->setWrapModes( dp::sg::core::TextureWrapMode::CLAMP_TO_EDGE, dp::sg::core::TextureWrapMode::CLAMP_TO_EDGE, dp::sg::core::TextureWrapMode::CLAMP_TO_EDGE ); sampler->setMagFilterMode( dp::sg::core::TextureMagFilterMode::NEAREST ); sampler->setMinFilterMode( dp::sg::core::TextureMinFilterMode::NEAREST ); m_rendererHighlight->setSamplerByName( "selection", sampler ); } return true; }