Skip to content

Commit

Permalink
Merge pull request ImageEngine#156 from johnhaddon/gl2
Browse files Browse the repository at this point in the history
OpenGL 2.1 Compatibility Fixes. Looks good to me but I haven't tested the OSX code...
  • Loading branch information
goddardl committed Oct 24, 2013
2 parents 686012a + 3669dff commit 5567f12
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 23 deletions.
2 changes: 2 additions & 0 deletions include/IECoreGL/CurvesPrimitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class CurvesPrimitive : public Primitive

private :

void renderMode( const State *state, bool &linear, bool &ribbons ) const;

static const std::string &cubicLinesGeometrySource();
static const std::string &cubicRibbonsGeometrySource();
static const std::string &linearRibbonsGeometrySource();
Expand Down
6 changes: 6 additions & 0 deletions include/IECoreGL/FrameBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ class FrameBuffer : public IECore::RunTimeTyped
FrameBuffer();
virtual ~FrameBuffer();

/// Returns the GL handle for the framebuffer. Note that this is
/// owned by the FrameBuffer class and will be destroyed in the
/// destructor - you must therefore not call glDeleteFramebuffers()
/// yourself.
GLuint frameBuffer() const;

/// Returns the maximum number of color attachments available
/// in the calls below (the maximum allowable value for index).
static unsigned int maxColors();
Expand Down
3 changes: 3 additions & 0 deletions include/IECoreGL/IECoreGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ namespace IECoreGL
/// it multiple times.
void init( bool glAlreadyInitialised = false );

/// Returns the current GLSL version.
int glslVersion();

} // namespace IECoreGL

#endif // IECOREGL_COREGL_H
5 changes: 4 additions & 1 deletion include/IECoreGL/Selector.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ class Selector : boost::noncopyable
OcclusionQuery,
/// Renders each object to an offscreen framebuffer using a
/// unique colour per object. Can therefore only select the
/// frontmost objects, but does provide accurate depth information.
/// frontmost objects, but does provide accurate depth information.
/// Note that this mode is currently only supported for GLSL
/// versions 330 and up - lesser versions will fall back to using
/// the GLSelect mode.
IDRender
};

Expand Down
24 changes: 19 additions & 5 deletions src/IECoreGL/CurvesPrimitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "IECoreGL/CachedConverter.h"
#include "IECoreGL/ShaderLoader.h"
#include "IECoreGL/ShaderStateComponent.h"
#include "IECoreGL/IECoreGL.h"

