From Mike Weiblen, adding prelimimnary GL Shader Language support into core OSG lib.
with renaming and reordering by Robert Osfield,
This commit is contained in:
@@ -39,8 +39,10 @@ CXXFILES =\
|
||||
FrameStamp.cpp\
|
||||
FrontFace.cpp\
|
||||
GLExtensions.cpp\
|
||||
Geometry.cpp\
|
||||
Geode.cpp\
|
||||
Geometry.cpp\
|
||||
Program.cpp\
|
||||
Uniform.cpp\
|
||||
Group.cpp\
|
||||
dxtctool.cpp\
|
||||
Image.cpp\
|
||||
@@ -78,6 +80,7 @@ CXXFILES =\
|
||||
Quat.cpp\
|
||||
Referenced.cpp\
|
||||
Sequence.cpp\
|
||||
Shader.cpp\
|
||||
ShadeModel.cpp\
|
||||
ShadowVolumeOccluder.cpp\
|
||||
Shape.cpp\
|
||||
|
||||
2163
src/osg/Program.cpp
Normal file
2163
src/osg/Program.cpp
Normal file
File diff suppressed because it is too large
Load Diff
239
src/osg/Shader.cpp
Normal file
239
src/osg/Shader.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
|
||||
* Copyright (C) 2003-2005 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/osg/Program.cpp
|
||||
* author: Mike Weiblen 2005-02-20
|
||||
*/
|
||||
|
||||
// NOTICE: This code is CLOSED during construction and/or renovation!
|
||||
// It is in active development, so DO NOT yet use in application code.
|
||||
// This notice will be removed when the code is open for business.
|
||||
// For development plan and status see:
|
||||
// http://www.openscenegraph.org/index.php?page=Community.DevelopmentWork
|
||||
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/State>
|
||||
#include <osg/Timer>
|
||||
#include <osg/FrameStamp>
|
||||
#include <osg/buffered_value>
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Shader>
|
||||
#include <osg/GLExtensions>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
typedef std::list<GLuint> GlShaderHandleList;
|
||||
typedef std::map<unsigned int, GlShaderHandleList> DeletedGlShaderCache;
|
||||
|
||||
static OpenThreads::Mutex s_mutex_deletedGL2ShaderCache;
|
||||
static DeletedGlShaderCache s_deletedGlShaderCache;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// osg::Shader
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Shader::Shader(Type type, const char* sourceText) :
|
||||
_type(type)
|
||||
{
|
||||
setShaderSource( sourceText );
|
||||
}
|
||||
|
||||
Shader::Shader(const Shader& rhs, const osg::CopyOp& /*copyop*/):
|
||||
Referenced( rhs ),
|
||||
_type(rhs._type)
|
||||
{
|
||||
/*TODO*/
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
/*TODO*/
|
||||
}
|
||||
|
||||
int Shader::compare(const Shader& rhs) const
|
||||
{
|
||||
if( this == &rhs ) return 0;
|
||||
|
||||
if( getComment() < rhs.getComment() ) return -1;
|
||||
if( rhs.getComment() < getComment() ) return 1;
|
||||
|
||||
if( getShaderSource() < rhs.getShaderSource() ) return -1;
|
||||
if( rhs.getShaderSource() < getShaderSource() ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Shader::dirtyShader()
|
||||
{
|
||||
// mark each PCSO as needing a recompile
|
||||
for( unsigned int cxt=0; cxt < _pcsoList.size(); ++cxt )
|
||||
{
|
||||
if( ! _pcsoList[cxt] ) continue;
|
||||
|
||||
PerContextShaderObj* pcso = _pcsoList[cxt].get();
|
||||
pcso->markAsDirty();
|
||||
}
|
||||
|
||||
// also mark-as-dirty the Programs we're attach to
|
||||
for( unsigned int i=0; i < _programList.size(); ++i )
|
||||
{
|
||||
_programList[i]->dirtyProgram();
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::setShaderSource( const char* sourceText )
|
||||
{
|
||||
_shaderSource = ( sourceText ? sourceText : "" );
|
||||
dirtyShader();
|
||||
}
|
||||
|
||||
bool Shader::loadShaderSourceFromFile( const char* fileName )
|
||||
{
|
||||
std::ifstream sourceFile;
|
||||
|
||||
sourceFile.open(fileName, std::ios::binary);
|
||||
if(!sourceFile)
|
||||
{
|
||||
osg::notify(osg::WARN)<<"Error: can't open file \""<<fileName<<"\""<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"Loading shader source file \""<<fileName<<"\""<<std::endl;
|
||||
|
||||
sourceFile.seekg(0, std::ios::end);
|
||||
int length = sourceFile.tellg();
|
||||
char *text = new char[length + 1];
|
||||
sourceFile.seekg(0, std::ios::beg);
|
||||
sourceFile.read(text, length);
|
||||
sourceFile.close();
|
||||
text[length] = '\0';
|
||||
|
||||
setShaderSource( text );
|
||||
delete [] text;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* Shader::getTypename() const
|
||||
{
|
||||
switch( getType() )
|
||||
{
|
||||
case VERTEX: return "Vertex";
|
||||
case FRAGMENT: return "Fragment";
|
||||
default: return "UNDEFINED";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Shader::compileShader( unsigned int contextID ) const
|
||||
{
|
||||
PerContextShaderObj* pcso = getPCSO( contextID );
|
||||
if( pcso->isDirty() ) pcso->compileShader();
|
||||
}
|
||||
|
||||
|
||||
Shader::PerContextShaderObj* Shader::getPCSO(unsigned int contextID) const
|
||||
{
|
||||
if( ! _pcsoList[contextID].valid() )
|
||||
{
|
||||
_pcsoList[contextID] = new PerContextShaderObj( this, contextID );
|
||||
}
|
||||
return _pcsoList[contextID].get();
|
||||
}
|
||||
|
||||
|
||||
void Shader::attachShader(unsigned int contextID, GLuint program) const
|
||||
{
|
||||
getPCSO( contextID )->attachShader( program );
|
||||
}
|
||||
|
||||
|
||||
void Shader::addProgObjRef( Program* program )
|
||||
{
|
||||
_programList.push_back( program );
|
||||
}
|
||||
|
||||
|
||||
void Shader::deleteShader(unsigned int contextID, GLuint shader)
|
||||
{
|
||||
if( shader )
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedGL2ShaderCache);
|
||||
|
||||
// add shader to the cache for the appropriate context.
|
||||
s_deletedGlShaderCache[contextID].push_back(shader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// osg::Shader::PerContextShaderObj
|
||||
// PCSO is the OSG abstraction of the per-context glShader
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Shader::PerContextShaderObj::PerContextShaderObj(const Shader* shader, unsigned int contextID) :
|
||||
osg::Referenced(),
|
||||
_contextID( contextID )
|
||||
{
|
||||
_shader = shader;
|
||||
_extensions = GL2Extensions::Get( _contextID, true );
|
||||
_glShaderHandle = _extensions->glCreateShader( shader->getType() );
|
||||
markAsDirty();
|
||||
}
|
||||
|
||||
Shader::PerContextShaderObj::PerContextShaderObj(const PerContextShaderObj& rhs) :
|
||||
osg::Referenced(),
|
||||
_contextID( rhs._contextID )
|
||||
{
|
||||
_shader = rhs._shader;
|
||||
_extensions = rhs._extensions;
|
||||
_glShaderHandle = rhs._glShaderHandle;
|
||||
_dirty = rhs._dirty;
|
||||
}
|
||||
|
||||
Shader::PerContextShaderObj::~PerContextShaderObj()
|
||||
{
|
||||
}
|
||||
|
||||
void Shader::PerContextShaderObj::compileShader()
|
||||
{
|
||||
GLint compiled;
|
||||
const char* sourceText = _shader->getShaderSource().c_str();
|
||||
|
||||
_extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL );
|
||||
_extensions->glCompileShader( _glShaderHandle );
|
||||
_extensions->glGetShaderiv( _glShaderHandle, GL_COMPILE_STATUS, &compiled );
|
||||
_dirty = (compiled == 0);
|
||||
|
||||
if( _dirty )
|
||||
{
|
||||
// _still_ dirty, something went wrong
|
||||
std::string infoLog;
|
||||
_extensions->getShaderInfoLog( _glShaderHandle, infoLog );
|
||||
osg::notify(osg::WARN) << _shader->getTypename() <<
|
||||
" glCompileShader FAILED:\n" << infoLog << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::PerContextShaderObj::attachShader(GLuint program) const
|
||||
{
|
||||
_extensions->glAttachShader( program, _glShaderHandle );
|
||||
}
|
||||
|
||||
/*EOF*/
|
||||
527
src/osg/Uniform.cpp
Normal file
527
src/osg/Uniform.cpp
Normal file
@@ -0,0 +1,527 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
|
||||
* Copyright (C) 2003-2005 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/osg/Uniform.cpp
|
||||
* author: Mike Weiblen 2005-02-20
|
||||
*/
|
||||
|
||||
// NOTICE: This code is CLOSED during construction and/or renovation!
|
||||
// It is in active development, so DO NOT yet use in application code.
|
||||
// This notice will be removed when the code is open for business.
|
||||
// For development plan and status see:
|
||||
// http://www.openscenegraph.org/index.php?page=Community.DevelopmentWork
|
||||
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/Uniform>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// osg::Uniform::Value
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Uniform::Value::Value( const char* name, Type type ) :
|
||||
_name(name), _type(type), _isValid(false)
|
||||
{}
|
||||
|
||||
|
||||
Uniform::Value::Value( const Value& rhs ) :
|
||||
_name(rhs._name), _type(rhs._type), _isValid(false)
|
||||
{
|
||||
if( rhs._isValid ) copyData(rhs);
|
||||
}
|
||||
|
||||
|
||||
const char* Uniform::Value::getTypename( Type t )
|
||||
{
|
||||
switch( t )
|
||||
{
|
||||
case FLOAT: return "float";
|
||||
case FLOAT_VEC2: return "vec2";
|
||||
case FLOAT_VEC3: return "vec3";
|
||||
case FLOAT_VEC4: return "vec4";
|
||||
case INT: return "int";
|
||||
case INT_VEC2: return "ivec2";
|
||||
case INT_VEC3: return "ivec3";
|
||||
case INT_VEC4: return "ivec4";
|
||||
case BOOL: return "bool";
|
||||
case BOOL_VEC2: return "bvec2";
|
||||
case BOOL_VEC3: return "bvec3";
|
||||
case BOOL_VEC4: return "bvec4";
|
||||
case FLOAT_MAT2: return "mat2";
|
||||
case FLOAT_MAT3: return "mat3";
|
||||
case FLOAT_MAT4: return "mat4";
|
||||
case SAMPLER_1D: return "sampler1D";
|
||||
case SAMPLER_2D: return "sampler2D";
|
||||
case SAMPLER_3D: return "sampler3D";
|
||||
case SAMPLER_CUBE: return "samplerCube";
|
||||
case SAMPLER_1D_SHADOW: return "sampler1DShadow";
|
||||
case SAMPLER_2D_SHADOW: return "sampler2DShadow";
|
||||
default: return "UNDEFINED";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Uniform::Value::compare(const Value& rhs) const
|
||||
{
|
||||
if( this == &rhs ) return 0;
|
||||
|
||||
if( _type < rhs._type ) return -1;
|
||||
if( rhs._type < _type ) return 1;
|
||||
|
||||
// consider invalid values "less than" valid values
|
||||
if( !_isValid && rhs._isValid ) return -1;
|
||||
if( _isValid && !rhs._isValid ) return 1;
|
||||
|
||||
if( _name < rhs._name ) return -1;
|
||||
if( rhs._name < _name ) return 1;
|
||||
|
||||
if( isValid() ) return compareData( rhs );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Uniform::Value:: set( float f )
|
||||
{
|
||||
_data.f1 = f;
|
||||
_isValid = true;
|
||||
}
|
||||
|
||||
void Uniform::Value:: set( const osg::Vec2& v2 )
|
||||
{
|
||||
_data.f2[0] = v2.x();
|
||||
_data.f2[1] = v2.y();
|
||||
_isValid = true;
|
||||
}
|
||||
|
||||
void Uniform::Value:: set( const osg::Vec3& v3 )
|
||||
{
|
||||
_data.f3[0] = v3.x();
|
||||
_data.f3[1] = v3.y();
|
||||
_data.f3[2] = v3.z();
|
||||
_isValid = true;
|
||||
}
|
||||
|
||||
void Uniform::Value:: set( const osg::Vec4& v4 )
|
||||
{
|
||||
_data.f4[0] = v4.x();
|
||||
_data.f4[1] = v4.y();
|
||||
_data.f4[2] = v4.z();
|
||||
_data.f4[3] = v4.w();
|
||||
_isValid = true;
|
||||
}
|
||||
|
||||
//TODO void Uniform::Value:: set( const osg::Matrix2& m2 )
|
||||
|
||||
//TODO void Uniform::Value:: set( const osg::Matrix3& m3 )
|
||||
|
||||
void Uniform::Value:: set( const osg::Matrix& m4 )
|
||||
{ // TODO verify if needs to be transposed
|
||||
int n = 0;
|
||||
for(int row=0; row<4; ++row)
|
||||
{
|
||||
for(int col=0; col<4; ++col)
|
||||
{
|
||||
_data.f16[n++] = m4(row,col);
|
||||
}
|
||||
}
|
||||
_isValid = true;
|
||||
}
|
||||
|
||||
void Uniform::Value:: set( int i )
|
||||
{
|
||||
_data.i1 = i;
|
||||
_isValid = true;
|
||||
}
|
||||
|
||||
//TODO void Uniform::Value:: set( int i0, int i1 )
|
||||
|
||||
//TODO void Uniform::Value:: set( int i0, int i1, int i2 )
|
||||
|
||||
//TODO void Uniform::Value:: set( int i0, int i1, int i2, int i3 )
|
||||
|
||||
//TODO void Uniform::Value:: set( bool b )
|
||||
|
||||
//TODO void Uniform::Value:: set( bool b0, bool b1 )
|
||||
|
||||
//TODO void Uniform::Value:: set( bool b0, bool b1, bool b2 )
|
||||
|
||||
//TODO void Uniform::Value:: set( bool b0, bool b1, bool b2, bool b3 )
|
||||
|
||||
|
||||
|
||||
int Uniform::Value::compareData(const Value& rhs) const
|
||||
{
|
||||
// caller is responsible for ensuring that
|
||||
// _type==rhs._type && _isValid && rhs._isValid
|
||||
|
||||
switch( getType() )
|
||||
{
|
||||
case FLOAT:
|
||||
{
|
||||
if( _data.f1 < rhs._data.f1 ) return -1;
|
||||
if( _data.f1 > rhs._data.f1 ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case FLOAT_VEC2:
|
||||
{
|
||||
if( _data.f2[0] < rhs._data.f2[0] ) return -1;
|
||||
if( _data.f2[0] > rhs._data.f2[0] ) return 1;
|
||||
if( _data.f2[1] < rhs._data.f2[1] ) return -1;
|
||||
if( _data.f2[1] > rhs._data.f2[1] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case FLOAT_VEC3:
|
||||
{
|
||||
if( _data.f3[0] < rhs._data.f3[0] ) return -1;
|
||||
if( _data.f3[0] > rhs._data.f3[0] ) return 1;
|
||||
if( _data.f3[1] < rhs._data.f3[1] ) return -1;
|
||||
if( _data.f3[1] > rhs._data.f3[1] ) return 1;
|
||||
if( _data.f3[2] < rhs._data.f3[2] ) return -1;
|
||||
if( _data.f3[2] > rhs._data.f3[2] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case FLOAT_VEC4:
|
||||
case FLOAT_MAT2:
|
||||
{
|
||||
if( _data.f4[0] < rhs._data.f4[0] ) return -1;
|
||||
if( _data.f4[0] > rhs._data.f4[0] ) return 1;
|
||||
if( _data.f4[1] < rhs._data.f4[1] ) return -1;
|
||||
if( _data.f4[1] > rhs._data.f4[1] ) return 1;
|
||||
if( _data.f4[2] < rhs._data.f4[2] ) return -1;
|
||||
if( _data.f4[2] > rhs._data.f4[2] ) return 1;
|
||||
if( _data.f4[3] < rhs._data.f4[3] ) return -1;
|
||||
if( _data.f4[3] > rhs._data.f4[3] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case FLOAT_MAT3: return memcmp(_data.f9, rhs._data.f9, sizeof(_data.f9));
|
||||
|
||||
case FLOAT_MAT4: return memcmp(_data.f16, rhs._data.f16, sizeof(_data.f16));
|
||||
|
||||
case INT:
|
||||
case BOOL:
|
||||
case SAMPLER_1D:
|
||||
case SAMPLER_2D:
|
||||
case SAMPLER_3D:
|
||||
case SAMPLER_CUBE:
|
||||
case SAMPLER_1D_SHADOW:
|
||||
case SAMPLER_2D_SHADOW:
|
||||
{
|
||||
if( _data.i1 < rhs._data.i1 ) return -1;
|
||||
if( _data.i1 > rhs._data.i1 ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case INT_VEC2:
|
||||
case BOOL_VEC2:
|
||||
{
|
||||
if( _data.i2[0] < rhs._data.i2[0] ) return -1;
|
||||
if( _data.i2[0] > rhs._data.i2[0] ) return 1;
|
||||
if( _data.i2[1] < rhs._data.i2[1] ) return -1;
|
||||
if( _data.i2[1] > rhs._data.i2[1] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case INT_VEC3:
|
||||
case BOOL_VEC3:
|
||||
{
|
||||
if( _data.i3[0] < rhs._data.i3[0] ) return -1;
|
||||
if( _data.i3[0] > rhs._data.i3[0] ) return 1;
|
||||
if( _data.i3[1] < rhs._data.i3[1] ) return -1;
|
||||
if( _data.i3[1] > rhs._data.i3[1] ) return 1;
|
||||
if( _data.i3[2] < rhs._data.i3[2] ) return -1;
|
||||
if( _data.i3[2] > rhs._data.i3[2] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case INT_VEC4:
|
||||
case BOOL_VEC4:
|
||||
{
|
||||
if( _data.i4[0] < rhs._data.i4[0] ) return -1;
|
||||
if( _data.i4[0] > rhs._data.i4[0] ) return 1;
|
||||
if( _data.i4[1] < rhs._data.i4[1] ) return -1;
|
||||
if( _data.i4[1] > rhs._data.i4[1] ) return 1;
|
||||
if( _data.i4[2] < rhs._data.i4[2] ) return -1;
|
||||
if( _data.i4[2] > rhs._data.i4[2] ) return 1;
|
||||
if( _data.i4[3] < rhs._data.i4[3] ) return -1;
|
||||
if( _data.i4[3] > rhs._data.i4[3] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
osg::notify(osg::INFO) << "how got here?" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Uniform::Value::copyData(const Value& rhs)
|
||||
{
|
||||
// caller is responsible for ensuring that
|
||||
// _type==rhs._type && rhs._isValid
|
||||
|
||||
_isValid = true;
|
||||
switch( getType() )
|
||||
{
|
||||
case FLOAT:
|
||||
_data.f1 = rhs._data.f1;
|
||||
break;
|
||||
|
||||
case FLOAT_VEC2:
|
||||
_data.f2[0] = rhs._data.f2[0];
|
||||
_data.f2[1] = rhs._data.f2[1];
|
||||
break;
|
||||
|
||||
case FLOAT_VEC3:
|
||||
_data.f3[0] = rhs._data.f3[0];
|
||||
_data.f3[1] = rhs._data.f3[1];
|
||||
_data.f3[2] = rhs._data.f3[2];
|
||||
break;
|
||||
|
||||
case FLOAT_VEC4:
|
||||
case FLOAT_MAT2:
|
||||
_data.f4[0] = rhs._data.f4[0];
|
||||
_data.f4[1] = rhs._data.f4[1];
|
||||
_data.f4[2] = rhs._data.f4[2];
|
||||
_data.f4[3] = rhs._data.f4[3];
|
||||
break;
|
||||
|
||||
case FLOAT_MAT3:
|
||||
for(int i=0;i<9;++i) _data.f9[i]=rhs._data.f9[i];
|
||||
break;
|
||||
|
||||
case FLOAT_MAT4:
|
||||
for(int i=0;i<16;++i) _data.f16[i]=rhs._data.f16[i];
|
||||
break;
|
||||
|
||||
case INT:
|
||||
case BOOL:
|
||||
case SAMPLER_1D:
|
||||
case SAMPLER_2D:
|
||||
case SAMPLER_3D:
|
||||
case SAMPLER_CUBE:
|
||||
case SAMPLER_1D_SHADOW:
|
||||
case SAMPLER_2D_SHADOW:
|
||||
_data.i1 = rhs._data.i1;
|
||||
break;
|
||||
|
||||
case INT_VEC2:
|
||||
case BOOL_VEC2:
|
||||
_data.i2[0] = rhs._data.i2[0];
|
||||
_data.i2[1] = rhs._data.i2[1];
|
||||
break;
|
||||
|
||||
case INT_VEC3:
|
||||
case BOOL_VEC3:
|
||||
_data.i3[0] = rhs._data.i3[0];
|
||||
_data.i3[1] = rhs._data.i3[1];
|
||||
_data.i3[2] = rhs._data.i3[2];
|
||||
break;
|
||||
|
||||
case INT_VEC4:
|
||||
case BOOL_VEC4:
|
||||
_data.i4[0] = rhs._data.i4[0];
|
||||
_data.i4[1] = rhs._data.i4[1];
|
||||
_data.i4[2] = rhs._data.i4[2];
|
||||
_data.i4[3] = rhs._data.i4[3];
|
||||
break;
|
||||
|
||||
default:
|
||||
osg::notify(osg::INFO) << "how got here?" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// osg::Uniform
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Uniform::Uniform() :
|
||||
_value( "", Value::UNDEFINED )
|
||||
{
|
||||
// do not use this constructor in application code!
|
||||
// it exists only because StateAttribute _requires_ a trivial default
|
||||
// constructor, but that is concept is meaningless for Uniform.
|
||||
}
|
||||
|
||||
|
||||
Uniform::Uniform( const char* name, Value::Type type ) :
|
||||
_value( name, type )
|
||||
{}
|
||||
|
||||
|
||||
Uniform::Uniform( const char* name, float f ) :
|
||||
_value( name, Value::FLOAT )
|
||||
{
|
||||
_value.set( f );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Vec2& v2 ) :
|
||||
_value( name, Value::FLOAT_VEC2 )
|
||||
{
|
||||
_value.set( v2 );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Vec3& v3 ) :
|
||||
_value( name, Value::FLOAT_VEC3 )
|
||||
{
|
||||
_value.set( v3 );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Vec4& v4 ) :
|
||||
_value( name, Value::FLOAT_VEC4 )
|
||||
{
|
||||
_value.set( v4 );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, const osg::Matrix2& m2 )
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, const osg::Matrix3& m3 )
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Matrix& m4 ) :
|
||||
_value( name, Value::FLOAT_MAT4 )
|
||||
{
|
||||
_value.set( m4 );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, int i ) :
|
||||
_value( name, Value::INT )
|
||||
{
|
||||
_value.set( i );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, int i0, int i1 )
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, int i0, int i1, int i2 )
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, int i0, int i1, int i2, int i3 )
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b )
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b0, bool b1 )
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b0, bool b1, bool b2 )
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 )
|
||||
|
||||
|
||||
Uniform::Uniform( const Uniform& gu, const CopyOp& copyop ) :
|
||||
StateAttribute(gu,copyop),
|
||||
_value( gu._value )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Uniform::apply( State& /*state*/ ) const
|
||||
{
|
||||
// The definition of apply() for Uniforms is unique among
|
||||
// osg::StateAttributes...
|
||||
// If a Program is not active, then cannot apply the uniform value,
|
||||
// but must wait for a Program to do that itself later when it
|
||||
// does become active.
|
||||
// If a Program is active, then the Uniform may be applied
|
||||
// immediately.
|
||||
// something like...
|
||||
//
|
||||
// Program* program = state->getActiveProgram();
|
||||
// if( program )
|
||||
// {
|
||||
// program->applyUniform( this );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Uniform::set( float f )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT ) ) return false;
|
||||
_value.set( f );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( const osg::Vec2& v2 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_VEC2 ) ) return false;
|
||||
_value.set( v2 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( const osg::Vec3& v3 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_VEC3 ) ) return false;
|
||||
_value.set( v3 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( const osg::Vec4& v4 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_VEC4 ) ) return false;
|
||||
_value.set( v4 );
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO bool Uniform::set( const osg::Matrix2& m2 )
|
||||
|
||||
//TODO bool Uniform::set( const osg::Matrix3& m3 )
|
||||
|
||||
bool Uniform::set( const osg::Matrix& m4 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_MAT4 ) ) return false;
|
||||
_value.set( m4 );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( int i )
|
||||
{
|
||||
if( ! isCompatibleType( Value::INT ) ) return false;
|
||||
_value.set( i );
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO bool Uniform::set( int i0, int i1 )
|
||||
|
||||
//TODO bool Uniform::set( int i0, int i1, int i2 )
|
||||
|
||||
//TODO bool Uniform::set( int i0, int i1, int i2, int i3 )
|
||||
|
||||
//TODO bool Uniform::set( bool b )
|
||||
|
||||
//TODO bool Uniform::set( bool b0, bool b1 );
|
||||
|
||||
//TODO bool Uniform::set( bool b0, bool b1, bool b2 )
|
||||
|
||||
//TODO bool Uniform::set( bool b0, bool b1, bool b2, bool b3 )
|
||||
|
||||
|
||||
bool Uniform::isCompatibleType( Value::Type t ) const
|
||||
{
|
||||
if( t == _value.getType() ) return true;
|
||||
|
||||
osg::notify(osg::WARN) <<
|
||||
"Cannot assign " << _value.getTypename(t) <<
|
||||
" to Uniform \"" << _value.getName() <<
|
||||
"\" of type " << _value.getTypename( _value.getType() ) <<
|
||||
std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*EOF*/
|
||||
Reference in New Issue
Block a user