diff --git a/examples/osgcubemap/osgcubemap.cpp b/examples/osgcubemap/osgcubemap.cpp index a666217cc..62c457a66 100644 --- a/examples/osgcubemap/osgcubemap.cpp +++ b/examples/osgcubemap/osgcubemap.cpp @@ -129,6 +129,23 @@ int main(int argc, char *argv[]) // create the windows and run the threads. viewer.realize(); + + // now check to see if texture cube map is supported. + for(unsigned int contextID = 0; + contextIDgetMaxNumberOfGraphicsContexts(); + ++contextID) + { + osg::TextureCubeMap::Extensions* tcmExt = osg::TextureCubeMap::getExtensions(contextID,false); + if (tcmExt) + { + if (!tcmExt->isCubeMapSupported()) + { + cout<<"Warning: texture_cube_map not supported by OpenGL drivers, unable to run application."<getMaxNumberOfGraphicsContexts(); + ++contextID) + { + osg::Texture::Extensions* textExt = osg::Texture::getExtensions(contextID,false); + if (textExt) + { + if (!textExt->isMultiTexturingSupported()) + { + cout<<"Warning: texture_cube_map not supported by OpenGL drivers, unable to run application."<getMaxNumberOfGraphicsContexts(); + ++contextID) + { + osg::VertexProgram::Extensions* vpExt = osg::VertexProgram::getExtensions(contextID,false); + if (vpExt) + { + if (!vpExt->isVertexProgramSupported()) + { + cout<<"Warning: ARB_vertex_program not supported by OpenGL drivers, unable to run application."<=0) || + isGLExtensionSupported("GL_ARB_multitexture") || + isGLExtensionSupported("GL_EXT_multitexture"); _isTextureFilterAnisotropicSupported = isGLExtensionSupported("GL_EXT_texture_filter_anisotropic"); _isTextureCompressionARBSupported = isGLExtensionSupported("GL_ARB_texture_compression"); _isTextureCompressionS3TCSupported = isGLExtensionSupported("GL_EXT_texture_compression_s3tc"); diff --git a/src/osg/VertexProgram.cpp b/src/osg/VertexProgram.cpp index 799d3431d..7b5685b02 100644 --- a/src/osg/VertexProgram.cpp +++ b/src/osg/VertexProgram.cpp @@ -32,25 +32,13 @@ VertexProgram::VertexProgram(const VertexProgram& vp,const CopyOp& copyop): VertexProgram::~VertexProgram() {} - -typedef void (APIENTRY * BindProgramProc) (GLenum target, GLuint id); -typedef void (APIENTRY * GenProgramsProc) (GLsizei n, GLuint *programs); -typedef void (APIENTRY * ProgramStringProc) (GLenum target, GLenum format, GLsizei len, const void *string); -typedef void (APIENTRY * ProgramLocalParameter4fvProc) (GLenum target, GLuint index, const GLfloat *params); - void VertexProgram::apply(State& state) const { - static bool supported = osg::isGLExtensionSupported("GL_ARB_vertex_program"); - if (!supported) return; + const unsigned int contextID = state.getContextID(); + const Extensions* extensions = getExtensions(contextID,true); - static BindProgramProc s_glBindProgram = - (BindProgramProc)osg::getGLExtensionFuncPtr("glBindProgramARB"); - static GenProgramsProc s_glGenPrograms = - (GenProgramsProc)osg::getGLExtensionFuncPtr("glGenProgramsARB"); - static ProgramStringProc s_glProgramString = - (ProgramStringProc)osg::getGLExtensionFuncPtr("glProgramStringARB"); - static ProgramLocalParameter4fvProc s_glProgramLocalParameter4fv = - (ProgramLocalParameter4fvProc)osg::getGLExtensionFuncPtr("glProgramLocalParameter4fvARB"); + if (!extensions->isVertexProgramSupported()) + return; GLuint& vertexProgramId=getVertexProgramID(state.getContextID()); @@ -58,15 +46,15 @@ void VertexProgram::apply(State& state) const // Vertex Program if (vertexProgramId != 0) { - s_glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId ); + extensions->glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId ); } else if (!_vertexProgram.empty()) { ::glGetError(); // Reset Error flags. - s_glGenPrograms( 1, &vertexProgramId ); - s_glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId ); - s_glProgramString( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - _vertexProgram.length(), _vertexProgram.c_str()); + extensions->glGenPrograms( 1, &vertexProgramId ); + extensions->glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId ); + extensions->glProgramString( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + _vertexProgram.length(), _vertexProgram.c_str()); // Check for errors GLint errorposition; @@ -93,7 +81,7 @@ void VertexProgram::apply(State& state) const itr!=_programLocalParameters.end(); ++itr) { - s_glProgramLocalParameter4fv(GL_VERTEX_PROGRAM_ARB, (*itr).first, (*itr).second.ptr()); + extensions->glProgramLocalParameter4fv(GL_VERTEX_PROGRAM_ARB, (*itr).first, (*itr).second.ptr()); } } @@ -112,3 +100,105 @@ void VertexProgram::apply(State& state) const } +typedef buffered_value< ref_ptr > BufferedExtensions; +static BufferedExtensions s_extensions; + +VertexProgram::Extensions* VertexProgram::getExtensions(unsigned int contextID,bool createIfNotInitalized) +{ + if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions; + return s_extensions[contextID].get(); +} + +void VertexProgram::setExtensions(unsigned int contextID,Extensions* extensions) +{ + s_extensions[contextID] = extensions; +} + +VertexProgram::Extensions::Extensions() +{ + setupGLExtenions(); +} + +VertexProgram::Extensions::Extensions(const Extensions& rhs): + Referenced() +{ + _isVertexProgramSupported = rhs._isVertexProgramSupported; + _glBindProgram = rhs._glBindProgram; + _glGenPrograms = rhs._glGenPrograms; + _glProgramString = rhs._glProgramString; + _glProgramLocalParameter4fv = rhs._glProgramLocalParameter4fv; +} + + +void VertexProgram::Extensions::lowestCommonDenominator(const Extensions& rhs) +{ + if (!rhs._isVertexProgramSupported) _isVertexProgramSupported = false; + + if (!rhs._glBindProgram) _glBindProgram = 0; + if (!rhs._glGenPrograms) _glGenPrograms = 0; + if (!rhs._glProgramString) _glProgramString = 0; + if (!rhs._glProgramLocalParameter4fv) _glProgramLocalParameter4fv = 0; + +} + +void VertexProgram::Extensions::setupGLExtenions() +{ + _isVertexProgramSupported = isGLExtensionSupported("GL_ARB_vertex_program"); + + _glBindProgram = osg::getGLExtensionFuncPtr("glBindProgramARB"); + _glGenPrograms = osg::getGLExtensionFuncPtr("glGenProgramsARB"); + _glProgramString = osg::getGLExtensionFuncPtr("glProgramStringARB"); + _glProgramLocalParameter4fv = osg::getGLExtensionFuncPtr("glProgramLocalParameter4fvARB"); +} + +void VertexProgram::Extensions::glBindProgram(GLenum target, GLuint id) const +{ + if (_glBindProgram) + { + typedef void (APIENTRY * BindProgramProc) (GLenum target, GLuint id); + ((BindProgramProc)_glBindProgram)(target,id); + } + else + { + notify(WARN)<<"Error: glBindProgram not supported by OpenGL driver"<