Added tests for presense of extensions to osgcubemap, osgvertexproram and

osgmultitexture examples.

Added osg::VertexProgram::Extensions class to better handle multiple graphics
context vertex program extensions.
This commit is contained in:
Robert Osfield 2003-04-10 19:32:32 +00:00
parent 52d2d8eaff
commit aaa761e333
8 changed files with 225 additions and 24 deletions

View File

@ -129,6 +129,23 @@ int main(int argc, char *argv[])
// create the windows and run the threads. // create the windows and run the threads.
viewer.realize(); viewer.realize();
// now check to see if texture cube map is supported.
for(unsigned int contextID = 0;
contextID<viewer.getDisplaySettings()->getMaxNumberOfGraphicsContexts();
++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."<<std::endl;
return 1;
}
}
}
while( !viewer.done() ) while( !viewer.done() )
{ {
// wait for all cull and draw threads to complete. // wait for all cull and draw threads to complete.

View File

@ -101,6 +101,21 @@ int main( int argc, char **argv )
// create the windows and run the threads. // create the windows and run the threads.
viewer.realize(); viewer.realize();
for(unsigned int contextID = 0;
contextID<viewer.getDisplaySettings()->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."<<std::endl;
return 1;
}
}
}
while( !viewer.done() ) while( !viewer.done() )
{ {
// wait for all cull and draw threads to complete. // wait for all cull and draw threads to complete.

View File

@ -405,6 +405,22 @@ int main(int argc, char *argv[])
// create the windows and run the threads. // create the windows and run the threads.
viewer.realize(); viewer.realize();
// now check to see if vertex program is supported.
for(unsigned int contextID = 0;
contextID<viewer.getDisplaySettings()->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."<<std::endl;
return 1;
}
}
}
while( !viewer.done() ) while( !viewer.done() )
{ {
// wait for all cull and draw threads to complete. // wait for all cull and draw threads to complete.

View File

@ -215,10 +215,10 @@ class SG_EXPORT StateAttribute : public Object
* in to allow the StateAttribute to obtain details on the * in to allow the StateAttribute to obtain details on the
* the current context and state. * the current context and state.
*/ */
virtual void apply(State&) const = 0 ; virtual void apply(State&) const = 0;
/** default to nothing to compile - all state is applied immediately. */ /** default to nothing to compile - all state is applied immediately. */
virtual void compile(State&) const {}; virtual void compile(State&) const {}
protected: protected:

View File

@ -251,6 +251,9 @@ class SG_EXPORT Texture : public osg::StateAttribute
void setupGLExtenions(); void setupGLExtenions();
void setMultiTexturingSupported(bool flag) { _isMultiTexturingSupported=flag; }
bool isMultiTexturingSupported() const { return _isMultiTexturingSupported; }
void setTextureFilterAnisotropicSupported(bool flag) { _isTextureFilterAnisotropicSupported=flag; } void setTextureFilterAnisotropicSupported(bool flag) { _isTextureFilterAnisotropicSupported=flag; }
bool isTextureFilterAnisotropicSupported() const { return _isTextureFilterAnisotropicSupported; } bool isTextureFilterAnisotropicSupported() const { return _isTextureFilterAnisotropicSupported; }
@ -290,6 +293,7 @@ class SG_EXPORT Texture : public osg::StateAttribute
~Extensions() {} ~Extensions() {}
bool _isMultiTexturingSupported;
bool _isTextureFilterAnisotropicSupported; bool _isTextureFilterAnisotropicSupported;
bool _isTextureCompressionARBSupported; bool _isTextureCompressionARBSupported;
bool _isTextureCompressionS3TCSupported; bool _isTextureCompressionS3TCSupported;

View File

@ -170,6 +170,57 @@ class SG_EXPORT VertexProgram : public StateAttribute
virtual void apply(State& state) const; virtual void apply(State& state) const;
virtual void compile(State& state) const { apply(state); }
/** Extensions class which encapsulates the querring of extensions and
* associated function pointers, and provide convinience wrappers to
* check for the extensions or use the associated functions.*/
class SG_EXPORT Extensions : public osg::Referenced
{
public:
Extensions();
Extensions(const Extensions& rhs);
void lowestCommonDenominator(const Extensions& rhs);
void setupGLExtenions();
void setVertexProgramSupported(bool flag) { _isVertexProgramSupported=flag; }
bool isVertexProgramSupported() const { return _isVertexProgramSupported; }
void glBindProgram(GLenum target, GLuint id) const;
void glGenPrograms(GLsizei n, GLuint *programs) const;
void glProgramString(GLenum target, GLenum format, GLsizei len, const void *string) const;
void glProgramLocalParameter4fv(GLenum target, GLuint index, const GLfloat *params) const;
protected:
~Extensions() {}
bool _isVertexProgramSupported;
void* _glBindProgram;
void* _glGenPrograms;
void* _glProgramString;
void* _glProgramLocalParameter4fv;
};
/** Function to call to get the extension of a specified context.
* If the Exentsion object for that context has not yet been created then
* and the 'createIfNotInitalized' flag been set to false then returns NULL.
* If 'createIfNotInitalized' is true then the Extensions object is
* automatically created. However, in this case the extension object
* only be created with the graphics context associated with ContextID..*/
static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized);
/** setExtensions allows users to override the extensions across graphics contexts.
* typically used when you have different extensions supported across graphics pipes
* but need to ensure that they all use the same low common denominator extensions.*/
static void setExtensions(unsigned int contextID,Extensions* extensions);
protected: protected:

View File

@ -850,6 +850,7 @@ Texture::Extensions::Extensions()
Texture::Extensions::Extensions(const Extensions& rhs): Texture::Extensions::Extensions(const Extensions& rhs):
Referenced() Referenced()
{ {
_isMultiTexturingSupported = rhs._isMultiTexturingSupported;
_isTextureFilterAnisotropicSupported = rhs._isTextureFilterAnisotropicSupported; _isTextureFilterAnisotropicSupported = rhs._isTextureFilterAnisotropicSupported;
_isTextureCompressionARBSupported = rhs._isTextureCompressionARBSupported; _isTextureCompressionARBSupported = rhs._isTextureCompressionARBSupported;
_isTextureCompressionS3TCSupported = rhs._isTextureCompressionS3TCSupported; _isTextureCompressionS3TCSupported = rhs._isTextureCompressionS3TCSupported;
@ -865,6 +866,8 @@ Texture::Extensions::Extensions(const Extensions& rhs):
void Texture::Extensions::lowestCommonDenominator(const Extensions& rhs) void Texture::Extensions::lowestCommonDenominator(const Extensions& rhs)
{ {
if (!rhs._isMultiTexturingSupported) _isMultiTexturingSupported = false;
if (!rhs._isTextureFilterAnisotropicSupported) _isTextureFilterAnisotropicSupported = false; if (!rhs._isTextureFilterAnisotropicSupported) _isTextureFilterAnisotropicSupported = false;
if (!rhs._isTextureMirroredRepeatSupported) _isTextureMirroredRepeatSupported = false; if (!rhs._isTextureMirroredRepeatSupported) _isTextureMirroredRepeatSupported = false;
if (!rhs._isTextureEdgeClampSupported) _isTextureEdgeClampSupported = false; if (!rhs._isTextureEdgeClampSupported) _isTextureEdgeClampSupported = false;
@ -878,11 +881,16 @@ void Texture::Extensions::lowestCommonDenominator(const Extensions& rhs)
if (rhs._maxTextureSize<_maxTextureSize) _maxTextureSize = rhs._maxTextureSize; if (rhs._maxTextureSize<_maxTextureSize) _maxTextureSize = rhs._maxTextureSize;
if (!rhs._glCompressedTexImage2D) _glCompressedTexImage2D = 0; if (!rhs._glCompressedTexImage2D) _glCompressedTexImage2D = 0;
if (!rhs._glCompressedTexSubImage2D) _glCompressedTexSubImage2D = 0;
if (!rhs._glGetCompressedTexImage) _glGetCompressedTexImage = 0;
} }
void Texture::Extensions::setupGLExtenions() void Texture::Extensions::setupGLExtenions()
{ {
_isMultiTexturingSupported = (strncmp((const char*)glGetString(GL_VERSION),"1.3",3)>=0) ||
isGLExtensionSupported("GL_ARB_multitexture") ||
isGLExtensionSupported("GL_EXT_multitexture");
_isTextureFilterAnisotropicSupported = isGLExtensionSupported("GL_EXT_texture_filter_anisotropic"); _isTextureFilterAnisotropicSupported = isGLExtensionSupported("GL_EXT_texture_filter_anisotropic");
_isTextureCompressionARBSupported = isGLExtensionSupported("GL_ARB_texture_compression"); _isTextureCompressionARBSupported = isGLExtensionSupported("GL_ARB_texture_compression");
_isTextureCompressionS3TCSupported = isGLExtensionSupported("GL_EXT_texture_compression_s3tc"); _isTextureCompressionS3TCSupported = isGLExtensionSupported("GL_EXT_texture_compression_s3tc");

View File

@ -32,25 +32,13 @@ VertexProgram::VertexProgram(const VertexProgram& vp,const CopyOp& copyop):
VertexProgram::~VertexProgram() 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 void VertexProgram::apply(State& state) const
{ {
static bool supported = osg::isGLExtensionSupported("GL_ARB_vertex_program"); const unsigned int contextID = state.getContextID();
if (!supported) return; const Extensions* extensions = getExtensions(contextID,true);
static BindProgramProc s_glBindProgram = if (!extensions->isVertexProgramSupported())
(BindProgramProc)osg::getGLExtensionFuncPtr("glBindProgramARB"); return;
static GenProgramsProc s_glGenPrograms =
(GenProgramsProc)osg::getGLExtensionFuncPtr("glGenProgramsARB");
static ProgramStringProc s_glProgramString =
(ProgramStringProc)osg::getGLExtensionFuncPtr("glProgramStringARB");
static ProgramLocalParameter4fvProc s_glProgramLocalParameter4fv =
(ProgramLocalParameter4fvProc)osg::getGLExtensionFuncPtr("glProgramLocalParameter4fvARB");
GLuint& vertexProgramId=getVertexProgramID(state.getContextID()); GLuint& vertexProgramId=getVertexProgramID(state.getContextID());
@ -58,15 +46,15 @@ void VertexProgram::apply(State& state) const
// Vertex Program // Vertex Program
if (vertexProgramId != 0) if (vertexProgramId != 0)
{ {
s_glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId ); extensions->glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId );
} }
else if (!_vertexProgram.empty()) else if (!_vertexProgram.empty())
{ {
::glGetError(); // Reset Error flags. ::glGetError(); // Reset Error flags.
s_glGenPrograms( 1, &vertexProgramId ); extensions->glGenPrograms( 1, &vertexProgramId );
s_glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId ); extensions->glBindProgram( GL_VERTEX_PROGRAM_ARB, vertexProgramId );
s_glProgramString( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, extensions->glProgramString( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
_vertexProgram.length(), _vertexProgram.c_str()); _vertexProgram.length(), _vertexProgram.c_str());
// Check for errors // Check for errors
GLint errorposition; GLint errorposition;
@ -93,7 +81,7 @@ void VertexProgram::apply(State& state) const
itr!=_programLocalParameters.end(); itr!=_programLocalParameters.end();
++itr) ++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<VertexProgram::Extensions> > 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"<<std::endl;
}
}
void VertexProgram::Extensions::glGenPrograms(GLsizei n, GLuint *programs) const
{
if (_glGenPrograms)
{
typedef void (APIENTRY * GenProgramsProc) (GLsizei n, GLuint *programs);
((GenProgramsProc)_glGenPrograms)(n,programs);
}
else
{
notify(WARN)<<"Error: glGenPrograms not supported by OpenGL driver"<<std::endl;
}
}
void VertexProgram::Extensions::glProgramString(GLenum target, GLenum format, GLsizei len, const void *string) const
{
if (_glProgramString)
{
typedef void (APIENTRY * ProgramStringProc) (GLenum target, GLenum format, GLsizei len, const void *string);
((ProgramStringProc)_glProgramString)(target,format, len, string);
}
else
{
notify(WARN)<<"Error: glProgramString not supported by OpenGL driver"<<std::endl;
}
}
void VertexProgram::Extensions::glProgramLocalParameter4fv(GLenum target, GLuint index, const GLfloat *params) const
{
if (_glProgramLocalParameter4fv)
{
typedef void (APIENTRY * ProgramLocalParameter4fvProc) (GLenum target, GLuint index, const GLfloat *params);
((ProgramLocalParameter4fvProc)_glProgramLocalParameter4fv)(target, index, params);
}
else
{
notify(WARN)<<"Error: glProgramLocalParameter4fv not supported by OpenGL driver"<<std::endl;
}
}