using namespace IECoreGL;
using namespace Imath;
Expand Down Expand Up @@ -147,8 +148,8 @@ void CurvesPrimitive::addPrimitiveVariable( const std::string &name, const IECor

const Shader::Setup *CurvesPrimitive::shaderSetup( const Shader *shader, State *state ) const
{
bool linear = m_memberData->basis==IECore::CubicBasisf::linear() || state->get<IgnoreBasis>()->value();
bool ribbons = !state->get<UseGLLines>()->value();
bool linear, ribbons;
renderMode( state, linear, ribbons );

if( linear && !ribbons )
{
Expand Down Expand Up @@ -205,9 +206,9 @@ const Shader::Setup *CurvesPrimitive::shaderSetup( const Shader *shader, State *

void CurvesPrimitive::render( const State *currentState, IECore::TypeId style ) const
{
bool linear = m_memberData->basis==IECore::CubicBasisf::linear() || currentState->get<IgnoreBasis>()->value();
bool ribbons = !currentState->get<UseGLLines>()->value();

bool linear, ribbons;
renderMode( currentState, linear, ribbons );
if( !ribbons )
{
glLineWidth( currentState->get<GLLineWidth>()->value() );
Expand Down Expand Up @@ -239,6 +240,19 @@ void CurvesPrimitive::renderInstances( size_t numInstances ) const
glDrawElementsInstancedARB( GL_LINES, m_memberData->numVertIds, GL_UNSIGNED_INT, 0, numInstances );
}

void CurvesPrimitive::renderMode( const State *state, bool &linear, bool &ribbons ) const
{
if( glslVersion() < 150 )
{
linear = true;
ribbons = false;
return;
}

linear = m_memberData->basis==IECore::CubicBasisf::linear() || state->get<IgnoreBasis>()->value();
ribbons = !state->get<UseGLLines>()->value();
}

const std::string &CurvesPrimitive::cubicLinesGeometrySource()
{
static std::string s =
Expand Down
5 changes: 5 additions & 0 deletions src/IECoreGL/FrameBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ FrameBuffer::~FrameBuffer()
glDeleteFramebuffers( 1, &m_frameBuffer );
}

GLuint FrameBuffer::frameBuffer() const
{
return m_frameBuffer;
}

unsigned int FrameBuffer::maxColors()
{
GLint m;
Expand Down
30 changes: 30 additions & 0 deletions src/IECoreGL/IECoreGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@

#include "IECoreGL/GL.h"
#include "IECoreGL/IECoreGL.h"
#include "IECoreGL/FrameBuffer.h"
#include "IECoreGL/ColorTexture.h"
#include "IECoreGL/DepthTexture.h"

#if defined( __APPLE__ )

Expand All @@ -50,6 +53,8 @@

#include "IECore/MessageHandler.h"

static int g_glslVersion = 0;

void IECoreGL::init( bool glAlreadyInitialised )
{
static bool init = false;
Expand Down Expand Up @@ -117,5 +122,30 @@ void IECoreGL::init( bool glAlreadyInitialised )
IECore::msg( IECore::Msg::Error, "IECoreGL::init", boost::format( "GLEW initialisation failed (%s)." ) % glewGetErrorString( initStatus ) );
}
init = true;

const char *s = (const char *)glGetString( GL_SHADING_LANGUAGE_VERSION );
int major = 0; int minor = 0;
sscanf( s, "%d.%d", &major, &minor );
g_glslVersion = major * 100 + minor;

#if defined( __APPLE__ )

if( !glAlreadyInitialised )
{
// we have to do this bit after GLEW initialisation.
static FrameBufferPtr g_frameBuffer = new FrameBuffer();
g_frameBuffer->setColor( new ColorTexture( 32, 23 ) );
g_frameBuffer->setDepth( new DepthTexture( 32, 32 ) );
g_frameBuffer->validate();
glBindFramebuffer( GL_FRAMEBUFFER, g_frameBuffer->frameBuffer() );
}

#endif

}
}

int IECoreGL::glslVersion()
{
return g_glslVersion;
}
22 changes: 15 additions & 7 deletions src/IECoreGL/Selector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include "IECoreGL/Primitive.h"
#include "IECoreGL/ShaderLoader.h"
#include "IECoreGL/TextureLoader.h"
#include "IECoreGL/IECoreGL.h"

using namespace IECoreGL;

Expand Down Expand Up @@ -100,6 +101,13 @@ class Selector::Implementation : public IECore::RefCounted
glMultMatrixd( projectionMatrix );
glMatrixMode( GL_MODELVIEW );

// fall back to GLSelect mode if we can't
// support IDRender mode.
if( m_mode == IDRender && glslVersion() < 330 )
{
m_mode = GLSelect;
}

switch( m_mode )
{
case GLSelect :
Expand Down Expand Up @@ -413,32 +421,32 @@ class Selector::Implementation : public IECore::RefCounted
{
if( m_queries.size() )
{
glEndQuery( GL_ANY_SAMPLES_PASSED );
glEndQueryARB( GL_SAMPLES_PASSED_ARB );
}
m_queries.push_back( 0 );
glGenQueries( 1, &(m_queries[m_queries.size()-1]) );
glBeginQuery( GL_ANY_SAMPLES_PASSED, m_queries[m_queries.size()-1] );
glGenQueriesARB( 1, &(m_queries[m_queries.size()-1]) );
glBeginQueryARB( GL_SAMPLES_PASSED_ARB, m_queries[m_queries.size()-1] );
m_queryNames.push_back( name );
}

void endOcclusionQuery()
{
if( m_queries.size() )
{
glEndQuery( GL_ANY_SAMPLES_PASSED );
glEndQueryARB( GL_SAMPLES_PASSED_ARB );
}

for( size_t i = 0, e = m_queries.size(); i < e; i++ )
{
GLuint samplesPassed = 0;
glGetQueryObjectuiv( m_queries[i], GL_QUERY_RESULT, &samplesPassed );
glGetQueryObjectuivARB( m_queries[i], GL_QUERY_RESULT_ARB, &samplesPassed );
if( samplesPassed )
{
m_hits.push_back( HitRecord( 0, 0, NameStateComponent::nameFromGLName( m_queryNames[i] ) ) );
}
}

glDeleteQueries( m_queries.size(), &(m_queries[0]) );
glDeleteQueriesARB( m_queries.size(), &(m_queries[0]) );
m_baseState->add( const_cast<DepthTestStateComponent *>( State::defaultState()->get<DepthTestStateComponent>() ), false /* no override */ );
}

Expand Down
32 changes: 31 additions & 1 deletion src/IECoreGL/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include <iostream>

#include "boost/format.hpp"
#include "boost/tokenizer.hpp"
#include "boost/algorithm/string/predicate.hpp"

#include "IECore/SimpleTypedData.h"
#include "IECore/MessageHandler.h"
Expand Down Expand Up @@ -117,7 +119,35 @@ class Shader::Implementation : public IECore::RefCounted
vector<char> log( logLength, ' ' );
glGetProgramInfoLog( m_program, logLength, 0, &log[0] );
message = &log[0];
IECore::msg( IECore::Msg::Warning, "IECoreGL::Shader", message );

// os x spews warnings rather overzealously, so we split them
// into warnings and debug messages. the debug messages will generally
// be filtered out by the message level, but they're still there
// if someone really wants them.
std::string warning;
std::string debug;
typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
Tokenizer lines( message, boost::char_separator<char>( "\n" ) );
for( Tokenizer::iterator it = lines.begin(); it != lines.end(); ++it )
{
if( starts_with( *it, "WARNING: Output of vertex shader" ) && ends_with( *it, "not read by fragment shader" ) )
{
debug += *it + "\n";
}
else
{
warning += *it + "\n";
}
}

if( debug.size() )
{
IECore::msg( IECore::Msg::Debug, "IECoreGL::Shader", debug );
}
if( warning.size() )
{
IECore::msg( IECore::Msg::Warning, "IECoreGL::Shader", warning );
}
}
{
// build the uniform parameter description map
Expand Down
1 change: 1 addition & 0 deletions src/IECoreGL/bindings/IECoreGLBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,5 @@ BOOST_PYTHON_MODULE( _IECoreGL )
#endif

def( "init", &IECoreGL::init );
def( "glslVersion", &IECoreGL::glslVersion );
}
Loading

0 comments on commit 5567f12

Please sign in to comment.