From faa3d2353c58b48ef5169cf68c796937e2a9472a Mon Sep 17 00:00:00 2001 From: davidsminor Date: Tue, 3 Dec 2013 11:56:30 -0800 Subject: [PATCH] Added IECoreGL::Selector::push/popIDShader() ID shaders weren't being reverted correctly in certain situations involving ribbon curves, so Selector::loadIDShader() has been deprecated and replaced by Selector::pushIDShader(), which can be reverted using Selector::popIDShader() --- include/IECoreGL/Selector.h | 6 +++++ src/IECoreGL/Selector.cpp | 48 +++++++++++++++++++++++++++---------- src/IECoreGL/Shader.cpp | 9 ++++++- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/include/IECoreGL/Selector.h b/include/IECoreGL/Selector.h index 7fcab22adb..1438bb8487 100644 --- a/include/IECoreGL/Selector.h +++ b/include/IECoreGL/Selector.h @@ -110,6 +110,12 @@ class Selector : boost::noncopyable /// Typically one is set up automatically in baseState(), but /// if rendering must be performed with an alternative shader /// then it may be passed via this function. + void pushIDShader( const IECoreGL::Shader *idShader ); + + /// Revert to previous ID shader: + void popIDShader(); + + /// Deprecated: calls pushIDShader void loadIDShader( const IECoreGL::Shader *idShader ); /// Returns the currently active Selector - this may be used diff --git a/src/IECoreGL/Selector.cpp b/src/IECoreGL/Selector.cpp index 1ca59240ae..0f0df0874b 100644 --- a/src/IECoreGL/Selector.cpp +++ b/src/IECoreGL/Selector.cpp @@ -189,7 +189,29 @@ class Selector::Implementation : public IECore::RefCounted return m_baseState; } - void loadIDShader( const IECoreGL::Shader *shader ) + void pushIDShader( const IECoreGL::Shader *shader ) + { + bindIDShader( shader ); + m_IDShaderStack.push( shader ); + } + + void popIDShader() + { + m_IDShaderStack.pop(); + if( m_IDShaderStack.size() ) + { + bindIDShader( m_IDShaderStack.top() ); + } + } + + static Selector *currentSelector() + { + return g_currentSelector; + } + + private : + + void bindIDShader( const IECoreGL::Shader *shader ) { if( shader == m_currentIDShader ) { @@ -214,7 +236,7 @@ class Selector::Implementation : public IECore::RefCounted m_currentIDShader = shader; glUseProgram( m_currentIDShader->program() ); - + std::vector buffers; buffers.resize( fragDataLocation + 1, GL_NONE ); buffers[buffers.size()-1] = GL_COLOR_ATTACHMENT0; @@ -222,14 +244,7 @@ class Selector::Implementation : public IECore::RefCounted loadNameIDRender( m_currentName ); } - - static Selector *currentSelector() - { - return g_currentSelector; - } - - private : - + Mode m_mode; std::vector &m_hits; StatePtr m_baseState; @@ -285,6 +300,7 @@ class Selector::Implementation : public IECore::RefCounted boost::shared_ptr m_frameBufferBinding; GLint m_prevProgram; ConstShaderPtr m_currentIDShader; + std::stack m_IDShaderStack; GLint m_prevViewport[4]; GLint m_nameUniformLocation; @@ -346,7 +362,7 @@ class Selector::Implementation : public IECore::RefCounted } glGetIntegerv( GL_CURRENT_PROGRAM, &m_prevProgram ); - loadIDShader( m_baseState->get()->shaderSetup()->shader() ); + pushIDShader( m_baseState->get()->shaderSetup()->shader() ); } void loadNameIDRender( GLuint name ) @@ -484,7 +500,15 @@ State *Selector::baseState() void Selector::loadIDShader( const IECoreGL::Shader *idShader ) { - m_implementation->loadIDShader( idShader ); + m_implementation->pushIDShader( idShader ); +} +void Selector::pushIDShader( const IECoreGL::Shader *idShader ) +{ + m_implementation->pushIDShader( idShader ); +} +void Selector::popIDShader() +{ + m_implementation->popIDShader(); } Selector *Selector::currentSelector() diff --git a/src/IECoreGL/Shader.cpp b/src/IECoreGL/Shader.cpp index 4ad7c10eeb..c6701d7e6f 100644 --- a/src/IECoreGL/Shader.cpp +++ b/src/IECoreGL/Shader.cpp @@ -880,7 +880,7 @@ Shader::Setup::ScopedBinding::ScopedBinding( const Setup &setup ) { if( currentSelector->mode() == Selector::IDRender ) { - currentSelector->loadIDShader( m_setup.shader() ); + currentSelector->pushIDShader( m_setup.shader() ); } } } @@ -894,6 +894,13 @@ Shader::Setup::ScopedBinding::~ScopedBinding() } glUseProgram( m_previousProgram ); + if( Selector *currentSelector = Selector::currentSelector() ) + { + if( currentSelector->mode() == Selector::IDRender ) + { + currentSelector->popIDShader(); + } + } } ///////////////////////////////////////////////////////////////////////////////