From 23fc1900ce63ddf96c58727a175a158da5ead387 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 17 Jul 2003 06:43:15 +0000 Subject: [PATCH] From Romano Jose Magacho da Silva, added osg:FragmentProgram. From Robert, add .osg support for FragmentProgram. --- AUTHORS.txt | 2 +- VisualStudio/osg/osg.dsp | 8 + VisualStudio/osgPlugins/osg/dot_osg.dsp | 4 + include/osg/FragmentProgram | 269 +++++++++++++++++++++ src/osg/FragmentProgram.cpp | 298 ++++++++++++++++++++++++ src/osg/GNUmakefile | 1 + src/osgPlugins/osg/FragmentProgram.cpp | 75 ++++++ src/osgPlugins/osg/GNUmakefile | 1 + src/osgUtil/SceneView.cpp | 2 + 9 files changed, 659 insertions(+), 1 deletion(-) create mode 100644 include/osg/FragmentProgram create mode 100644 src/osg/FragmentProgram.cpp create mode 100644 src/osgPlugins/osg/FragmentProgram.cpp diff --git a/AUTHORS.txt b/AUTHORS.txt index 84d8785ac..3690562b6 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -137,7 +137,7 @@ Rune Schmidt Jensen Romano José Magacho da Silva - pause/resume in osgGA::AnimationPathManipulator - support for managing deleted vertex programs in osg::VertexProgram. - + - osg::FragmentProgram. Eric Sokolowsky - pbm/pgm/ppm reader. diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index c5847eb7c..cd5b7998b 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -201,6 +201,10 @@ SOURCE=..\..\src\osg\Fog.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\FragmentProgram.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\FrameStamp.cpp # End Source File # Begin Source File @@ -573,6 +577,10 @@ SOURCE=..\..\include\osg\FrameStamp # End Source File # Begin Source File +SOURCE=..\..\include\osg\FragmentProgram +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\FrontFace # End Source File # Begin Source File diff --git a/VisualStudio/osgPlugins/osg/dot_osg.dsp b/VisualStudio/osgPlugins/osg/dot_osg.dsp index 77a69e17c..1db1a6230 100755 --- a/VisualStudio/osgPlugins/osg/dot_osg.dsp +++ b/VisualStudio/osgPlugins/osg/dot_osg.dsp @@ -150,6 +150,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\Fog.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\FragmentProgram.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\FrontFace.cpp # End Source File # Begin Source File diff --git a/include/osg/FragmentProgram b/include/osg/FragmentProgram new file mode 100644 index 000000000..ca8332051 --- /dev/null +++ b/include/osg/FragmentProgram @@ -0,0 +1,269 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library 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. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_FRAGMENTPROGRAM +#define OSG_FRAGMENTPROGRAM 1 + +#include +#include +#include +#include + +#include +#include + +// if not defined by gl.h use the definition found in: +// http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_program.txt +#ifndef GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF + +#endif + + +namespace osg { + + + +/** FragmentProgram - encapsulates the OpenGL ARB fragment program state.*/ +class SG_EXPORT FragmentProgram : public StateAttribute +{ + public: + + FragmentProgram(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + FragmentProgram(const FragmentProgram& vp,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, FragmentProgram, FRAGMENTPROGRAM); + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + virtual int compare(const osg::StateAttribute& sa) const + { + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Paramter macro's below. + COMPARE_StateAttribute_Types(FragmentProgram,sa) + + // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_fragmentProgram) + + return 0; // passed all the above comparison macro's, must be equal. + } + + virtual void getAssociatedModes(std::vector& modes) const + { + modes.push_back(GL_FRAGMENT_PROGRAM_ARB); + } + + // data access methods. + + /** Get the handle to the fragment program id for the current context.*/ + inline GLuint& getFragmentProgramID(unsigned int contextID) const + { + return _fragmentProgramIDList[contextID]; + } + + /** Set the fragment program using C++ style string.*/ + inline void setFragmentProgram( const std::string& program ) + { + _fragmentProgram = program; + dirtyFragmentProgramObject(); + } + + /** Set the fragment program using a C style string.*/ + inline void setFragmentProgram( const char* program ) + { + _fragmentProgram = program; + dirtyFragmentProgramObject(); + } + /** Get the fragment program.*/ + inline const std::string& getFragmentProgram() const { return _fragmentProgram; } + + /** Program Parameters */ + inline void setProgramLocalParameter(const GLuint index, const Vec4& p) + { + _programLocalParameters[index] = p; + } + + /** Matrix */ + inline void setMatrix(const GLenum mode, const Matrix& matrix) + { + _matrixList[mode] = matrix; + } + + /** Force a recompile on next apply() of associated OpenGL vertex program objects.*/ + void dirtyFragmentProgramObject(); + + /** use deleteFragmentProgramObject instead of glDeletePrograms to allow + * OpenGL Fragment Program objects to cached until they can be deleted + * by the OpenGL context in which they were created, specified + * by contextID.*/ + static void deleteFragmentProgramObject(unsigned int contextID,GLuint handle); + + /** flush all the cached fragment programs which need to be deleted + * in the OpenGL context related to contextID.*/ + static void flushDeletedFragmentProgramObjects(unsigned int contextID,double currentTime, double& availableTime); + + virtual void apply(State& state) const; + + virtual void compile(State& state) const { apply(state); } + + /** Extensions class which encapsulates the querring of extensions and + * associated function pointers, and provide convinience wrappers to + * check for the extensions or use the associated functions.*/ + class SG_EXPORT Extensions : public osg::Referenced + { + public: + Extensions(); + + Extensions(const Extensions& rhs); + + void lowestCommonDenominator(const Extensions& rhs); + + void setupGLExtenions(); + + void setFragmentProgramSupported(bool flag) { _isFragmentProgramSupported=flag; } + bool isFragmentProgramSupported() const { return _isFragmentProgramSupported; } + + void glBindProgram(GLenum target, GLuint id) const; + void glGenPrograms(GLsizei n, GLuint *programs) const; + void glDeletePrograms(GLsizei n, GLuint *programs) const; + void glProgramString(GLenum target, GLenum format, GLsizei len, const void *string) const; + void glProgramLocalParameter4fv(GLenum target, GLuint index, const GLfloat *params) const; + + protected: + + ~Extensions() {} + + bool _isFragmentProgramSupported; + + void* _glBindProgram; + void* _glGenPrograms; + void *_glDeletePrograms; + void* _glProgramString; + void* _glProgramLocalParameter4fv; + }; + + /** Function to call to get the extension of a specified context. + * If the Exentsion object for that context has not yet been created then + * and the 'createIfNotInitalized' flag been set to false then returns NULL. + * If 'createIfNotInitalized' is true then the Extensions object is + * automatically created. However, in this case the extension object + * only be created with the graphics context associated with ContextID..*/ + static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized); + + /** setExtensions allows users to override the extensions across graphics contexts. + * typically used when you have different extensions supported across graphics pipes + * but need to ensure that they all use the same low common denominator extensions.*/ + static void setExtensions(unsigned int contextID,Extensions* extensions); + + + protected: + + + virtual ~FragmentProgram(); + + typedef buffered_value FragmentProgramIDList; + mutable FragmentProgramIDList _fragmentProgramIDList; + + std::string _fragmentProgram; + + typedef std::map LocalParamList; + LocalParamList _programLocalParameters; + + typedef std::map MatrixList; + MatrixList _matrixList; +}; + + + +} + +#endif + diff --git a/src/osg/FragmentProgram.cpp b/src/osg/FragmentProgram.cpp new file mode 100644 index 000000000..371a2bcaa --- /dev/null +++ b/src/osg/FragmentProgram.cpp @@ -0,0 +1,298 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library 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. See the + * OpenSceneGraph Public License for more details. +*/ +#include +#include +#include +#include +#include + +#include + +using namespace osg; + +// static cache of deleted fragment programs which can only +// by completely deleted once the appropriate OpenGL context +// is set. +typedef std::list FragmentProgramObjectList; +typedef std::map DeletedFragmentProgramObjectCache; +static DeletedFragmentProgramObjectCache s_deletedFragmentProgramObjectCache; + +void FragmentProgram::deleteFragmentProgramObject(unsigned int contextID,GLuint handle) +{ + if (handle!=0) + { + // insert the handle into the cache for the appropriate context. + s_deletedFragmentProgramObjectCache[contextID].push_back(handle); + } +} + + +void FragmentProgram::flushDeletedFragmentProgramObjects(unsigned int contextID,double /*currentTime*/, double& availableTime) +{ + // if no time available don't try to flush objects. + if (availableTime<=0.0) return; + + const osg::Timer& timer = *osg::Timer::instance(); + osg::Timer_t start_tick = timer.tick(); + double elapsedTime = 0.0; + + DeletedFragmentProgramObjectCache::iterator citr = s_deletedFragmentProgramObjectCache.find(contextID); + if (citr!=s_deletedFragmentProgramObjectCache.end()) + { + + const Extensions* extensions = getExtensions(contextID,true); + + FragmentProgramObjectList& vpol = citr->second; + + for(FragmentProgramObjectList::iterator titr=vpol.begin(); + titr!=vpol.end() && elapsedTimeglDeletePrograms( 1L, &(*titr ) ); + titr = vpol.erase(titr); + elapsedTime = timer.delta_s(start_tick,timer.tick()); + } + } + + availableTime -= elapsedTime; +} + + +FragmentProgram::FragmentProgram() +{ +} + + +FragmentProgram::FragmentProgram(const FragmentProgram& vp,const CopyOp& copyop): + osg::StateAttribute(vp,copyop) +{ + _fragmentProgram = vp._fragmentProgram; + + for( LocalParamList::const_iterator itr = vp._programLocalParameters.begin(); + itr != vp._programLocalParameters.end(); ++itr ) + { + _programLocalParameters[itr->first] = itr->second; + } + + for( MatrixList::const_iterator mitr = vp._matrixList.begin(); + mitr != vp._matrixList.end(); ++mitr ) + { + _matrixList[mitr->first] = mitr->second; + } +} + + +// virtual +FragmentProgram::~FragmentProgram() +{ + dirtyFragmentProgramObject(); +} + +void FragmentProgram::dirtyFragmentProgramObject() +{ + for(unsigned int i=0;i<_fragmentProgramIDList.size();++i) + { + if (_fragmentProgramIDList[i] != 0) + { + FragmentProgram::deleteFragmentProgramObject(i,_fragmentProgramIDList[i]); + _fragmentProgramIDList[i] = 0; + } + } +} + +void FragmentProgram::apply(State& state) const +{ + const unsigned int contextID = state.getContextID(); + const Extensions* extensions = getExtensions(contextID,true); + + if (!extensions->isFragmentProgramSupported()) + return; + + + GLuint& fragmentProgramId=getFragmentProgramID(state.getContextID()); + + // Fragment Program + if (fragmentProgramId != 0) + { + extensions->glBindProgram( GL_FRAGMENT_PROGRAM_ARB, fragmentProgramId ); + } + else if (!_fragmentProgram.empty()) + { + glGetError(); // Reset Error flags. + extensions->glGenPrograms( 1, &fragmentProgramId ); + extensions->glBindProgram( GL_FRAGMENT_PROGRAM_ARB, fragmentProgramId ); + extensions->glProgramString( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + _fragmentProgram.length(), _fragmentProgram.c_str()); + + // Check for errors + GLint errorposition; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorposition); + if (errorposition != -1) + { + notify(osg::FATAL) << "FragmentProgram: " << glGetString(GL_PROGRAM_ERROR_STRING_ARB) << std::endl; + + std::string::size_type start = _fragmentProgram.rfind('\n', errorposition); + std::string::size_type stop = _fragmentProgram.find('\n', errorposition); + if (start!=std::string::npos && stop!=std::string::npos) + { + notify(osg::FATAL) << " : " << _fragmentProgram.substr(start+1, stop-start-2) << std::endl; + std::string pointAtproblem(errorposition-(start+1), ' '); + notify(osg::FATAL) << " : " << pointAtproblem << '^' << std::endl; + } + return; + } + } + + // Update local program parameters + { + for(LocalParamList::const_iterator itr=_programLocalParameters.begin(); + itr!=_programLocalParameters.end(); + ++itr) + { + extensions->glProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM_ARB, (*itr).first, (*itr).second.ptr()); + } + } + + // Update matrix + if (!_matrixList.empty()) + { + for(MatrixList::const_iterator itr = _matrixList.begin(); + itr!=_matrixList.end(); + ++itr) + { + glMatrixMode((*itr).first); + glLoadMatrixf((*itr).second.ptr()); + } + glMatrixMode(GL_MODELVIEW); // restore matrix mode + } +} + + +typedef buffered_value< ref_ptr > BufferedExtensions; +static BufferedExtensions s_extensions; + +FragmentProgram::Extensions* FragmentProgram::getExtensions(unsigned int contextID,bool createIfNotInitalized) +{ + if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions; + return s_extensions[contextID].get(); +} + +void FragmentProgram::setExtensions(unsigned int contextID,Extensions* extensions) +{ + s_extensions[contextID] = extensions; +} + +FragmentProgram::Extensions::Extensions() +{ + setupGLExtenions(); +} + +FragmentProgram::Extensions::Extensions(const Extensions& rhs): + Referenced() +{ + _isFragmentProgramSupported = rhs._isFragmentProgramSupported; + _glBindProgram = rhs._glBindProgram; + _glGenPrograms = rhs._glGenPrograms; + _glDeletePrograms = rhs._glDeletePrograms; + _glProgramString = rhs._glProgramString; + _glProgramLocalParameter4fv = rhs._glProgramLocalParameter4fv; +} + + +void FragmentProgram::Extensions::lowestCommonDenominator(const Extensions& rhs) +{ + if (!rhs._isFragmentProgramSupported) _isFragmentProgramSupported = false; + + if (!rhs._glBindProgram) _glBindProgram = 0; + if (!rhs._glGenPrograms) _glGenPrograms = 0; + if (!rhs._glDeletePrograms) _glDeletePrograms = 0; + if (!rhs._glProgramString) _glProgramString = 0; + if (!rhs._glProgramLocalParameter4fv) _glProgramLocalParameter4fv = 0; + +} + +void FragmentProgram::Extensions::setupGLExtenions() +{ + _isFragmentProgramSupported = isGLExtensionSupported("GL_ARB_fragment_program"); + + _glBindProgram = osg::getGLExtensionFuncPtr("glBindProgramARB"); + _glGenPrograms = osg::getGLExtensionFuncPtr("glGenProgramsARB"); + _glDeletePrograms = osg::getGLExtensionFuncPtr("glDeleteProgramsARB"); + _glProgramString = osg::getGLExtensionFuncPtr("glProgramStringARB"); + _glProgramLocalParameter4fv = osg::getGLExtensionFuncPtr("glProgramLocalParameter4fvARB"); +} + +void FragmentProgram::Extensions::glBindProgram(GLenum target, GLuint id) const +{ + if (_glBindProgram) + { + typedef void (APIENTRY * BindProgramProc) (GLenum target, GLuint id); + ((BindProgramProc)_glBindProgram)(target,id); + } + else + { + notify(WARN)<<"Error: glBindProgram not supported by OpenGL driver"< +#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 FragmentProgram_readLocalData(Object& obj, Input& fr); +bool FragmentProgram_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_FragmentProgramProxy +( + new osg::FragmentProgram, + "FragmentProgram", + "Object StateAttribute FragmentProgram", + &FragmentProgram_readLocalData, + &FragmentProgram_writeLocalData +); + + +bool FragmentProgram_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + FragmentProgram& fragmentProgram = static_cast(obj); + + 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.push_back('\n'); + } + ++fr; + } + fragmentProgram.setFragmentProgram(code); + } + return iteratorAdvanced; +} + + +bool FragmentProgram_writeLocalData(const Object& obj,Output& fw) +{ + const FragmentProgram& fragmentProgram = static_cast(obj); + + std::vector lines; + std::istringstream iss(fragmentProgram.getFragmentProgram()); + 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/GNUmakefile b/src/osgPlugins/osg/GNUmakefile index 880d6f5dc..6da9e4f2c 100644 --- a/src/osgPlugins/osg/GNUmakefile +++ b/src/osgPlugins/osg/GNUmakefile @@ -16,6 +16,7 @@ CXXFILES =\ Drawable.cpp\ ClearNode.cpp\ Fog.cpp\ + FragmentProgram.cpp\ FrontFace.cpp\ Geode.cpp\ Geometry.cpp\ diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 15c2e330f..a443f1f23 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -546,6 +547,7 @@ void SceneView::draw() osg::Drawable::flushDeletedDisplayLists(_state->getContextID(),currentTime,availableTime); osg::Drawable::flushDeletedVertexBufferObjects(_state->getContextID(),currentTime,availableTime); osg::VertexProgram::flushDeletedVertexProgramObjects(_state->getContextID(),currentTime,availableTime); + osg::FragmentProgram::flushDeletedFragmentProgramObjects(_state->getContextID(),currentTime,availableTime); osg::Texture::flushTextureObjects(_state->getContextID(),currentTime,availableTime); //osg::Timer_t tend = timer.tick();