From Art Trevs, "File Changes:

- GL2Extensions, Program and Program.cpp

Features:
- Support for fragment output binding. (e.g. You can now specify in the fragment shader varying out vec3 fragOut; fragOut = vec3(1,0,1); to write to the fragOut variable. In your program you call glBindFragDataLocation(program, 1, "fragOut") to bind the fragOut variable with the MRT 1 - GL_COLOR_ATTACHMENT1_EXT)

- new methods Program::add/removeBindFragDataLocation Program::getFragDataBindingList

"
This commit is contained in:
Robert Osfield
2007-09-11 13:34:41 +00:00
parent 884b3b7aa2
commit 175c3ce806
3 changed files with 99 additions and 2 deletions

View File

@@ -267,6 +267,11 @@ class OSG_EXPORT GL2Extensions : public osg::Referenced
bool getProgramInfoLog( GLuint program, std::string& result ) const;
bool getShaderInfoLog( GLuint shader, std::string& result ) const;
bool getAttribLocation( const char* attribName, GLuint& slot ) const;
bool getFragDataLocation( const char* fragDataName, GLuint& slot) const;
//EXT_gpu_shader4 to support frag data binding
void glBindFragDataLocation(GLuint program, GLuint colorNumber, const GLchar *name) const;
GLint glGetFragDataLocation(GLuint program, const GLchar *name) const;
protected:
~GL2Extensions() {}
@@ -377,6 +382,9 @@ class OSG_EXPORT GL2Extensions : public osg::Referenced
void* _glGetObjectParameterivARB;
void* _glDeleteObjectARB;
void* _glGetHandleARB;
void* _glBindFragDataLocation;
void* _glGetFragDataLocation;
};
}

View File

@@ -2,7 +2,7 @@
* Copyright (C) 2003-2005 3Dlabs Inc. Ltd.
* Copyright (C) 2004-2005 Nathan Cournia
*
* This application is open source and may be redistributed and/or modified
* 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.
*
@@ -94,12 +94,20 @@ class OSG_EXPORT Program : public osg::StateAttribute
/** Add an attribute location binding. */
void addBindAttribLocation( const std::string& name, GLuint index );
/** Add an attribute location binding. */
/** Remove an attribute location binding. */
void removeBindAttribLocation( const std::string& name );
/** Add an frag data location binding. See EXT_gpu_shader4 for BindFragDataLocationEXT */
void addBindFragDataLocation( const std::string& name, GLuint index );
/** Remove an frag data location binding. */
void removeBindFragDataLocation( const std::string& name );
typedef std::map<std::string,GLuint> AttribBindingList;
typedef std::map<std::string,GLuint> FragDataBindingList;
const AttribBindingList& getAttribBindingList() const { return _attribBindingList; }
const FragDataBindingList& getFragDataBindingList() const { return _fragDataBindingList; }
/** Return true if this Program represents "fixed-functionality" rendering */
bool isFixedFunction() const;
@@ -234,6 +242,7 @@ class OSG_EXPORT Program : public osg::StateAttribute
mutable osg::buffered_value< osg::ref_ptr<PerContextProgram> > _pcpList;
AttribBindingList _attribBindingList;
FragDataBindingList _fragDataBindingList;
typedef std::vector< ref_ptr<Shader> > ShaderList;
ShaderList _shaderList;

View File

