/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield * Copyright (C) 2003-2004 3Dlabs Inc. Ltd. * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commericial and non commericial * applications, as long as this copyright notice is maintained. * * This application is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* file: src/osgGL2/Extensions.cpp * author: Mike Weiblen 2004-07-08 * * See http://www.3dlabs.com/opengl2/ for more information regarding * the OpenGL Shading Language. */ #include #include #include #include #include using namespace osgGL2; Extensions::Extensions() { setupGLExtensions(); } Extensions::Extensions(const Extensions& rhs) : osg::Referenced() { _isShaderObjectsSupported = rhs._isShaderObjectsSupported; _isVertexShaderSupported = rhs._isVertexShaderSupported; _isFragmentShaderSupported = rhs._isFragmentShaderSupported; _isLanguage100Supported = rhs._isLanguage100Supported; _languageVersion = rhs._languageVersion; _glCreateShaderObject = rhs._glCreateShaderObject; _glCreateProgramObject = rhs._glCreateProgramObject; _glDeleteObject = rhs._glDeleteObject; _glAttachObject = rhs._glAttachObject; _glDetachObject = rhs._glDetachObject; _glShaderSource = rhs._glShaderSource; _glCompileShader = rhs._glCompileShader; _glBindAttribLocation = rhs._glBindAttribLocation; _glLinkProgram = rhs._glLinkProgram; _glUseProgramObject = rhs._glUseProgramObject; _glGetInfoLog = rhs._glGetInfoLog; _glGetAttachedObjects = rhs._glGetAttachedObjects; _glGetShaderSource = rhs._glGetShaderSource; _glUniform1f = rhs._glUniform1f; _glUniform2f = rhs._glUniform2f; _glUniform3f = rhs._glUniform3f; _glUniform4f = rhs._glUniform4f; _glUniform1i = rhs._glUniform1i; _glUniform2i = rhs._glUniform2i; _glUniform3i = rhs._glUniform3i; _glUniform4i = rhs._glUniform4i; _glUniform1fv = rhs._glUniform1fv; _glUniform2fv = rhs._glUniform2fv; _glUniform3fv = rhs._glUniform3fv; _glUniform4fv = rhs._glUniform4fv; _glUniform1iv = rhs._glUniform1iv; _glUniform2iv = rhs._glUniform2iv; _glUniform3iv = rhs._glUniform3iv; _glUniform4iv = rhs._glUniform4iv; _glUniformMatrix2fv = rhs._glUniformMatrix2fv; _glUniformMatrix3fv = rhs._glUniformMatrix3fv; _glUniformMatrix4fv = rhs._glUniformMatrix4fv; _glGetUniformLocation = rhs._glGetUniformLocation; _glGetAttribLocation = rhs._glGetAttribLocation; _glGetActiveUniform = rhs._glGetActiveUniform; _glGetActiveAttribs = rhs._glGetActiveAttribs; _glGetUniformfv = rhs._glGetUniformfv; _glGetUniformiv = rhs._glGetUniformiv; _glGetObjectParameterfv = rhs._glGetObjectParameterfv; _glGetObjectParameteriv = rhs._glGetObjectParameteriv; _glGetHandle = rhs._glGetHandle; } void Extensions::lowestCommonDenominator(const Extensions& rhs) { if (!rhs._isShaderObjectsSupported) _isShaderObjectsSupported = false; if (!rhs._isVertexShaderSupported) _isVertexShaderSupported = false; if (!rhs._isFragmentShaderSupported) _isFragmentShaderSupported = false; if (!rhs._isLanguage100Supported) _isLanguage100Supported = false; if (rhs._languageVersion < _languageVersion) _languageVersion = rhs._languageVersion; if (!rhs._glCreateShaderObject) _glCreateShaderObject = 0; if (!rhs._glCreateProgramObject) _glCreateProgramObject = 0; if (!rhs._glDeleteObject) _glDeleteObject = 0; if (!rhs._glAttachObject) _glAttachObject = 0; if (!rhs._glDetachObject) _glDetachObject = 0; if (!rhs._glShaderSource) _glShaderSource = 0; if (!rhs._glCompileShader) _glCompileShader = 0; if (!rhs._glBindAttribLocation) _glBindAttribLocation = 0; if (!rhs._glLinkProgram) _glLinkProgram = 0; if (!rhs._glUseProgramObject) _glUseProgramObject = 0; if (!rhs._glGetInfoLog) _glGetInfoLog = 0; if (!rhs._glGetAttachedObjects) _glGetAttachedObjects = 0; if (!rhs._glGetShaderSource) _glGetShaderSource = 0; if (!rhs._glUniform1f) _glUniform1f = 0; if (!rhs._glUniform2f) _glUniform2f = 0; if (!rhs._glUniform3f) _glUniform3f = 0; if (!rhs._glUniform4f) _glUniform4f = 0; if (!rhs._glUniform1i) _glUniform1i = 0; if (!rhs._glUniform2i) _glUniform2i = 0; if (!rhs._glUniform3i) _glUniform3i = 0; if (!rhs._glUniform4i) _glUniform4i = 0; if (!rhs._glUniform1fv) _glUniform1fv = 0; if (!rhs._glUniform2fv) _glUniform2fv = 0; if (!rhs._glUniform3fv) _glUniform3fv = 0; if (!rhs._glUniform4fv) _glUniform4fv = 0; if (!rhs._glUniform1iv) _glUniform1iv = 0; if (!rhs._glUniform2iv) _glUniform2iv = 0; if (!rhs._glUniform3iv) _glUniform3iv = 0; if (!rhs._glUniform4iv) _glUniform4iv = 0; if (!rhs._glUniformMatrix2fv) _glUniformMatrix2fv = 0; if (!rhs._glUniformMatrix3fv) _glUniformMatrix3fv = 0; if (!rhs._glUniformMatrix4fv) _glUniformMatrix4fv = 0; if (!rhs._glGetUniformLocation) _glGetUniformLocation = 0; if (!rhs._glGetAttribLocation) _glGetAttribLocation = 0; if (!rhs._glGetActiveUniform) _glGetActiveUniform = 0; if (!rhs._glGetActiveAttribs) _glGetActiveAttribs = 0; if (!rhs._glGetUniformfv) _glGetUniformfv = 0; if (!rhs._glGetUniformiv) _glGetUniformiv = 0; if (!rhs._glGetObjectParameterfv) _glGetObjectParameterfv = 0; if (!rhs._glGetObjectParameteriv) _glGetObjectParameteriv = 0; if (!rhs._glGetHandle) _glGetHandle = 0; } void Extensions::setupGLExtensions() { _isShaderObjectsSupported = osg::isGLExtensionSupported("GL_ARB_shader_objects"); _isVertexShaderSupported = osg::isGLExtensionSupported("GL_ARB_vertex_shader"); _isFragmentShaderSupported = osg::isGLExtensionSupported("GL_ARB_fragment_shader"); _isLanguage100Supported = osg::isGLExtensionSupported("GL_ARB_shading_language_100"); _languageVersion = 0.0f; if( _isLanguage100Supported ) { // If glGetString raises an error, assume initial release "1.00" glGetError(); // reset error flag const char* langVerStr = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); const GLenum errorNum = glGetError(); if( (errorNum != GL_NO_ERROR) || (langVerStr == 0) ) { langVerStr = "1.00 (default)"; } osg::notify(osg::INFO) << "GL_SHADING_LANGUAGE_VERSION_ARB: \"" << langVerStr << "\"" << std::endl; // TODO verify this parser is sufficiently robust _languageVersion = atof( langVerStr ); } osg::notify(osg::INFO) << "GLSL language version = " << _languageVersion << std::endl; _glCreateShaderObject = osg::getGLExtensionFuncPtr("glCreateShaderObjectARB"); _glCreateProgramObject = osg::getGLExtensionFuncPtr("glCreateProgramObjectARB"); _glDeleteObject = osg::getGLExtensionFuncPtr("glDeleteObjectARB"); _glAttachObject = osg::getGLExtensionFuncPtr("glAttachObjectARB"); _glDetachObject = osg::getGLExtensionFuncPtr("glDetachObjectARB"); _glShaderSource = osg::getGLExtensionFuncPtr("glShaderSourceARB"); _glCompileShader = osg::getGLExtensionFuncPtr("glCompileShaderARB"); _glBindAttribLocation = osg::getGLExtensionFuncPtr("glBindAttribLocationARB"); _glLinkProgram = osg::getGLExtensionFuncPtr("glLinkProgramARB"); _glUseProgramObject = osg::getGLExtensionFuncPtr("glUseProgramObjectARB"); _glGetInfoLog = osg::getGLExtensionFuncPtr("glGetInfoLogARB"); _glGetAttachedObjects = osg::getGLExtensionFuncPtr("glGetAttachedObjectsARB"); _glGetShaderSource = osg::getGLExtensionFuncPtr("glGetShaderSourceARB"); _glUniform1f = osg::getGLExtensionFuncPtr("glUniform1fARB"); _glUniform2f = osg::getGLExtensionFuncPtr("glUniform2fARB"); _glUniform3f = osg::getGLExtensionFuncPtr("glUniform3fARB"); _glUniform4f = osg::getGLExtensionFuncPtr("glUniform4fARB"); _glUniform1i = osg::getGLExtensionFuncPtr("glUniform1iARB"); _glUniform2i = osg::getGLExtensionFuncPtr("glUniform2iARB"); _glUniform3i = osg::getGLExtensionFuncPtr("glUniform3iARB"); _glUniform4i = osg::getGLExtensionFuncPtr("glUniform4iARB"); _glUniform1fv = osg::getGLExtensionFuncPtr("glUniform1fvARB"); _glUniform2fv = osg::getGLExtensionFuncPtr("glUniform2fvARB"); _glUniform3fv = osg::getGLExtensionFuncPtr("glUniform3fvARB"); _glUniform4fv = osg::getGLExtensionFuncPtr("glUniform4fvARB"); _glUniform1iv = osg::getGLExtensionFuncPtr("glUniform1ivARB"); _glUniform2iv = osg::getGLExtensionFuncPtr("glUniform2ivARB"); _glUniform3iv = osg::getGLExtensionFuncPtr("glUniform3ivARB"); _glUniform4iv = osg::getGLExtensionFuncPtr("glUniform4ivARB"); _glUniformMatrix2fv = osg::getGLExtensionFuncPtr("glUniformMatrix2fvARB"); _glUniformMatrix3fv = osg::getGLExtensionFuncPtr("glUniformMatrix3fvARB"); _glUniformMatrix4fv = osg::getGLExtensionFuncPtr("glUniformMatrix4fvARB"); _glGetUniformLocation = osg::getGLExtensionFuncPtr("glGetUniformLocationARB"); _glGetAttribLocation = osg::getGLExtensionFuncPtr("glGetAttribLocationARB"); _glGetActiveUniform = osg::getGLExtensionFuncPtr("glGetActiveUniformARB"); _glGetActiveAttribs = osg::getGLExtensionFuncPtr("glGetActiveAttribsARB"); _glGetUniformfv = osg::getGLExtensionFuncPtr("glGetUniformfvARB"); _glGetUniformiv = osg::getGLExtensionFuncPtr("glGetUniformivARB"); _glGetObjectParameterfv = osg::getGLExtensionFuncPtr("glGetObjectParameterfvARB"); _glGetObjectParameteriv = osg::getGLExtensionFuncPtr("glGetObjectParameterivARB"); _glGetHandle = osg::getGLExtensionFuncPtr("glGetHandleARB"); } /***************************************************************************/ // Static array of per-context osgGL2::Extensions instances typedef osg::buffered_value< osg::ref_ptr > BufferedExtensions; static BufferedExtensions s_extensions; Extensions* Extensions::Get(unsigned int contextID, bool createIfNotInitalized) { if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions; return s_extensions[contextID].get(); } void Extensions::Set(unsigned int contextID, Extensions* extensions) { s_extensions[contextID] = extensions; } /***************************************************************************/ GLhandleARB Extensions::glCreateShaderObject(GLenum shaderType) const { if (_glCreateShaderObject) { typedef GLhandleARB (APIENTRY * CreateShaderObjectProc) (GLenum shaderType); return ((CreateShaderObjectProc)_glCreateShaderObject)(shaderType); } else { osg::notify(osg::WARN)<<"Error: glCreateShaderObject not supported by OpenGL driver"<