From 84e8338be11795b90d1409489ebb274fc9cc51da Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 7 Apr 2005 20:23:58 +0000 Subject: [PATCH] From Mike Weiblen, "adds sourcefiles for beginnings of .osg fileformat i/o support > - enhancemens to core GLSL classes to support file i/o" --- VisualStudio/osgPlugins/osg/dot_osg.dsp | 12 ++++ include/osg/Program | 7 +- include/osg/Shader | 15 ++-- include/osg/Uniform | 12 ++-- src/osg/Program.cpp | 6 +- src/osg/Shader.cpp | 30 ++++++-- src/osg/Uniform.cpp | 55 ++++++++++++-- src/osgPlugins/osg/GNUmakefile | 23 +++--- src/osgPlugins/osg/Program.cpp | 89 +++++++++++++++++++++++ src/osgPlugins/osg/Shader.cpp | 95 +++++++++++++++++++++++++ src/osgPlugins/osg/Uniform.cpp | 63 ++++++++++++++++ 11 files changed, 373 insertions(+), 34 deletions(-) create mode 100644 src/osgPlugins/osg/Program.cpp create mode 100644 src/osgPlugins/osg/Shader.cpp create mode 100644 src/osgPlugins/osg/Uniform.cpp diff --git a/VisualStudio/osgPlugins/osg/dot_osg.dsp b/VisualStudio/osgPlugins/osg/dot_osg.dsp index 52728d9ba..fb2b7a6f5 100755 --- a/VisualStudio/osgPlugins/osg/dot_osg.dsp +++ b/VisualStudio/osgPlugins/osg/dot_osg.dsp @@ -268,6 +268,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\PositionAttitudeTransform.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\Program.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\Projection.cpp # End Source File # Begin Source File @@ -288,6 +292,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\ShadeModel.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\Shader.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\Shape.cpp # End Source File # Begin Source File @@ -364,6 +372,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\Transform.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\Uniform.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\VertexProgram.cpp # End Source File # End Group diff --git a/include/osg/Program b/include/osg/Program index aed54ecb7..72cb3543e 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -12,7 +12,7 @@ */ /* file: include/osg/Program - * author: Mike Weiblen 2005-03-30 + * author: Mike Weiblen 2005-04-06 */ #ifndef OSG_PROGRAM @@ -330,6 +330,11 @@ class SG_EXPORT Program : public osg::StateAttribute * Mark Program as needing relink. Return true for success */ bool addShader( Shader* shader ); + unsigned int getNumShaders() const { return _shaderList.size(); } + + Shader* getShader( unsigned int i ) { return _shaderList[i].get(); } + const Shader* getShader( unsigned int i ) const { return _shaderList[i].get(); } + /** Remove osg::Shader from this osg::Program. * Mark Program as needing relink. Return true for success */ bool removeShader( Shader* shader ); diff --git a/include/osg/Shader b/include/osg/Shader index d69f0e024..7752bcfea 100644 --- a/include/osg/Shader +++ b/include/osg/Shader @@ -12,7 +12,7 @@ */ /* file: include/osg/Shader - * author: Mike Weiblen 2005-03-30 + * author: Mike Weiblen 2005-04-06 */ #ifndef OSG_SHADER @@ -41,19 +41,21 @@ class SG_EXPORT Shader : public osg::Object enum Type { VERTEX = GL_VERTEX_SHADER, - FRAGMENT = GL_FRAGMENT_SHADER + FRAGMENT = GL_FRAGMENT_SHADER, + UNDEFINED = -1 }; + Shader(); Shader( Type type, const char* sourceText = 0 ); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ Shader(const Shader& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); - META_Object(osg, Shader); // see note in Shader.cpp Shader() + META_Object(osg, Shader); int compare(const Shader& rhs) const; - // data access methods. + bool setType( Type t ); /** Load the Shader's source code text from a string. */ void setShaderSource( const char* sourceText ); @@ -97,6 +99,8 @@ class SG_EXPORT Shader : public osg::Object * in the OpenGL context related to contextID.*/ static void flushDeletedGlShaders(unsigned int contextID,double currentTime, double& availableTime); + static Shader::Type getTypeId( const std::string& tname ); + protected: /** PerContextShader (PCS) is an OSG-internal encapsulation of glShader per-GL context. */ class PerContextShader : public osg::Referenced @@ -139,7 +143,6 @@ class SG_EXPORT Shader : public osg::Object }; protected: /*methods*/ - Shader(); // undesired, temporarily required by META_Object. virtual ~Shader(); PerContextShader* getPCS(unsigned int contextID) const; @@ -149,7 +152,7 @@ class SG_EXPORT Shader : public osg::Object bool removeProgramRef( Program* program ); protected: /*data*/ - const Type _type; + Type _type; std::string _name; std::string _shaderSource; /** osg::Programs that this osg::Shader is attached to */ diff --git a/include/osg/Uniform b/include/osg/Uniform index 764928a9d..140fffa36 100644 --- a/include/osg/Uniform +++ b/include/osg/Uniform @@ -11,7 +11,7 @@ */ /* file: include/osg/Uniform - * author: Mike Weiblen 2005-03-29 + * author: Mike Weiblen 2005-04-06 */ // NOTICE: This code is CLOSED during construction and/or renovation! @@ -158,6 +158,7 @@ class SG_EXPORT Uniform : public Object }; public: + Uniform(); Uniform( const char* name, Type type ); /** Copy constructor using CopyOp to manage deep vs shallow copy. */ @@ -165,6 +166,8 @@ class SG_EXPORT Uniform : public Object META_Object(osg, Uniform); + bool setType( Type t ); + bool setName( const std::string& name ); /** Get the name of glUniform. */ const std::string& getName() const { return _name; } @@ -175,6 +178,8 @@ class SG_EXPORT Uniform : public Object /** Return the name of a type as string. */ static const char* getTypename( Type t ); + static Uniform::Type getTypeId( const std::string& tname ); + /** convenient construction w/ assignment */ explicit Uniform( const char* name, float f ); explicit Uniform( const char* name, int i ); @@ -243,8 +248,8 @@ class SG_EXPORT Uniform : public Object protected: - const std::string _name; - const Type _type; + std::string _name; + Type _type; union { GLfloat f1; // float GLfloat f2[2]; // vec2 @@ -259,7 +264,6 @@ class SG_EXPORT Uniform : public Object } _data; private: - Uniform(); // disallowed Uniform& operator=(const Uniform&); // disallowed }; diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index a223ec26c..456c26695 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -13,7 +13,7 @@ */ /* file: src/osg/Program.cpp - * author: Mike Weiblen 2005-03-30 + * author: Mike Weiblen 2005-04-06 */ #include @@ -2000,6 +2000,8 @@ void Program::releaseGLObjects(osg::State* state) const bool Program::addShader( Shader* shader ) { + if( !shader ) return false; + // Shader can only be added once to a Program for( unsigned int i=0; i < _shaderList.size(); ++i ) { @@ -2015,6 +2017,8 @@ bool Program::addShader( Shader* shader ) bool Program::removeShader( Shader* shader ) { + if( !shader ) return false; + // Shader must exist to be removed. for( unsigned int i=0; i < _shaderList.size(); ++i ) { diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 3c01ed634..03deddce2 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -13,7 +13,7 @@ */ /* file: src/osg/Shader.cpp - * author: Mike Weiblen 2005-03-30 + * author: Mike Weiblen 2005-04-06 */ #include @@ -99,11 +99,8 @@ Shader::Shader(Type type, const char* sourceText) : } Shader::Shader() : - _type(VERTEX) + _type(UNDEFINED) { - // TODO this default constructor is inappropriate for the Shader class. - // It exists for now because it is required by META_OBject - osg::notify(osg::FATAL) << "how got here?" << std::endl; } Shader::Shader(const Shader& rhs, const osg::CopyOp& copyop): @@ -118,6 +115,17 @@ Shader::~Shader() { } +bool Shader::setType( Type t ) +{ + if( _type != UNDEFINED ) + { + osg::notify(osg::WARN) << "cannot change type of Shader" << std::endl; + return false; + } + + _type = t; + return true; +} int Shader::compare(const Shader& rhs) const { @@ -172,13 +180,21 @@ const char* Shader::getTypename() const { switch( getType() ) { - case VERTEX: return "Vertex"; - case FRAGMENT: return "Fragment"; + case VERTEX: return "VERTEX"; + case FRAGMENT: return "FRAGMENT"; default: return "UNDEFINED"; } } +/*static*/ Shader::Type Shader::getTypeId( const std::string& tname ) +{ + if( tname == "VERTEX" ) return VERTEX; + if( tname == "FRAGMENT" ) return FRAGMENT; + return UNDEFINED; +} + + void Shader::compileShader( unsigned int contextID ) const { getPCS( contextID )->compileShader(); diff --git a/src/osg/Uniform.cpp b/src/osg/Uniform.cpp index d6f9424cb..5a0a81922 100644 --- a/src/osg/Uniform.cpp +++ b/src/osg/Uniform.cpp @@ -11,7 +11,7 @@ */ /* file: src/osg/Uniform.cpp - * author: Mike Weiblen 2005-03-30 + * author: Mike Weiblen 2005-04-06 */ // NOTICE: This code is CLOSED during construction and/or renovation! @@ -34,10 +34,6 @@ using namespace osg; Uniform::Uniform() : _name(""), _type(UNDEFINED) { - // 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; } @@ -79,6 +75,29 @@ Uniform::Uniform( const Uniform& rhs, const CopyOp& copyop ) : copyData( rhs ); } +bool Uniform::setType( Type t ) +{ + if( _type != UNDEFINED ) + { + osg::notify(osg::WARN) << "cannot change type of Uniform" << std::endl; + return false; + } + _type = t; + return true; +} + +bool Uniform::setName( const std::string& name ) +{ + if( _name != "" ) + { + osg::notify(osg::WARN) << "cannot change name of Uniform" << std::endl; + return false; + } + _name = name; + return true; +} + + /////////////////////////////////////////////////////////////////////////// int Uniform::compare(const Uniform& rhs) const @@ -286,6 +305,32 @@ const char* Uniform::getTypename( Type t ) } } +Uniform::Type Uniform::getTypeId( const std::string& tname ) +{ + if( tname == "float" ) return FLOAT; + if( tname == "vec2" ) return FLOAT_VEC2; + if( tname == "vec3" ) return FLOAT_VEC3; + if( tname == "vec4" ) return FLOAT_VEC4; + if( tname == "int" ) return INT; + if( tname == "ivec2" ) return INT_VEC2; + if( tname == "ivec3" ) return INT_VEC3; + if( tname == "ivec4" ) return INT_VEC4; + if( tname == "bool" ) return BOOL; + if( tname == "bvec2" ) return BOOL_VEC2; + if( tname == "bvec3" ) return BOOL_VEC3; + if( tname == "bvec4" ) return BOOL_VEC4; + if( tname == "mat2" ) return FLOAT_MAT2; + if( tname == "mat3" ) return FLOAT_MAT3; + if( tname == "mat4" ) return FLOAT_MAT4; + if( tname == "sampler1D" ) return SAMPLER_1D; + if( tname == "sampler2D" ) return SAMPLER_2D; + if( tname == "sampler3D" ) return SAMPLER_3D; + if( tname == "samplerCube" ) return SAMPLER_CUBE; + if( tname == "sampler1DShadow" ) return SAMPLER_1D_SHADOW; + if( tname == "sampler2DShadow" ) return SAMPLER_2D_SHADOW; + return UNDEFINED; +} + Uniform::Type Uniform::repType( Type t ) { switch( t ) diff --git a/src/osgPlugins/osg/GNUmakefile b/src/osgPlugins/osg/GNUmakefile index 7a0b1ff88..d029dd61a 100644 --- a/src/osgPlugins/osg/GNUmakefile +++ b/src/osgPlugins/osg/GNUmakefile @@ -7,13 +7,13 @@ CXXFILES =\ AutoTransform.cpp\ Billboard.cpp\ BlendFunc.cpp\ - ClipPlane.cpp\ ClearNode.cpp\ - ColorMask.cpp\ - CoordinateSystemNode.cpp\ - ConvexPlanarOccluder.cpp\ - CullFace.cpp\ ClipNode.cpp\ + ClipPlane.cpp\ + ColorMask.cpp\ + ConvexPlanarOccluder.cpp\ + CoordinateSystemNode.cpp\ + CullFace.cpp\ Depth.cpp\ Drawable.cpp\ EllipsoidModel.cpp\ @@ -34,8 +34,8 @@ CXXFILES =\ Material.cpp\ Matrix.cpp\ MatrixTransform.cpp\ - Node.cpp\ NodeCallback.cpp\ + Node.cpp\ Object.cpp\ OccluderNode.cpp\ PagedLOD.cpp\ @@ -44,30 +44,33 @@ CXXFILES =\ PolygonMode.cpp\ PolygonOffset.cpp\ PositionAttitudeTransform.cpp\ + Program.cpp\ Projection.cpp\ ProxyNode.cpp\ ReaderWriterOSG.cpp\ + Sequence.cpp\ ShadeModel.cpp\ + Shader.cpp\ Shape.cpp\ ShapeDrawable.cpp\ StateSet.cpp\ - Sequence.cpp\ Stencil.cpp\ Switch.cpp\ TessellationHints.cpp\ - TexEnv.cpp\ TexEnvCombine.cpp\ + TexEnv.cpp\ TexEnvFilter.cpp\ TexGen.cpp\ TexGenNode.cpp\ TexMat.cpp\ - Texture.cpp\ Texture1D.cpp\ Texture2D.cpp\ Texture3D.cpp\ - TextureRectangle.cpp\ + Texture.cpp\ TextureCubeMap.cpp\ + TextureRectangle.cpp\ Transform.cpp\ + Uniform.cpp\ VertexProgram.cpp\ Viewport.cpp\ diff --git a/src/osgPlugins/osg/Program.cpp b/src/osgPlugins/osg/Program.cpp new file mode 100644 index 000000000..1a75a1e9e --- /dev/null +++ b/src/osgPlugins/osg/Program.cpp @@ -0,0 +1,89 @@ +#include "osg/Program" +#include "osg/Shader" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgDB; +using namespace std; + +// forward declare functions to use later. +bool Program_readLocalData(Object& obj, Input& fr); +bool Program_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_ProgramProxy +( + new osg::Program, + "Program", + "Object StateAttribute Program", + &Program_readLocalData, + &Program_writeLocalData +); + + +bool Program_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + Program& program = static_cast(obj); + + if (fr.matchSequence("name %s")) + { + program.setName(fr[1].getStr()); + fr+=2; + iteratorAdvanced = true; + } + + while(fr[0].matchWord("AttribBindingLocation")) + { + int index; + fr[1].getInt(index); + program.bindAttribLocation(index,fr[2].getStr()); + fr += 3; + iteratorAdvanced = true; + } + + int num_shaders; + if (fr[0].matchWord("num_shaders") && + fr[1].getInt(num_shaders)) + { + // could allocate space for shaders here... + fr+=2; + iteratorAdvanced = true; + } + + Object* object = NULL; + while((object=fr.readObject())!=NULL) + { + program.addShader(dynamic_cast(object)); + iteratorAdvanced = true; + } + + return iteratorAdvanced; +} + + +bool Program_writeLocalData(const Object& obj,Output& fw) +{ + const Program& program = static_cast(obj); + + if (!program.getName().empty()) fw.indent() << "name "< +#include +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgDB; +using namespace std; + +// forward declare functions to use later. +bool Shader_readLocalData(Object& obj, Input& fr); +bool Shader_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_ShaderProxy +( + new osg::Shader, + "Shader", + "Object Shader", + &Shader_readLocalData, + &Shader_writeLocalData +); + + +bool Shader_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + Shader& shader = static_cast(obj); + + if (fr.matchSequence("type %s")) + { + shader.setType( Shader::getTypeId(fr[1].getStr()) ); + fr+=2; + iteratorAdvanced = true; + } + + if (fr.matchSequence("name %s")) + { + shader.setName(fr[1].getStr()); + fr+=2; + iteratorAdvanced = true; + } + + if (fr.matchSequence("code {")) { + std::string code; + fr += 2; + iteratorAdvanced = true; + int entry = fr[0].getNoNestedBrackets(); + while (!fr.eof() && fr[0].getNoNestedBrackets() >= entry) { + if (fr[0].getStr()) { + code.append(std::string(fr[0].getStr())); + code += '\n' ; + } + ++fr; + } + shader.setShaderSource(code.c_str()); + } + + return iteratorAdvanced; +} + + +bool Shader_writeLocalData(const Object& obj,Output& fw) +{ + const Shader& shader = static_cast(obj); + + fw.indent() << "type " << shader.getTypename() << std::endl; + + if (!shader.getName().empty()) fw.indent() << "name "< lines; + std::istringstream iss(shader.getShaderSource()); + std::string line; + while (std::getline(iss, line)) { + lines.push_back(line); + } + + fw.indent() << "code {\n"; + fw.moveIn(); + + std::vector::const_iterator j; + for (j=lines.begin(); j!=lines.end(); ++j) { + fw.indent() << "\"" << *j << "\"\n"; + } + + fw.moveOut(); + fw.indent() << "}\n"; + + return true; +} diff --git a/src/osgPlugins/osg/Uniform.cpp b/src/osgPlugins/osg/Uniform.cpp new file mode 100644 index 000000000..09dc2e3db --- /dev/null +++ b/src/osgPlugins/osg/Uniform.cpp @@ -0,0 +1,63 @@ +#include "osg/Uniform" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgDB; +using namespace std; + +// forward declare functions to use later. +bool Uniform_readLocalData(Object& obj, Input& fr); +bool Uniform_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_UniformProxy +( + new osg::Uniform, + "Uniform", + "Object Uniform", + &Uniform_readLocalData, + &Uniform_writeLocalData +); + + +bool Uniform_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + Uniform& uniform = static_cast(obj); + + if (fr.matchSequence("type %s")) + { + uniform.setType( Uniform::getTypeId(fr[1].getStr()) ); + fr+=2; + iteratorAdvanced = true; + } + + if (fr.matchSequence("name %s")) + { + uniform.setName(fr[1].getStr()); + fr+=2; + iteratorAdvanced = true; + } + + // TODO read uniform value based on type + + return iteratorAdvanced; +} + + +bool Uniform_writeLocalData(const Object& obj,Output& fw) +{ + const Uniform& uniform = static_cast(obj); + + fw.indent() << "type " << uniform.getTypename( uniform.getType() ) << std::endl; + + fw.indent() << "name "<< uniform.getName() << std::endl; + + // TODO write uniform value based on type + + return true; +}