@@ -153,6 +153,9 @@ GL2Extensions::GL2Extensions(const GL2Extensions& rhs) : osg::Referenced()
_glGetObjectParameterivARB = rhs._glGetObjectParameterivARB;
_glDeleteObjectARB = rhs._glDeleteObjectARB;
_glGetHandleARB = rhs._glGetHandleARB;
_glBindFragDataLocation = rhs._glBindFragDataLocation;
_glGetFragDataLocation = rhs._glGetFragDataLocation;
}
@@ -265,6 +268,9 @@ void GL2Extensions::lowestCommonDenominator(const GL2Extensions& rhs)
if (!rhs._glGetObjectParameterivARB) _glGetObjectParameterivARB = 0;
if (!rhs._glDeleteObjectARB) _glDeleteObjectARB = 0;
if (!rhs._glGetHandleARB) _glGetHandleARB = 0;
if (!rhs._glBindFragDataLocation) _glBindFragDataLocation = 0;
if (!rhs._glGetFragDataLocation) _glGetFragDataLocation = 0;
}
@@ -402,6 +408,13 @@ void GL2Extensions::setupGL2Extensions(unsigned int contextID)
_glGetObjectParameterivARB = osg::getGLExtensionFuncPtr("glGetObjectParameterivARB");
_glDeleteObjectARB = osg::getGLExtensionFuncPtr("glDeleteObjectARB");
_glGetHandleARB = osg::getGLExtensionFuncPtr("glGetHandleARB");
// v2.1 check also for EXT and ARB names, since this extension can became ARB later
_glBindFragDataLocation = osg::getGLExtensionFuncPtr("glBindFragDataLocation", "glBindFragDataLocationARB");
if (_glBindFragDataLocation == NULL) _glBindFragDataLocation = osg::getGLExtensionFuncPtr("glBindFragDataLocationEXT");
_glGetFragDataLocation = osg::getGLExtensionFuncPtr("glGetFragDataLocation", "glGetFragDataLocationARB");
if (_glGetFragDataLocation == NULL) _glGetFragDataLocation = osg::getGLExtensionFuncPtr("glGetFragDataLocationEXT");
}
@@ -1782,6 +1795,32 @@ void GL2Extensions::glVertexAttribPointer(GLuint index, GLint size, GLenum type,
}
}
void GL2Extensions::glBindFragDataLocation(GLuint program, GLuint colorIndex, const GLchar *name) const
{
if (_glBindFragDataLocation)
{
typedef void (APIENTRY * BindFragDataLocationProc)(GLuint , GLuint, const GLchar*);
((BindFragDataLocationProc)_glBindFragDataLocation)(program, colorIndex, name);
}
else
{
NotSupported( "glBindFragDataLocation" );
}
}
GLint GL2Extensions::glGetFragDataLocation(GLuint program, const GLchar *name) const
{
if (_glGetFragDataLocation)
{
typedef GLint (APIENTRY * GetFragDataLocationProc)(GLuint, const GLchar*);
return ((GetFragDataLocationProc)_glGetFragDataLocation)(program, name);
}
else
{
NotSupported( "glGetFragDataLocation" );
return -1;
}
}
///////////////////////////////////////////////////////////////////////////
// C++-friendly convenience methods
@@ -1866,6 +1905,28 @@ bool GL2Extensions::getAttribLocation( const char* attribName, GLuint& location
}
bool GL2Extensions::getFragDataLocation( const char* fragDataName, GLuint& location ) const
{
// is there an active GLSL program?
GLuint program = getCurrentProgram();
if( glIsProgram(program) == GL_FALSE ) return false;
// has that program been successfully linked?
GLint linked = GL_FALSE;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if( linked == GL_FALSE ) return false;
// check if supported
if (_glGetFragDataLocation == NULL) return false;
// is there such a named attribute?
GLint loc = glGetFragDataLocation( program, fragDataName );
if( loc < 0 ) return false;
location = loc;
return true;
}
///////////////////////////////////////////////////////////////////////////
// static cache of glPrograms flagged for deletion, which will actually
// be deleted in the correct GL context.
@@ -2079,6 +2140,17 @@ void Program::removeBindAttribLocation( const std::string& name )
dirtyProgram();
}
void Program::addBindFragDataLocation( const std::string& name, GLuint index )
{
_fragDataBindingList[name] = index;
dirtyProgram();
}
void Program::removeBindFragDataLocation( const std::string& name )
{
_fragDataBindingList.erase(name);
dirtyProgram();
}
void Program::apply( osg::State& state ) const
{
@@ -2206,6 +2278,14 @@ void Program::PerContextProgram::linkProgram()
_extensions->glBindAttribLocation( _glProgramHandle, itr->second, itr->first.c_str() );
}
// set any explicit frag data bindings
const FragDataBindingList& fdbindlist = _program->getFragDataBindingList();
for( FragDataBindingList::const_iterator itr = fdbindlist.begin();
itr != fdbindlist.end(); ++itr )
{
_extensions->glBindFragDataLocation( _glProgramHandle, itr->second, itr->first.c_str() );
}
// link the glProgram
GLint linked = GL_FALSE;
_extensions->glLinkProgram( _glProgramHandle );