From Mike Weiblen, updates to Shander Language support
This commit is contained in:
parent
2e91a74f14
commit
aa8dbea11c
@ -12,21 +12,15 @@
|
||||
*/
|
||||
|
||||
/* file: include/osg/Program
|
||||
* author: Mike Weiblen 2005-03-23
|
||||
* author: Mike Weiblen 2005-03-30
|
||||
*/
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#ifndef OSG_PROGRAM
|
||||
#define OSG_PROGRAM 1
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <osg/buffered_value>
|
||||
#include <osg/ref_ptr>
|
||||
@ -180,6 +174,7 @@ class SG_EXPORT GL2Extensions : public osg::Referenced
|
||||
GLuint getCurrentProgram() const;
|
||||
bool getProgramInfoLog( GLuint program, std::string& result ) const;
|
||||
bool getShaderInfoLog( GLuint shader, std::string& result ) const;
|
||||
bool getAttribLocation( const char* attribName, GLuint& slot ) const;
|
||||
|
||||
protected:
|
||||
~GL2Extensions() {}
|
||||
@ -339,8 +334,10 @@ class SG_EXPORT Program : public osg::StateAttribute
|
||||
* Mark Program as needing relink. Return true for success */
|
||||
bool removeShader( Shader* shader );
|
||||
|
||||
/** */
|
||||
/** Add an attribute location binding. */
|
||||
void bindAttribLocation( GLuint index, const char* name );
|
||||
typedef std::map<std::string,GLuint> AttribBindingList;
|
||||
const AttribBindingList& getAttribBindingList() const { return _attribBindingList; }
|
||||
|
||||
/** Return true if this Program represents "fixed-functionality" rendering */
|
||||
bool isFixedFunction() const;
|
||||
@ -353,12 +350,6 @@ class SG_EXPORT Program : public osg::StateAttribute
|
||||
void setName( const char* name ) { _name = name; }
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
/** should Uniform values be tested to avoid redundant setting? */
|
||||
void setAvoidRedundantUniformSetting( bool flag ) { _avoidRedundantUniformSetting = flag; }
|
||||
bool getAvoidRedundantUniformSetting() const { return _avoidRedundantUniformSetting; }
|
||||
|
||||
// TODO glBindAttribLocation
|
||||
|
||||
/** Mark internal glProgram for deletion.
|
||||
* Deletion requests are queued until they can be executed
|
||||
* in the proper GL context. */
|
||||
@ -370,23 +361,22 @@ class SG_EXPORT Program : public osg::StateAttribute
|
||||
|
||||
|
||||
protected:
|
||||
/** An OSG-internal encapsulation of glProgram's active uniforms */
|
||||
class ActiveUniform : public osg::Referenced
|
||||
class ActiveUniform : public osg::Uniform
|
||||
{
|
||||
public:
|
||||
ActiveUniform( const GLchar* name, GLenum type );
|
||||
ActiveUniform( const char* name, GLenum type, GLint loc );
|
||||
void applyData( const GL2Extensions* ext, GLuint prog );
|
||||
|
||||
protected:
|
||||
virtual ~ActiveUniform() {}
|
||||
|
||||
Uniform::Value _value;
|
||||
GLint _location;
|
||||
const GLint _location;
|
||||
|
||||
private:
|
||||
ActiveUniform(); // disallowed
|
||||
ActiveUniform(ActiveUniform&); // disallowed
|
||||
ActiveUniform& operator=(ActiveUniform&); // disallowed
|
||||
};
|
||||
typedef osg::ref_ptr< ActiveUniform > ActiveUniformPtr;
|
||||
typedef std::vector< ActiveUniformPtr > ActiveUniformList;
|
||||
typedef std::vector< osg::ref_ptr<ActiveUniform> > ActiveUniformList;
|
||||
|
||||
|
||||
protected:
|
||||
@ -405,9 +395,11 @@ class SG_EXPORT Program : public osg::StateAttribute
|
||||
void getInfoLog( std::string& infoLog ) const;
|
||||
|
||||
void useProgram() const;
|
||||
|
||||
void applyUniforms( osg::State& state ) const;
|
||||
|
||||
GLint getUniformLocation( const char* name ) const;
|
||||
GLint getAttribLocation( const char* name ) const;
|
||||
|
||||
protected: /*methods*/
|
||||
~PerContextProgram();
|
||||
|
||||
@ -438,11 +430,13 @@ class SG_EXPORT Program : public osg::StateAttribute
|
||||
PerContextProgram* getPCP(unsigned int contextID) const;
|
||||
|
||||
protected: /*data*/
|
||||
bool _avoidRedundantUniformSetting;
|
||||
std::string _name;
|
||||
mutable osg::buffered_value< osg::ref_ptr<PerContextProgram> > _pcpList;
|
||||
AttribBindingList _attribBindingList;
|
||||
|
||||
typedef std::vector< ref_ptr<Shader> > ShaderList;
|
||||
ShaderList _shaderList;
|
||||
mutable osg::buffered_value< osg::ref_ptr<PerContextProgram> > _pcpList;
|
||||
|
||||
|
||||
private:
|
||||
Program& operator=(const Program&); // disallowed
|
||||
|
@ -12,16 +12,9 @@
|
||||
*/
|
||||
|
||||
/* file: include/osg/Shader
|
||||
* author: Mike Weiblen 2005-03-23
|
||||
* author: Mike Weiblen 2005-03-30
|
||||
*/
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#ifndef OSG_SHADER
|
||||
#define OSG_SHADER 1
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <osg/Export>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Uniform>
|
||||
|
||||
#include <osg/FrameStamp>
|
||||
#include <osg/DisplaySettings>
|
||||
@ -25,6 +26,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#ifndef GL_TEXTURE0
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
@ -710,6 +712,13 @@ class SG_EXPORT State : public Referenced
|
||||
bool checkGLErrors(StateAttribute::GLMode mode) const;
|
||||
bool checkGLErrors(const StateAttribute* attribute) const;
|
||||
|
||||
typedef std::map< std::string,ref_ptr<Uniform> > UniformMap;
|
||||
const Uniform* findUniform( const std::string& name )
|
||||
{
|
||||
UniformMap::const_iterator itr = _uniformMap.find( name );
|
||||
return (itr != _uniformMap.end()) ? itr->second.get() : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~State();
|
||||
@ -840,6 +849,8 @@ class SG_EXPORT State : public Referenced
|
||||
TextureModeMapList _textureModeMapList;
|
||||
TextureAttributeMapList _textureAttributeMapList;
|
||||
|
||||
UniformMap _uniformMap;
|
||||
|
||||
StateSetStack _drawStateStack;
|
||||
|
||||
struct EnabledArrayPair
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
/* file: include/osg/Uniform
|
||||
* author: Mike Weiblen 2005-03-23
|
||||
* author: Mike Weiblen 2005-03-29
|
||||
*/
|
||||
|
||||
// NOTICE: This code is CLOSED during construction and/or renovation!
|
||||
@ -33,8 +33,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef GL_VERSION_2_0
|
||||
#ifndef GL_VERSION_2_0 //[
|
||||
#define GL_VERSION_2_0 1
|
||||
typedef char GLchar;
|
||||
#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
|
||||
@ -119,116 +120,60 @@
|
||||
#define GL_STENCIL_BACK_REF 0x8CA3
|
||||
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
|
||||
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
|
||||
|
||||
typedef char GLchar;
|
||||
|
||||
#endif
|
||||
#endif //]
|
||||
|
||||
namespace osg {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/** Uniform encapsulates glUniform values */
|
||||
|
||||
class GL2Extensions;
|
||||
|
||||
class SG_EXPORT Uniform : public Object
|
||||
{
|
||||
public:
|
||||
class Value
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
FLOAT = GL_FLOAT,
|
||||
FLOAT_VEC2 = GL_FLOAT_VEC2,
|
||||
FLOAT_VEC3 = GL_FLOAT_VEC3,
|
||||
FLOAT_VEC4 = GL_FLOAT_VEC4,
|
||||
INT = GL_INT,
|
||||
INT_VEC2 = GL_INT_VEC2,
|
||||
INT_VEC3 = GL_INT_VEC3,
|
||||
INT_VEC4 = GL_INT_VEC4,
|
||||
BOOL = GL_BOOL,
|
||||
BOOL_VEC2 = GL_BOOL_VEC2,
|
||||
BOOL_VEC3 = GL_BOOL_VEC3,
|
||||
BOOL_VEC4 = GL_BOOL_VEC4,
|
||||
FLOAT_MAT2 = GL_FLOAT_MAT2,
|
||||
FLOAT_MAT3 = GL_FLOAT_MAT3,
|
||||
FLOAT_MAT4 = GL_FLOAT_MAT4,
|
||||
SAMPLER_1D = GL_SAMPLER_1D,
|
||||
SAMPLER_2D = GL_SAMPLER_2D,
|
||||
SAMPLER_3D = GL_SAMPLER_3D,
|
||||
SAMPLER_CUBE = GL_SAMPLER_CUBE,
|
||||
SAMPLER_1D_SHADOW = GL_SAMPLER_1D_SHADOW,
|
||||
SAMPLER_2D_SHADOW = GL_SAMPLER_2D_SHADOW,
|
||||
UNDEFINED = -1,
|
||||
};
|
||||
|
||||
Value( const char* name, Type type );
|
||||
Value( const Value& rhs );
|
||||
|
||||
|
||||
/** Get the name of glUniform. */
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
/** Get the type of glUniform as enum. */
|
||||
const Type getType() const { return _type; }
|
||||
|
||||
/** Return the name of a type as string. */
|
||||
static const char* getTypename(Type t);
|
||||
|
||||
/** Does this Value contain real data? */
|
||||
bool isValid() const { return _isValid; }
|
||||
|
||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
|
||||
int compare(const Value& rhs) const;
|
||||
|
||||
bool isCompatibleType( Type t ) const;
|
||||
|
||||
/** assignment */
|
||||
void set( float f );
|
||||
void set( const osg::Vec2& v2 );
|
||||
void set( const osg::Vec3& v3 );
|
||||
void set( const osg::Vec4& v4 );
|
||||
//TODO void set( const osg::Matrix2& m2 );
|
||||
//TODO void set( const osg::Matrix3& m3 );
|
||||
void set( const osg::Matrix& m4 );
|
||||
void set( int i );
|
||||
void set( int i0, int i1 );
|
||||
void set( int i0, int i1, int i2 );
|
||||
void set( int i0, int i1, int i2, int i3 );
|
||||
void set( bool b );
|
||||
void set( bool b0, bool b1 );
|
||||
void set( bool b0, bool b1, bool b2 );
|
||||
void set( bool b0, bool b1, bool b2, bool b3 );
|
||||
|
||||
|
||||
protected:
|
||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
|
||||
int compareData(const Value& rhs) const;
|
||||
void copyData(const Value& rhs);
|
||||
|
||||
protected:
|
||||
const std::string _name;
|
||||
const Type _type;
|
||||
bool _isValid; // is _data valid?
|
||||
union {
|
||||
GLfloat f1; // float
|
||||
GLfloat f2[2]; // vec2
|
||||
GLfloat f3[3]; // vec3
|
||||
GLfloat f4[4]; // vec4, mat2
|
||||
GLfloat f9[9]; // mat3
|
||||
GLfloat f16[16]; // mat4
|
||||
GLint i1; // int, bool, sampler*
|
||||
GLint i2[2]; // ivec2, bvec2
|
||||
GLint i3[3]; // ivec3, bvec3
|
||||
GLint i4[4]; // ivec4, bvec4
|
||||
} _data;
|
||||
|
||||
private:
|
||||
Value(); // disallowed
|
||||
enum Type {
|
||||
FLOAT = GL_FLOAT,
|
||||
FLOAT_VEC2 = GL_FLOAT_VEC2,
|
||||
FLOAT_VEC3 = GL_FLOAT_VEC3,
|
||||
FLOAT_VEC4 = GL_FLOAT_VEC4,
|
||||
INT = GL_INT,
|
||||
INT_VEC2 = GL_INT_VEC2,
|
||||
INT_VEC3 = GL_INT_VEC3,
|
||||
INT_VEC4 = GL_INT_VEC4,
|
||||
BOOL = GL_BOOL,
|
||||
BOOL_VEC2 = GL_BOOL_VEC2,
|
||||
BOOL_VEC3 = GL_BOOL_VEC3,
|
||||
BOOL_VEC4 = GL_BOOL_VEC4,
|
||||
FLOAT_MAT2 = GL_FLOAT_MAT2,
|
||||
FLOAT_MAT3 = GL_FLOAT_MAT3,
|
||||
FLOAT_MAT4 = GL_FLOAT_MAT4,
|
||||
SAMPLER_1D = GL_SAMPLER_1D,
|
||||
SAMPLER_2D = GL_SAMPLER_2D,
|
||||
SAMPLER_3D = GL_SAMPLER_3D,
|
||||
SAMPLER_CUBE = GL_SAMPLER_CUBE,
|
||||
SAMPLER_1D_SHADOW = GL_SAMPLER_1D_SHADOW,
|
||||
SAMPLER_2D_SHADOW = GL_SAMPLER_2D_SHADOW,
|
||||
UNDEFINED = -1,
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
Uniform();
|
||||
Uniform( const char* name, Value::Type type );
|
||||
Uniform( const char* name, Type type );
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
|
||||
Uniform(const Uniform& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(osg, Uniform);
|
||||
|
||||
|
||||
/** Get the name of glUniform. */
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
/** Get the type of glUniform as enum. */
|
||||
const Type getType() const { return _type; }
|
||||
|
||||
/** Return the name of a type as string. */
|
||||
static const char* getTypename( Type t );
|
||||
|
||||
/** convenient construction w/ assignment */
|
||||
explicit Uniform( const char* name, float f );
|
||||
@ -247,26 +192,15 @@ class SG_EXPORT Uniform : public Object
|
||||
Uniform( const char* name, bool b0, bool b1, bool b2 );
|
||||
Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 );
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
|
||||
Uniform(const Uniform& gu,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
|
||||
virtual int compare(const Uniform& rhs) const;
|
||||
virtual int compareData(const Uniform& rhs) const;
|
||||
|
||||
META_Object(osg, Uniform);
|
||||
virtual bool operator < (const Uniform& rhs) const { return (compare(rhs) == -1); }
|
||||
|
||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
|
||||
virtual int compare(const Uniform& rhs) const
|
||||
{
|
||||
return _value.compare( rhs._value );
|
||||
}
|
||||
void copyData( const Uniform& rhs );
|
||||
|
||||
bool operator < (const Uniform& rhs) const
|
||||
{
|
||||
if (_value.getName()<rhs._value.getName()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& getName() const { return _value.getName(); }
|
||||
|
||||
/** assignment */
|
||||
/** value assignment */
|
||||
bool set( float f );
|
||||
bool set( int i );
|
||||
bool set( bool b );
|
||||
@ -283,15 +217,49 @@ class SG_EXPORT Uniform : public Object
|
||||
bool set( bool b0, bool b1, bool b2 );
|
||||
bool set( bool b0, bool b1, bool b2, bool b3 );
|
||||
|
||||
/** value query */
|
||||
bool get( float& f ) const;
|
||||
bool get( int& i ) const;
|
||||
bool get( bool& b ) const;
|
||||
bool get( osg::Vec2& v2 ) const;
|
||||
bool get( osg::Vec3& v3 ) const;
|
||||
bool get( osg::Vec4& v4 ) const;
|
||||
//TODO bool get( osg::Matrix2& m2 ) const;
|
||||
//TODO bool get( osg::Matrix3& m3 ) const;
|
||||
bool get( osg::Matrix& m4 ) const;
|
||||
bool get( int& i0, int& i1 ) const;
|
||||
bool get( int& i0, int& i1, int& i2 ) const;
|
||||
bool get( int& i0, int& i1, int& i2, int& i3 ) const;
|
||||
bool get( bool& b0, bool& b1 ) const;
|
||||
bool get( bool& b0, bool& b1, bool& b2 ) const;
|
||||
bool get( bool& b0, bool& b1, bool& b2, bool& b3 ) const;
|
||||
|
||||
|
||||
protected:
|
||||
virtual ~Uniform() {}
|
||||
|
||||
bool isCompatibleType( Value::Type t ) const;
|
||||
bool isCompatibleType( Type t ) const;
|
||||
static Type repType( Type t );
|
||||
|
||||
|
||||
protected:
|
||||
Value _value;
|
||||
const std::string _name;
|
||||
const Type _type;
|
||||
union {
|
||||
GLfloat f1; // float
|
||||
GLfloat f2[2]; // vec2
|
||||
GLfloat f3[3]; // vec3
|
||||
GLfloat f4[4]; // vec4, mat2
|
||||
GLfloat f9[9]; // mat3
|
||||
GLfloat f16[16]; // mat4
|
||||
GLint i1; // int, bool, sampler*
|
||||
GLint i2[2]; // ivec2, bvec2
|
||||
GLint i3[3]; // ivec3, bvec3
|
||||
GLint i4[4]; // ivec4, bvec4
|
||||
} _data;
|
||||
|
||||
private:
|
||||
Uniform(); // disallowed
|
||||
Uniform& operator=(const Uniform&); // disallowed
|
||||
};
|
||||
|
||||
|
@ -13,16 +13,9 @@
|
||||
*/
|
||||
|
||||
/* file: src/osg/Program.cpp
|
||||
* author: Mike Weiblen 2005-03-23
|
||||
* author: Mike Weiblen 2005-03-30
|
||||
*/
|
||||
|
||||
// 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>
|
||||
|
||||
@ -35,12 +28,14 @@
|
||||
#include <osg/Shader>
|
||||
#include <osg/Uniform>
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/GLU>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Extension function pointers for OpenGL v2.0
|
||||
|
||||
@ -286,16 +281,12 @@ void GL2Extensions::setupGL2Extensions()
|
||||
if( isGlslSupported() )
|
||||
{
|
||||
// If glGetString raises an error, assume initial release "1.00"
|
||||
glGetError(); // reset error flag
|
||||
while(glGetError() != GL_NO_ERROR) {} // reset error flag
|
||||
const char* langVerStr = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
const GLenum errorNum = glGetError();
|
||||
if( (errorNum != GL_NO_ERROR) || (langVerStr == 0) )
|
||||
{
|
||||
langVerStr = "1.00 (default)";
|
||||
}
|
||||
osg::notify(osg::INFO) << "GL_SHADING_LANGUAGE_VERSION: \"" << langVerStr << "\"" << std::endl;
|
||||
|
||||
_glslLanguageVersion = atof( langVerStr );
|
||||
if( (glGetError() == GL_NO_ERROR) && langVerStr )
|
||||
_glslLanguageVersion = atof( langVerStr );
|
||||
else
|
||||
_glslLanguageVersion = 1.0f;
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)
|
||||
@ -1787,14 +1778,14 @@ void GL2Extensions::glVertexAttribPointer(GLuint index, GLint size, GLenum type,
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// convenience methods
|
||||
// C++-friendly convenience methods
|
||||
|
||||
GLuint GL2Extensions::getCurrentProgram() const
|
||||
{
|
||||
if( _glVersion >= 2.0f )
|
||||
{
|
||||
// GLSL as GL v2.0 core functionality
|
||||
GLint result;
|
||||
GLint result = 0;
|
||||
glGetIntegerv( GL_CURRENT_PROGRAM, &result );
|
||||
return static_cast<GLuint>(result);
|
||||
}
|
||||
@ -1817,8 +1808,8 @@ GLuint GL2Extensions::getCurrentProgram() const
|
||||
|
||||
bool GL2Extensions::getProgramInfoLog( GLuint program, std::string& result ) const
|
||||
{
|
||||
GLint bufLen = 0; // length of buffer to allocate
|
||||
GLint strLen = 0; // strlen GL actually wrote to buffer
|
||||
GLsizei bufLen = 0; // length of buffer to allocate
|
||||
GLsizei strLen = 0; // strlen GL actually wrote to buffer
|
||||
|
||||
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &bufLen );
|
||||
if( bufLen > 1 )
|
||||
@ -1834,8 +1825,8 @@ bool GL2Extensions::getProgramInfoLog( GLuint program, std::string& result ) con
|
||||
|
||||
bool GL2Extensions::getShaderInfoLog( GLuint shader, std::string& result ) const
|
||||
{
|
||||
GLint bufLen = 0; // length of buffer to allocate
|
||||
GLint strLen = 0; // strlen GL actually wrote to buffer
|
||||
GLsizei bufLen = 0; // length of buffer to allocate
|
||||
GLsizei strLen = 0; // strlen GL actually wrote to buffer
|
||||
|
||||
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &bufLen );
|
||||
if( bufLen > 1 )
|
||||
@ -1848,6 +1839,27 @@ bool GL2Extensions::getShaderInfoLog( GLuint shader, std::string& result ) const
|
||||
return (strLen > 0);
|
||||
}
|
||||
|
||||
|
||||
bool GL2Extensions::getAttribLocation( const char* attribName, 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;
|
||||
|
||||
// is there such a named attribute?
|
||||
GLint loc = glGetAttribLocation( program, attribName );
|
||||
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.
|
||||
@ -1909,7 +1921,6 @@ void Program::flushDeletedGlPrograms(unsigned int contextID,double /*currentTime
|
||||
|
||||
Program::Program()
|
||||
{
|
||||
_avoidRedundantUniformSetting = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1952,9 +1963,6 @@ int Program::compare(const osg::StateAttribute& sa) const
|
||||
if (result!=0) return result;
|
||||
}
|
||||
|
||||
// TODO should Program comparison depend on the values of
|
||||
// its uniforms? I'd assert not.
|
||||
|
||||
return 0; // passed all the above comparison macro's, must be equal.
|
||||
}
|
||||
|
||||
@ -2024,7 +2032,7 @@ bool Program::removeShader( Shader* shader )
|
||||
|
||||
void Program::bindAttribLocation( GLuint index, const char* name )
|
||||
{
|
||||
// TODO add to binding list
|
||||
_attribBindingList[name] = index;
|
||||
dirtyProgram();
|
||||
}
|
||||
|
||||
@ -2091,11 +2099,64 @@ void Program::getGlProgramInfoLog(unsigned int contextID, std::string& log) cons
|
||||
// osg::Program::ActiveUniform
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Program::ActiveUniform::ActiveUniform( const GLchar* name, GLenum type ) :
|
||||
_value( name, static_cast< Uniform::Value::Type >(type) )
|
||||
Program::ActiveUniform::ActiveUniform( const char* name, GLenum type, GLint loc ) :
|
||||
Uniform(name, static_cast<Type>(type)), _location(loc)
|
||||
{
|
||||
}
|
||||
|
||||
void Program::ActiveUniform::applyData( const GL2Extensions* ext, GLuint prog )
|
||||
{
|
||||
switch( repType(getType()) )
|
||||
{
|
||||
case FLOAT:
|
||||
ext->glUniform1f( _location, _data.f1 );
|
||||
break;
|
||||
|
||||
case FLOAT_VEC2:
|
||||
ext->glUniform2fv( _location, 1, _data.f2 );
|
||||
break;
|
||||
|
||||
case FLOAT_VEC3:
|
||||
ext->glUniform3fv( _location, 1, _data.f3 );
|
||||
break;
|
||||
|
||||
case FLOAT_VEC4:
|
||||
ext->glUniform4fv( _location, 1, _data.f4 );
|
||||
break;
|
||||
|
||||
case FLOAT_MAT2:
|
||||
ext->glUniformMatrix2fv( _location, 1, GL_FALSE, _data.f4 );
|
||||
break;
|
||||
|
||||
case FLOAT_MAT3:
|
||||
ext->glUniformMatrix3fv( _location, 1, GL_FALSE, _data.f9 );
|
||||
break;
|
||||
|
||||
case FLOAT_MAT4:
|
||||
ext->glUniformMatrix4fv( _location, 1, GL_FALSE, _data.f16 );
|
||||
break;
|
||||
|
||||
case INT:
|
||||
ext->glUniform1i( _location, _data.i1 );
|
||||
break;
|
||||
|
||||
case INT_VEC2:
|
||||
ext->glUniform2iv( _location, 1, _data.i2 );
|
||||
break;
|
||||
|
||||
case INT_VEC3:
|
||||
ext->glUniform3iv( _location, 1, _data.i3 );
|
||||
break;
|
||||
|
||||
case INT_VEC4:
|
||||
ext->glUniform4iv( _location, 1, _data.i4 );
|
||||
break;
|
||||
|
||||
default:
|
||||
osg::notify(osg::FATAL) << "how got here?" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// osg::Program::PerContextProgram
|
||||
@ -2130,15 +2191,20 @@ void Program::PerContextProgram::linkProgram()
|
||||
if( ! _needsLink ) return;
|
||||
_needsLink = false;
|
||||
|
||||
// TODO for( each itr in binding list )
|
||||
// {
|
||||
// _extensions->glBindAttribLocation( _glProgramHandle, index, name );
|
||||
// }
|
||||
_activeUniformList.clear();
|
||||
|
||||
GLint linked;
|
||||
// set any explicit vertex attribute bindings
|
||||
const AttribBindingList& bindlist = _program->getAttribBindingList();
|
||||
for( AttribBindingList::const_iterator itr = bindlist.begin();
|
||||
itr != bindlist.end(); ++itr )
|
||||
{
|
||||
_extensions->glBindAttribLocation( _glProgramHandle, itr->second, itr->first.c_str() );
|
||||
}
|
||||
|
||||
// link the glProgram
|
||||
GLint linked = GL_FALSE;
|
||||
_extensions->glLinkProgram( _glProgramHandle );
|
||||
_extensions->glGetProgramiv( _glProgramHandle, GL_LINK_STATUS, &linked );
|
||||
|
||||
_isLinked = (linked == GL_TRUE);
|
||||
if( ! _isLinked )
|
||||
{
|
||||
@ -2146,6 +2212,32 @@ void Program::PerContextProgram::linkProgram()
|
||||
std::string infoLog;
|
||||
getInfoLog( infoLog );
|
||||
osg::notify(osg::WARN) << "glLinkProgram FAILED:\n" << infoLog << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// build ActiveUniformList
|
||||
GLint numUniforms = 0;
|
||||
GLsizei maxLen = 0;
|
||||
_extensions->glGetProgramiv( _glProgramHandle, GL_ACTIVE_UNIFORMS, &numUniforms );
|
||||
_extensions->glGetProgramiv( _glProgramHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen );
|
||||
if( (numUniforms > 0) && (maxLen > 1) )
|
||||
{
|
||||
GLint size = 0;
|
||||
GLenum type = 0;
|
||||
GLchar* name = new GLchar[maxLen];
|
||||
|
||||
for( GLint i = 0; i < numUniforms; ++i )
|
||||
{
|
||||
_extensions->glGetActiveUniform( _glProgramHandle,
|
||||
i, maxLen, 0, &size, &type, name );
|
||||
GLint loc = getUniformLocation( name );
|
||||
|
||||
if( loc != -1 )
|
||||
{
|
||||
_activeUniformList.push_back( new ActiveUniform( name, type, loc ) );
|
||||
}
|
||||
}
|
||||
delete [] name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2159,23 +2251,36 @@ void Program::PerContextProgram::useProgram() const
|
||||
_extensions->glUseProgram( _glProgramHandle );
|
||||
}
|
||||
|
||||
|
||||
void Program::PerContextProgram::applyUniforms( osg::State& /*state*/ ) const
|
||||
GLint Program::PerContextProgram::getUniformLocation( const char* name ) const
|
||||
{
|
||||
bool uniformDoesNeedSetting = true;
|
||||
return _extensions->glGetUniformLocation( _glProgramHandle, name );
|
||||
}
|
||||
|
||||
if( _program->getAvoidRedundantUniformSetting() )
|
||||
{
|
||||
// TODO - calling glUniform*() can be expensive.
|
||||
// so this will query osg::Program state to determine if
|
||||
// the uniform already has the requested value, and if so,
|
||||
// will set uniformNeedsSetting=false to prevent redundant
|
||||
// re-setting of the uniform.
|
||||
}
|
||||
GLint Program::PerContextProgram::getAttribLocation( const char* name ) const
|
||||
{
|
||||
return _extensions->glGetAttribLocation( _glProgramHandle, name );
|
||||
}
|
||||
|
||||
if( uniformDoesNeedSetting )
|
||||
|
||||
void Program::PerContextProgram::applyUniforms( osg::State& state ) const
|
||||
{
|
||||
for( ActiveUniformList::const_iterator itr = _activeUniformList.begin();
|
||||
itr != _activeUniformList.end(); ++itr )
|
||||
{
|
||||
// TODO set the uniform value on the currently active glProgram.
|
||||
ActiveUniform* au = const_cast<ActiveUniform*>( itr->get() );
|
||||
|
||||
// use name of active uniform to find a value uniform
|
||||
const osg::Uniform* vu = state.findUniform( au->getName() );
|
||||
if( ! vu ) continue;
|
||||
|
||||
// skip if types are not identical
|
||||
if( au->getType() != vu->getType() ) continue;
|
||||
|
||||
// skip if values are already identical
|
||||
if( au->compareData( *vu ) == 0 ) continue;
|
||||
|
||||
au->copyData( *vu );
|
||||
au->applyData( _extensions.get(), _glProgramHandle );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,16 +13,9 @@
|
||||
*/
|
||||
|
||||
/* file: src/osg/Shader.cpp
|
||||
* author: Mike Weiblen 2005-03-23
|
||||
* author: Mike Weiblen 2005-03-30
|
||||
*/
|
||||
|
||||
// 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>
|
||||
|
||||
@ -290,7 +283,7 @@ void Shader::PerContextShader::compileShader()
|
||||
if( ! _needsCompile ) return;
|
||||
_needsCompile = false;
|
||||
|
||||
GLint compiled;
|
||||
GLint compiled = GL_FALSE;
|
||||
const char* sourceText = _shader->getShaderSource().c_str();
|
||||
_extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL );
|
||||
_extensions->glCompileShader( _glShaderHandle );
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
/* file: src/osg/Uniform.cpp
|
||||
* author: Mike Weiblen 2005-03-23
|
||||
* author: Mike Weiblen 2005-03-30
|
||||
*/
|
||||
|
||||
// NOTICE: This code is CLOSED during construction and/or renovation!
|
||||
@ -23,27 +23,241 @@
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/Uniform>
|
||||
#include <osg/Program>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// osg::Uniform::Value
|
||||
// osg::Uniform
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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)
|
||||
Uniform::Uniform() :
|
||||
_name(""), _type(UNDEFINED)
|
||||
{
|
||||
if( rhs._isValid ) copyData(rhs);
|
||||
// do not use this constructor in application code.
|
||||
// it exists only because META_Object requires a trivial
|
||||
// default constructor, but that is concept is meaningless for Uniform.
|
||||
osg::notify(osg::FATAL) << "how got here?" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
const char* Uniform::Value::getTypename( Type t )
|
||||
Uniform::Uniform( const char* name, Type type ) :
|
||||
_name(name), _type(type)
|
||||
{
|
||||
switch( _type )
|
||||
{
|
||||
case FLOAT: set( 0.0f ); break;
|
||||
case FLOAT_VEC2: set( osg::Vec2() ); break;
|
||||
case FLOAT_VEC3: set( osg::Vec3() ); break;
|
||||
case FLOAT_VEC4: set( osg::Vec4() ); break;
|
||||
case INT: set( 0 ); break;
|
||||
case INT_VEC2: set( 0, 0 ); break;
|
||||
case INT_VEC3: set( 0, 0, 0 ); break;
|
||||
case INT_VEC4: set( 0, 0, 0, 0 ); break;
|
||||
case BOOL: set( false ); break;
|
||||
case BOOL_VEC2: set( false, false ); break;
|
||||
case BOOL_VEC3: set( false, false, false ); break;
|
||||
case BOOL_VEC4: set( false, false, false, false ); break;
|
||||
// TODO case FLOAT_MAT2:
|
||||
// TODO case FLOAT_MAT3:
|
||||
case FLOAT_MAT4: set( osg::Matrix() ); break;
|
||||
case SAMPLER_1D: set( 0 ); break;
|
||||
case SAMPLER_2D: set( 0 ); break;
|
||||
case SAMPLER_3D: set( 0 ); break;
|
||||
case SAMPLER_CUBE: set( 0 ); break;
|
||||
case SAMPLER_1D_SHADOW: set( 0 ); break;
|
||||
case SAMPLER_2D_SHADOW: set( 0 ); break;
|
||||
default:
|
||||
osg::notify(osg::WARN) << "unhandled Uniform type" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Uniform::Uniform( const Uniform& rhs, const CopyOp& copyop ) :
|
||||
Object(rhs,copyop), _name(rhs._name), _type(rhs._type)
|
||||
{
|
||||
copyData( rhs );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int Uniform::compare(const Uniform& rhs) const
|
||||
{
|
||||
if( this == &rhs ) return 0;
|
||||
|
||||
if( _type < rhs._type ) return -1;
|
||||
if( rhs._type < _type ) return 1;
|
||||
|
||||
if( _name < rhs._name ) return -1;
|
||||
if( rhs._name < _name ) return 1;
|
||||
|
||||
return compareData( rhs );
|
||||
}
|
||||
|
||||
int Uniform::compareData(const Uniform& rhs) const
|
||||
{
|
||||
// caller must ensure that _type==rhs._type
|
||||
|
||||
switch( repType(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:
|
||||
if( _data.i1 < rhs._data.i1 ) return -1;
|
||||
if( _data.i1 > rhs._data.i1 ) return 1;
|
||||
return 0;
|
||||
|
||||
case INT_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:
|
||||
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:
|
||||
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::FATAL) << "how got here?" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Uniform::copyData(const Uniform& rhs)
|
||||
{
|
||||
// caller must ensure that _type==rhs._type
|
||||
|
||||
int i;
|
||||
switch( repType(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(i=0;i<9;++i) _data.f9[i]=rhs._data.f9[i];
|
||||
break;
|
||||
|
||||
case FLOAT_MAT4:
|
||||
for(i=0;i<16;++i) _data.f16[i]=rhs._data.f16[i];
|
||||
break;
|
||||
|
||||
case INT:
|
||||
_data.i1 = rhs._data.i1;
|
||||
break;
|
||||
|
||||
case INT_VEC2:
|
||||
_data.i2[0] = rhs._data.i2[0];
|
||||
_data.i2[1] = rhs._data.i2[1];
|
||||
break;
|
||||
|
||||
case INT_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:
|
||||
_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::FATAL) << "how got here?" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Uniform::isCompatibleType( Type t ) const
|
||||
{
|
||||
if( t == getType() ) return true;
|
||||
if( repType(t) == repType(getType()) ) return true;
|
||||
|
||||
osg::notify(osg::WARN)
|
||||
<< "Cannot assign between Uniform types " << getTypename(t)
|
||||
<< " and " << getTypename(getType()) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// static methods
|
||||
|
||||
const char* Uniform::getTypename( Type t )
|
||||
{
|
||||
switch( t )
|
||||
{
|
||||
@ -72,150 +286,10 @@ const char* Uniform::Value::getTypename( Type t )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Uniform::Value::compare(const Value& rhs) const
|
||||
Uniform::Type Uniform::repType( Type t )
|
||||
{
|
||||
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)
|
||||
switch( t )
|
||||
{
|
||||
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:
|
||||
@ -223,238 +297,142 @@ int Uniform::Value::compareData(const Value& rhs) const
|
||||
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;
|
||||
}
|
||||
return INT;
|
||||
|
||||
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;
|
||||
}
|
||||
return INT_VEC2;
|
||||
|
||||
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;
|
||||
}
|
||||
return INT_VEC3;
|
||||
|
||||
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;
|
||||
}
|
||||
return INT_VEC4;
|
||||
|
||||
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;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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 Uniform& gu, const CopyOp& copyop ) :
|
||||
Object(gu,copyop),
|
||||
_value( gu._value )
|
||||
{
|
||||
}
|
||||
|
||||
// value constructors
|
||||
|
||||
Uniform::Uniform( const char* name, float f ) :
|
||||
_value( name, Value::FLOAT )
|
||||
_name(name), _type(FLOAT)
|
||||
{
|
||||
_value.set( f );
|
||||
set( f );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Vec2& v2 ) :
|
||||
_value( name, Value::FLOAT_VEC2 )
|
||||
_name(name), _type(FLOAT_VEC2)
|
||||
{
|
||||
_value.set( v2 );
|
||||
set( v2 );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Vec3& v3 ) :
|
||||
_value( name, Value::FLOAT_VEC3 )
|
||||
_name(name), _type(FLOAT_VEC3)
|
||||
{
|
||||
_value.set( v3 );
|
||||
set( v3 );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Vec4& v4 ) :
|
||||
_value( name, Value::FLOAT_VEC4 )
|
||||
_name(name), _type(FLOAT_VEC4)
|
||||
{
|
||||
_value.set( v4 );
|
||||
set( v4 );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, const osg::Matrix2& m2 )
|
||||
//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::Matrix3& m3 )
|
||||
|
||||
Uniform::Uniform( const char* name, const osg::Matrix& m4 ) :
|
||||
_value( name, Value::FLOAT_MAT4 )
|
||||
_name(name), _type(FLOAT_MAT4)
|
||||
{
|
||||
_value.set( m4 );
|
||||
set( m4 );
|
||||
}
|
||||
|
||||
Uniform::Uniform( const char* name, int i ) :
|
||||
_value( name, Value::INT )
|
||||
_name(name), _type(INT)
|
||||
{
|
||||
_value.set( i );
|
||||
set( i );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, int i0, int i1 )
|
||||
Uniform::Uniform( const char* name, int i0, int i1 ) :
|
||||
_name(name), _type(INT_VEC2)
|
||||
{
|
||||
set( i0, i1 );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, int i0, int i1, int i2 )
|
||||
Uniform::Uniform( const char* name, int i0, int i1, int i2 ) :
|
||||
_name(name), _type(INT_VEC3)
|
||||
{
|
||||
set( i0, i1, i2 );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, int i0, int i1, int i2, int i3 )
|
||||
Uniform::Uniform( const char* name, int i0, int i1, int i2, int i3 ) :
|
||||
_name(name), _type(INT_VEC4)
|
||||
{
|
||||
set( i0, i1, i2, i3 );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b )
|
||||
Uniform::Uniform( const char* name, bool b ) :
|
||||
_name(name), _type(BOOL)
|
||||
{
|
||||
set( b );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b0, bool b1 )
|
||||
Uniform::Uniform( const char* name, bool b0, bool b1 ) :
|
||||
_name(name), _type(BOOL_VEC2)
|
||||
{
|
||||
set( b0, b1 );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b0, bool b1, bool b2 )
|
||||
Uniform::Uniform( const char* name, bool b0, bool b1, bool b2 ) :
|
||||
_name(name), _type(BOOL_VEC3)
|
||||
{
|
||||
set( b0, b1, b2 );
|
||||
}
|
||||
|
||||
//TODO Uniform::Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 )
|
||||
Uniform::Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 ) :
|
||||
_name(name), _type(BOOL_VEC4)
|
||||
{
|
||||
set( b0, b1, b2, b3 );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// value assignment
|
||||
|
||||
bool Uniform::set( float f )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT ) ) return false;
|
||||
_value.set( f );
|
||||
if( ! isCompatibleType(FLOAT) ) return false;
|
||||
_data.f1 = f;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( const osg::Vec2& v2 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_VEC2 ) ) return false;
|
||||
_value.set( v2 );
|
||||
if( ! isCompatibleType(FLOAT_VEC2) ) return false;
|
||||
_data.f2[0] = v2.x();
|
||||
_data.f2[1] = v2.y();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( const osg::Vec3& v3 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_VEC3 ) ) return false;
|
||||
_value.set( v3 );
|
||||
if( ! isCompatibleType(FLOAT_VEC3) ) return false;
|
||||
_data.f3[0] = v3.x();
|
||||
_data.f3[1] = v3.y();
|
||||
_data.f3[2] = v3.z();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( const osg::Vec4& v4 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_VEC4 ) ) return false;
|
||||
_value.set( v4 );
|
||||
if( ! isCompatibleType(FLOAT_VEC4) ) return false;
|
||||
_data.f4[0] = v4.x();
|
||||
_data.f4[1] = v4.y();
|
||||
_data.f4[2] = v4.z();
|
||||
_data.f4[3] = v4.w();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -464,43 +442,207 @@ bool Uniform::set( const osg::Vec4& v4 )
|
||||
|
||||
bool Uniform::set( const osg::Matrix& m4 )
|
||||
{
|
||||
if( ! isCompatibleType( Value::FLOAT_MAT4 ) ) return false;
|
||||
_value.set( m4 );
|
||||
if( ! isCompatibleType(FLOAT_MAT4) ) return false;
|
||||
int n = 0;
|
||||
for(int row=0; row<4; ++row)
|
||||
{
|
||||
for(int col=0; col<4; ++col)
|
||||
{
|
||||
_data.f16[n++] = m4(row,col);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( int i )
|
||||
{
|
||||
if( ! isCompatibleType( Value::INT ) ) return false;
|
||||
_value.set( i );
|
||||
if( ! isCompatibleType(INT) ) return false;
|
||||
_data.i1 = 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
|
||||
bool Uniform::set( int i0, int i1 )
|
||||
{
|
||||
if( t == _value.getType() ) return true;
|
||||
if( ! isCompatibleType(INT_VEC2) ) return false;
|
||||
_data.i2[0] = i0;
|
||||
_data.i2[1] = i1;
|
||||
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;
|
||||
bool Uniform::set( int i0, int i1, int i2 )
|
||||
{
|
||||
if( ! isCompatibleType(INT_VEC3) ) return false;
|
||||
_data.i3[0] = i0;
|
||||
_data.i3[1] = i1;
|
||||
_data.i3[2] = i2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( int i0, int i1, int i2, int i3 )
|
||||
{
|
||||
if( ! isCompatibleType(INT_VEC4) ) return false;
|
||||
_data.i4[0] = i0;
|
||||
_data.i4[1] = i1;
|
||||
_data.i4[2] = i2;
|
||||
_data.i4[3] = i3;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( bool b )
|
||||
{
|
||||
if( ! isCompatibleType(BOOL) ) return false;
|
||||
_data.i1 = b;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( bool b0, bool b1 )
|
||||
{
|
||||
if( ! isCompatibleType(BOOL_VEC2) ) return false;
|
||||
_data.i2[0] = b0;
|
||||
_data.i2[1] = b1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( bool b0, bool b1, bool b2 )
|
||||
{
|
||||
if( ! isCompatibleType(BOOL_VEC3) ) return false;
|
||||
_data.i3[0] = b0;
|
||||
_data.i3[1] = b1;
|
||||
_data.i3[2] = b2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::set( bool b0, bool b1, bool b2, bool b3 )
|
||||
{
|
||||
if( ! isCompatibleType(BOOL_VEC4) ) return false;
|
||||
_data.i4[0] = b0;
|
||||
_data.i4[1] = b1;
|
||||
_data.i4[2] = b2;
|
||||
_data.i4[3] = b3;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// value query
|
||||
|
||||
bool Uniform::get( float& f ) const
|
||||
{
|
||||
if( ! isCompatibleType(FLOAT) ) return false;
|
||||
f = _data.f1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( osg::Vec2& v2 ) const
|
||||
{
|
||||
if( ! isCompatibleType(FLOAT_VEC2) ) return false;
|
||||
v2.x() = _data.f2[0];
|
||||
v2.y() = _data.f2[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( osg::Vec3& v3 ) const
|
||||
{
|
||||
if( ! isCompatibleType(FLOAT_VEC3) ) return false;
|
||||
v3.x() = _data.f3[0];
|
||||
v3.y() = _data.f3[1];
|
||||
v3.z() = _data.f3[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( osg::Vec4& v4 ) const
|
||||
{
|
||||
if( ! isCompatibleType(FLOAT_VEC4) ) return false;
|
||||
v4.x() = _data.f4[0];
|
||||
v4.y() = _data.f4[1];
|
||||
v4.z() = _data.f4[2];
|
||||
v4.w() = _data.f4[3];
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO bool Uniform::get( osg::Matrix2& m2 ) const
|
||||
|
||||
//TODO bool Uniform::get( osg::Matrix3& m3 ) const
|
||||
|
||||
bool Uniform::get( osg::Matrix& m4 ) const
|
||||
{
|
||||
if( ! isCompatibleType(FLOAT_MAT4) ) return false;
|
||||
int n = 0;
|
||||
for(int row=0; row<4; ++row)
|
||||
{
|
||||
for(int col=0; col<4; ++col)
|
||||
{
|
||||
m4(row,col) = _data.f16[n++];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( int& i ) const
|
||||
{
|
||||
if( ! isCompatibleType(INT) ) return false;
|
||||
i = _data.i1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( int& i0, int& i1 ) const
|
||||
{
|
||||
if( ! isCompatibleType(INT_VEC2) ) return false;
|
||||
i0 = _data.i2[0];
|
||||
i1 = _data.i2[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( int& i0, int& i1, int& i2 ) const
|
||||
{
|
||||
if( ! isCompatibleType(INT_VEC3) ) return false;
|
||||
i0 = _data.i3[0];
|
||||
i1 = _data.i3[1];
|
||||
i2 = _data.i3[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( int& i0, int& i1, int& i2, int& i3 ) const
|
||||
{
|
||||
if( ! isCompatibleType(INT_VEC4) ) return false;
|
||||
i0 = _data.i4[0];
|
||||
i1 = _data.i4[1];
|
||||
i2 = _data.i4[2];
|
||||
i3 = _data.i4[3];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( bool& b ) const
|
||||
{
|
||||
if( ! isCompatibleType(BOOL) ) return false;
|
||||
b = (_data.i1 != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( bool& b0, bool& b1 ) const
|
||||
{
|
||||
if( ! isCompatibleType(BOOL_VEC2) ) return false;
|
||||
b0 = (_data.i2[0] != 0);
|
||||
b1 = (_data.i2[1] != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( bool& b0, bool& b1, bool& b2 ) const
|
||||
{
|
||||
if( ! isCompatibleType(BOOL_VEC3) ) return false;
|
||||
b0 = (_data.i3[0] != 0);
|
||||
b1 = (_data.i3[1] != 0);
|
||||
b2 = (_data.i3[2] != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uniform::get( bool& b0, bool& b1, bool& b2, bool& b3 ) const
|
||||
{
|
||||
if( ! isCompatibleType(BOOL_VEC4) ) return false;
|
||||
b0 = (_data.i4[0] != 0);
|
||||
b1 = (_data.i4[1] != 0);
|
||||
b2 = (_data.i4[2] != 0);
|
||||
b3 = (_data.i4[3] != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*EOF*/
|
||||
|
Loading…
Reference in New Issue
Block a user