From 7ce1938543e12ced9f164d59603b937b70513031 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 12 Mar 2018 15:12:44 +0000 Subject: [PATCH 1/7] Improved indentation --- src/osg/Image.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index a2ccc85fc..ccbf68366 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -241,7 +241,7 @@ Image::Image(const Image& image,const CopyOp& copyop): { unsigned int size = image.getTotalSizeInBytesIncludingMipmaps(); setData(new unsigned char [size],USE_NEW_DELETE); - if (unsigned char* dest_ptr = _data) + if (unsigned char* dest_ptr = _data) { for(DataIterator itr(&image); itr.valid(); ++itr) { @@ -813,7 +813,7 @@ osg::Vec3i Image::computeBlockFootprint(GLenum pixelFormat) { case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : return osg::Vec3i(4,4,4);//opengl 3d dxt: r value means (max)4 consecutive blocks in r direction packed into a slab. - + case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT) : case(GL_COMPRESSED_RED_RGTC1_EXT) : case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT) : @@ -863,7 +863,7 @@ osg::Vec3i Image::computeBlockFootprint(GLenum pixelFormat) { case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) : return osg::Vec3i(10, 10, 1); case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) : return osg::Vec3i(12, 10, 1); case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) : return osg::Vec3i(12, 12, 1); - + default: break; } @@ -1611,13 +1611,16 @@ void Image::copySubImage(int s_offset, int t_offset, int r_offset, const osg::Im if (isCompressed()) { osg::Vec3i footprint = computeBlockFootprint(_pixelFormat); - if (footprint.x() == 4 && footprint.y() == 4) { - if ((source->s() & 0x3) || (source->t() & 0x3) || (s_offset & 0x3) || (t_offset & 0x3)) + if (footprint.x() == 4 && footprint.y() == 4) { - OSG_WARN << "Error Image::copySubImage() did not succeed : size " << source->s() << "x" << source->t() << " or offset " << s_offset<< "," << t_offset << " not multiple of 4." << std::endl; - return; + if ((source->s() & 0x3) || (source->t() & 0x3) || (s_offset & 0x3) || (t_offset & 0x3)) + { + OSG_WARN << "Error Image::copySubImage() did not succeed : size " << source->s() << "x" << source->t() << " or offset " << s_offset<< "," << t_offset << " not multiple of 4." << std::endl; + return; + } } - } else { + else + { if ((source->s() % footprint.x()) || (source->t() % footprint.y()) || (s_offset % footprint.x()) || (t_offset% footprint.y())) { OSG_WARN << "Error Image::copySubImage() did not succeed : size " << source->s() << "x" << source->t() << " or offset " << s_offset << "," << t_offset << " not multiple of footprint " << footprint.x() << "x" << footprint.y() << std::endl; From 3f686d871909decc04e76a989909c068f485c771 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 12 Mar 2018 15:29:56 +0000 Subject: [PATCH 2/7] Fixed indentation --- src/osg/Image.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index ccbf68366..98d67d3b2 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -805,14 +805,15 @@ unsigned int Image::computePixelSizeInBits(GLenum format,GLenum type) } -osg::Vec3i Image::computeBlockFootprint(GLenum pixelFormat) { +osg::Vec3i Image::computeBlockFootprint(GLenum pixelFormat) +{ switch (pixelFormat) { case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : - return osg::Vec3i(4,4,4);//opengl 3d dxt: r value means (max)4 consecutive blocks in r direction packed into a slab. + return osg::Vec3i(4,4,4);//opengl 3d dxt: r value means (max)4 consecutive blocks in r direction packed into a slab. case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT) : case(GL_COMPRESSED_RED_RGTC1_EXT) : From 5c8a5307d623af2d37821562e68e828f657dfc3b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 12 Mar 2018 15:55:35 +0000 Subject: [PATCH 3/7] From Colin McDonald, "If the glCreateProgram in osg::Program fails for any reason, then subsequently Program::PerContextProgram::linkProgram would crash. I've put in some checks to prevent that." --- src/osg/Program.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index b41d27b81..d54fb372f 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -656,7 +656,15 @@ Program::PerContextProgram::PerContextProgram(const Program* program, unsigned i { _extensions = GLExtensions::Get( _contextID, true ); _glProgramHandle = _extensions->glCreateProgram(); - _ownsProgramHandle = true; + + if (_glProgramHandle) + { + _ownsProgramHandle = true; + } + else + { + OSG_WARN << "Unable to create osg::Program \"" << _program->getName() << "\"" << " contextID=" << _contextID << std::endl; + } } requestLink(); } @@ -682,6 +690,8 @@ void Program::PerContextProgram::linkProgram(osg::State& state) if( ! _needsLink ) return; _needsLink = false; + if (!_glProgramHandle) return; + OSG_INFO << "Linking osg::Program \"" << _program->getName() << "\"" << " id=" << _glProgramHandle << " contextID=" << _contextID @@ -709,7 +719,7 @@ void Program::PerContextProgram::linkProgram(osg::State& state) if (!_loadedBinary) { const GLsizei shaderMaxCount = 20; - GLsizei shadersCount; + GLsizei shadersCount = 0; GLuint shaderObjectHandle[shaderMaxCount]; _extensions->glGetAttachedShaders(_glProgramHandle, shaderMaxCount, &shadersCount, shaderObjectHandle); @@ -1035,6 +1045,8 @@ void Program::PerContextProgram::linkProgram(osg::State& state) bool Program::PerContextProgram::validateProgram() { + if (!_glProgramHandle) return false; + GLint validated = GL_FALSE; _extensions->glValidateProgram( _glProgramHandle ); _extensions->glGetProgramiv( _glProgramHandle, GL_VALIDATE_STATUS, &validated ); @@ -1057,11 +1069,15 @@ bool Program::PerContextProgram::validateProgram() bool Program::PerContextProgram::getInfoLog( std::string& infoLog ) const { + if (!_glProgramHandle) return false; + return _extensions->getProgramInfoLog( _glProgramHandle, infoLog ); } Program::ProgramBinary* Program::PerContextProgram::compileProgramBinary(osg::State& state) { + if (!_glProgramHandle) return 0; + linkProgram(state); GLint binaryLength = 0; _extensions->glGetProgramiv( _glProgramHandle, GL_PROGRAM_BINARY_LENGTH, &binaryLength ); @@ -1079,5 +1095,7 @@ Program::ProgramBinary* Program::PerContextProgram::compileProgramBinary(osg::St void Program::PerContextProgram::useProgram() const { + if (!_glProgramHandle) return; + _extensions->glUseProgram( _glProgramHandle ); } From f8199935fa48683b9b07b9c2d5893c51f1f0a430 Mon Sep 17 00:00:00 2001 From: Yaroslav Tarasov Date: Mon, 12 Mar 2018 16:14:30 +0000 Subject: [PATCH 4/7] Fixed renamed of _textureDepth. --- src/osg/Texture2DArray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osg/Texture2DArray.cpp b/src/osg/Texture2DArray.cpp index 258478eff..5c78b171b 100644 --- a/src/osg/Texture2DArray.cpp +++ b/src/osg/Texture2DArray.cpp @@ -725,7 +725,7 @@ void Texture2DArray::allocateMipmap(State& state) const getCompressedSize( _internalFormat, width, height, textureDepth, blockSize, size); extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY, k, _internalFormat, - width, height, _textureDepth, _borderWidth, + width, height, textureDepth, _borderWidth, size, NULL); } From 23b94c24683940eec2d7d633c80c08a25623ce9a Mon Sep 17 00:00:00 2001 From: gwaldron Date: Mon, 12 Mar 2018 17:35:46 -0400 Subject: [PATCH 5/7] Text: added code in accept(functor) methods to check for empty vectors before accessing front() element, which was causing a crash in some cases. Also fixed a negated null check in getCharacterCoords --- src/osgText/Text.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 4069a6318..6a1f6e13c 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1250,9 +1250,13 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const { - if (_coords.valid() ) + if (_coords.valid() && !_coords->empty()) { af.apply(osg::Drawable::VERTICES, _coords->size(), &(_coords->front())); + } + + if (_texcoords.valid() && !_texcoords->empty()) + { af.apply(osg::Drawable::TEXTURE_COORDS_0, _texcoords->size(), &(_texcoords->front())); } } @@ -1285,14 +1289,14 @@ void Text::accept(osg::PrimitiveFunctor& pf) const if (glyphquad._primitives.valid()) { const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast(glyphquad._primitives.get()); - if (drawElementsUShort) + if (drawElementsUShort && drawElementsUShort->size() > 0) { pf.drawElements(GL_TRIANGLES, drawElementsUShort->size(), &(drawElementsUShort->front())); } else { const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast(glyphquad._primitives.get()); - if (drawElementsUInt) + if (drawElementsUInt && drawElementsUInt->size() > 0) { pf.drawElements(GL_TRIANGLES, drawElementsUInt->size(), &(drawElementsUInt->front())); } @@ -1303,7 +1307,7 @@ void Text::accept(osg::PrimitiveFunctor& pf) const bool Text::getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLeft, osg::Vec3& topRight) const { - if (_coords) return false; + if (!_coords.valid()) return false; if ((index*4+4)>static_cast(_coords->size())) return false; From 4447190dd6cb926341547c001bcaecedffb3bf81 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 14 Mar 2018 08:22:45 +0000 Subject: [PATCH 6/7] Refactored osgUtil::ShaderGen to use #pragma(tic) shader composition. --- examples/osgshadergen/osgshadergen.cpp | 51 ++-- include/osgUtil/ShaderGen | 46 +-- src/osgUtil/ShaderGen.cpp | 406 ++++--------------------- src/osgUtil/shaders/shadergen_frag.cpp | 35 +++ src/osgUtil/shaders/shadergen_vert.cpp | 44 +++ 5 files changed, 164 insertions(+), 418 deletions(-) create mode 100644 src/osgUtil/shaders/shadergen_frag.cpp create mode 100644 src/osgUtil/shaders/shadergen_vert.cpp diff --git a/examples/osgshadergen/osgshadergen.cpp b/examples/osgshadergen/osgshadergen.cpp index 042f00a02..f57eed04e 100644 --- a/examples/osgshadergen/osgshadergen.cpp +++ b/examples/osgshadergen/osgshadergen.cpp @@ -10,6 +10,7 @@ */ #include +#include #include #include @@ -26,31 +27,6 @@ #include -class ShaderGenReadFileCallback : public osgDB::Registry::ReadFileCallback -{ -public: - ShaderGenReadFileCallback() - { - } - - virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& filename, const osgDB::ReaderWriter::Options* options) - { - osgDB::ReaderWriter::ReadResult result = osgDB::Registry::ReadFileCallback::readNode(filename, options); - if (osg::Node *node = result.getNode()) - { - _visitor.reset(); - node->accept(_visitor); - } - return result; - } - - void setRootStateSet(osg::StateSet *stateSet) { _visitor.setRootStateSet(stateSet); } - osg::StateSet *getRootStateSet() const { return _visitor.getRootStateSet(); } - -protected: - osgUtil::ShaderGenVisitor _visitor; -}; - int main(int argc, char** argv) { @@ -64,6 +40,8 @@ int main(int argc, char** argv) osgViewer::Viewer viewer(arguments); + + unsigned int helpType = 0; if ((helpType = arguments.readHelpType())) { @@ -134,11 +112,10 @@ int main(int argc, char** argv) // add the screen capture handler viewer.addEventHandler(new osgViewer::ScreenCaptureHandler); - // Register shader generator callback - ShaderGenReadFileCallback *readFileCallback = new ShaderGenReadFileCallback; - // All read nodes will inherit root state set. - readFileCallback->setRootStateSet(viewer.getCamera()->getStateSet()); - osgDB::Registry::instance()->setReadFileCallback(readFileCallback); + + + std::string outputFilename; + if (arguments.read("-o", outputFilename)) {} // load the data osg::ref_ptr loadedModel = osgDB::readRefNodeFiles(arguments); @@ -148,6 +125,20 @@ int main(int argc, char** argv) return 1; } + // run the shadergen on the loaded scene graph, and assign the uber shader + osgUtil::ShaderGenVisitor shadergen; + shadergen.assignUberProgram(viewer.getCamera()->getStateSet()); + //shadergen.assignUberProgram(loadedModel->getOrCreateStateSet()); + loadedModel->accept(shadergen); + + if (!outputFilename.empty()) + { + osgDB::writeNodeFile(*loadedModel, outputFilename); + osgDB::writeObjectFile(*(viewer.getCamera()->getStateSet()),"rootStateSet.osgt"); + return 0; + } + + // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); diff --git a/include/osgUtil/ShaderGen b/include/osgUtil/ShaderGen index f30a9cd78..60c059c19 100644 --- a/include/osgUtil/ShaderGen +++ b/include/osgUtil/ShaderGen @@ -26,57 +26,19 @@ namespace osgUtil { -class OSGUTIL_EXPORT ShaderGenCache : public osg::Referenced -{ -public: - enum StateMask - { - BLEND = 1, - LIGHTING = 2, - FOG = 4, - DIFFUSE_MAP = 8, //< Texture in unit 0 - NORMAL_MAP = 16 //< Texture in unit 1 and vertex attribute array 6 - }; - - typedef std::map > StateSetMap; - - ShaderGenCache() {}; - - void setStateSet(int stateMask, osg::StateSet *program); - osg::StateSet *getStateSet(int stateMask) const; - osg::StateSet *getOrCreateStateSet(int stateMask); - -protected: - osg::StateSet *createStateSet(int stateMask) const; - mutable OpenThreads::Mutex _mutex; - StateSetMap _stateSetMap; - -}; - class OSGUTIL_EXPORT ShaderGenVisitor : public osg::NodeVisitor { public: ShaderGenVisitor(); - ShaderGenVisitor(ShaderGenCache *stateCache); - void setStateCache(ShaderGenCache *stateCache) { _stateCache = stateCache; } - ShaderGenCache *getStateCache() const { return _stateCache.get(); } + /// assign default uber program to specified StateSet - typically the root node of the scene graph or the view's Camera + void assignUberProgram(osg::StateSet *stateSet); - /// Top level state set applied as the first one. - void setRootStateSet(osg::StateSet *stateSet); - osg::StateSet *getRootStateSet() const { return _rootStateSet.get(); } + void apply(osg::Node& node); - void apply(osg::Node &node); - void apply(osg::Drawable &drawable); - - void reset(); + void remapStateSet(osg::StateSet* stateSet); protected: - void update(osg::Drawable *drawable); - - osg::ref_ptr _stateCache; - osg::ref_ptr _state; - osg::ref_ptr _rootStateSet; }; } diff --git a/src/osgUtil/ShaderGen.cpp b/src/osgUtil/ShaderGen.cpp index 4fb248e6d..e67eaba58 100644 --- a/src/osgUtil/ShaderGen.cpp +++ b/src/osgUtil/ShaderGen.cpp @@ -22,379 +22,93 @@ #include #include +#include "shaders/shadergen_vert.cpp" +#include "shaders/shadergen_frag.cpp" + using namespace osgUtil; namespace osgUtil { -/// State extended by mode/attribute accessors -class StateEx : public osg::State +osg::ref_ptr s_UberProgram; + +struct UberProgramConstructor { -public: - StateEx() : State() {} - - osg::StateAttribute::GLModeValue getMode(osg::StateAttribute::GLMode mode, - osg::StateAttribute::GLModeValue def = osg::StateAttribute::INHERIT) const + UberProgramConstructor() { - return getMode(_modeMap, mode, def); - } - - osg::StateAttribute *getAttribute(osg::StateAttribute::Type type, unsigned int member = 0) const - { - return getAttribute(_attributeMap, type, member); - } - - osg::StateAttribute::GLModeValue getTextureMode(unsigned int unit, - osg::StateAttribute::GLMode mode, - osg::StateAttribute::GLModeValue def = osg::StateAttribute::INHERIT) const - { - return unit < _textureModeMapList.size() ? getMode(_textureModeMapList[unit], mode, def) : def; - } - - osg::StateAttribute *getTextureAttribute(unsigned int unit, osg::StateAttribute::Type type) const - { - return unit < _textureAttributeMapList.size() ? getAttribute(_textureAttributeMapList[unit], type, 0) : 0; - } - - osg::Uniform *getUniform(const std::string& name) const - { - UniformMap::const_iterator it = _uniformMap.find(name); - return it != _uniformMap.end() ? - const_cast(it->second.uniformVec.back().first) : 0; - } - -protected: - - osg::StateAttribute::GLModeValue getMode(const ModeMap &modeMap, - osg::StateAttribute::GLMode mode, - osg::StateAttribute::GLModeValue def = osg::StateAttribute::INHERIT) const - { - ModeMap::const_iterator it = modeMap.find(mode); - return (it != modeMap.end() && it->second.valueVec.size()) ? it->second.valueVec.back() : def; - } - - osg::StateAttribute *getAttribute(const AttributeMap &attributeMap, - osg::StateAttribute::Type type, unsigned int member = 0) const - { - AttributeMap::const_iterator it = attributeMap.find(std::make_pair(type, member)); - return (it != attributeMap.end() && it->second.attributeVec.size()) ? - const_cast(it->second.attributeVec.back().first) : 0; + s_UberProgram = new osg::Program; + s_UberProgram->addShader(new osg::Shader(osg::Shader::VERTEX, shadergen_vert)); + s_UberProgram->addShader(new osg::Shader(osg::Shader::FRAGMENT, shadergen_frag)); } }; -} - -void ShaderGenCache::setStateSet(int stateMask, osg::StateSet *stateSet) -{ - OpenThreads::ScopedLock lock(_mutex); - _stateSetMap[stateMask] = stateSet; -} - -osg::StateSet *ShaderGenCache::getStateSet(int stateMask) const -{ - OpenThreads::ScopedLock lock(_mutex); - StateSetMap::const_iterator it = _stateSetMap.find(stateMask); - return (it != _stateSetMap.end()) ? it->second.get() : 0; -} - -osg::StateSet *ShaderGenCache::getOrCreateStateSet(int stateMask) -{ - OpenThreads::ScopedLock lock(_mutex); - StateSetMap::iterator it = _stateSetMap.find(stateMask); - if (it == _stateSetMap.end()) - { - osg::StateSet *stateSet = createStateSet(stateMask); - _stateSetMap.insert(it, StateSetMap::value_type(stateMask, stateSet)); - return stateSet; - } - return it->second.get(); -} - -osg::StateSet *ShaderGenCache::createStateSet(int stateMask) const -{ - osg::StateSet *stateSet = new osg::StateSet; - osg::Program *program = new osg::Program; - stateSet->setAttribute(program); - - std::ostringstream vert_frag; - - vert_frag << "// ShaderGen shader\n"; - vert_frag << "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n"; - - // write varyings - if ((stateMask & LIGHTING) && !(stateMask & NORMAL_MAP)) - { - vert_frag << "varying vec3 normalDir;\n"; - } - - if (stateMask & (LIGHTING | NORMAL_MAP)) - { - vert_frag << "varying vec3 lightDir;\n"; - } - - if (stateMask & (LIGHTING | NORMAL_MAP | FOG)) - { - vert_frag << "varying vec3 viewDir;\n"; - } - - vert_frag << "varying vec4 vertexColor;\n"; - - std::ostringstream vert; - std::ostringstream frag; - - // copy varying to vertex ad fragment shader - vert << vert_frag.str(); - frag << vert_frag.str(); - - // write uniforms and attributes - int unit = 0; - if (stateMask & DIFFUSE_MAP) - { - osg::Uniform *diffuseMap = new osg::Uniform("diffuseMap", unit++); - stateSet->addUniform(diffuseMap); - frag << "uniform sampler2D diffuseMap;\n"; - } - - if (stateMask & NORMAL_MAP) - { - osg::Uniform *normalMap = new osg::Uniform("normalMap", unit++); - stateSet->addUniform(normalMap); - frag << "uniform sampler2D normalMap;\n"; - program->addBindAttribLocation("tangent", 6); - vert << "attribute vec3 tangent;\n"; - } - - vert << "\n"\ - "void main()\n"\ - "{\n"\ - " gl_Position = ftransform();\n"; - - if (stateMask & (DIFFUSE_MAP | NORMAL_MAP)) - { - vert << " gl_TexCoord[0] = gl_MultiTexCoord0;\n"; - } - - if (stateMask & NORMAL_MAP) - { - vert << - " vec3 n = gl_NormalMatrix * gl_Normal;\n"\ - " vec3 t = gl_NormalMatrix * tangent;\n"\ - " vec3 b = cross(n, t);\n"\ - " vec3 dir = -vec3(gl_ModelViewMatrix * gl_Vertex);\n"\ - " viewDir.x = dot(dir, t);\n"\ - " viewDir.y = dot(dir, b);\n"\ - " viewDir.z = dot(dir, n);\n"\ - " vec4 lpos = gl_LightSource[0].position;\n"\ - " if (lpos.w == 0.0)\n"\ - " dir = lpos.xyz;\n"\ - " else\n"\ - " dir += lpos.xyz;\n"\ - " lightDir.x = dot(dir, t);\n"\ - " lightDir.y = dot(dir, b);\n"\ - " lightDir.z = dot(dir, n);\n"; - } -#if !OSG_GLES2_FEATURES && !OSG_GLES3_FEATURES && !OSG_GL2_FEATURES - else if (stateMask & LIGHTING) - { - vert << - " normalDir = gl_NormalMatrix * gl_Normal;\n"\ - " vec3 dir = -vec3(gl_ModelViewMatrix * gl_Vertex);\n"\ - " viewDir = dir;\n"\ - " vec4 lpos = gl_LightSource[0].position;\n"\ - " if (lpos.w == 0.0)\n"\ - " lightDir = lpos.xyz;\n"\ - " else\n"\ - " lightDir = lpos.xyz + dir;\n"; - } - else if (stateMask & FOG) - { - vert << - " viewDir = -vec3(gl_ModelViewMatrix * gl_Vertex);\n"\ - " vertexColor = gl_Color;\n"; - } -#endif - else - { - vert << " vertexColor = gl_Color;\n"; - } - - vert << "}\n"; - - frag << "\n"\ - "void main()\n"\ - "{\n"; - - if (stateMask & DIFFUSE_MAP) - { - frag << " vec4 base = vertexColor * texture2D(diffuseMap, gl_TexCoord[0].st);\n"; - } - else - { - frag << " vec4 base = vertexColor;\n"; - } - - if (stateMask & NORMAL_MAP) - { - frag << " vec3 normalDir = texture2D(normalMap, gl_TexCoord[0].st).xyz*2.0-1.0;\n"; - } - -#if !OSG_GLES2_FEATURES && !OSG_GLES3_FEATURES && !OSG_GL2_FEATURES - if (stateMask & (LIGHTING | NORMAL_MAP)) - { - frag << - " vec3 nd = normalize(normalDir);\n"\ - " vec3 ld = normalize(lightDir);\n"\ - " vec3 vd = normalize(viewDir);\n"\ - " vec4 color = gl_FrontLightModelProduct.sceneColor;\n"\ - " color += gl_FrontLightProduct[0].ambient;\n"\ - " float diff = max(dot(ld, nd), 0.0);\n"\ - " color += gl_FrontLightProduct[0].diffuse * diff;\n"\ - " color *= base;\n"\ - " if (diff > 0.0)\n"\ - " {\n"\ - " vec3 halfDir = normalize(ld+vd);\n"\ - " color.rgb += base.a * gl_FrontLightProduct[0].specular.rgb * \n"\ - " pow(max(dot(halfDir, nd), 0.0), gl_FrontMaterial.shininess);\n"\ - " }\n"; - } - else -#endif - { - frag << " vec4 color = base;\n"; - } +UberProgramConstructor s_UberProgramConstructor; -#if !OSG_GLES2_FEATURES && !OSG_GLES3_FEATURES && !OSG_GL2_FEATURES - if (stateMask & FOG) - { - frag << - " float d2 = dot(viewDir, viewDir);//gl_FragCoord.z/gl_FragCoord.w;\n"\ - " float f = exp2(-1.442695*gl_Fog.density*gl_Fog.density*d2);\n"\ - " color.rgb = mix(gl_Fog.color.rgb, color.rgb, clamp(f, 0.0, 1.0));\n"; - } -#endif - - frag << " gl_FragColor = color;\n"; - frag << "}\n"; - - std::string vertstr = vert.str(); - std::string fragstr = frag.str(); - - OSG_DEBUG << "ShaderGenCache Vertex shader:\n" << vertstr << std::endl; - OSG_DEBUG << "ShaderGenCache Fragment shader:\n" << fragstr << std::endl; - - program->addShader(new osg::Shader(osg::Shader::VERTEX, vertstr)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragstr)); - - return stateSet; -} - -ShaderGenVisitor::ShaderGenVisitor() : - NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _stateCache(new ShaderGenCache), - _state(new StateEx) +ShaderGenVisitor::ShaderGenVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { } -ShaderGenVisitor::ShaderGenVisitor(ShaderGenCache *stateCache) : - NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _stateCache(stateCache), - _state(new StateEx) +void ShaderGenVisitor::assignUberProgram(osg::StateSet *stateSet) { -} + if (stateSet) + { + stateSet->setAttribute(s_UberProgram.get()); + stateSet->addUniform(new osg::Uniform("diffuseMap", 0)); -void ShaderGenVisitor::setRootStateSet(osg::StateSet *stateSet) -{ - if (_rootStateSet.valid()) - _state->removeStateSet(0); - _rootStateSet = stateSet; - if (_rootStateSet.valid()) - _state->pushStateSet(_rootStateSet.get()); -} - -void ShaderGenVisitor::reset() -{ - _state->popAllStateSets(); - if (_rootStateSet.valid()) - _state->pushStateSet(_rootStateSet.get()); + remapStateSet(stateSet); + } } void ShaderGenVisitor::apply(osg::Node &node) { - osg::StateSet *stateSet = node.getStateSet(); - - if (stateSet) - _state->pushStateSet(stateSet); + osg::StateSet* stateSet = node.getStateSet(); + if (stateSet) remapStateSet(stateSet); traverse(node); - - if (stateSet) - _state->popStateSet(); } -void ShaderGenVisitor::apply(osg::Drawable &drawable) + +void ShaderGenVisitor::remapStateSet(osg::StateSet* stateSet) { - osg::StateSet *stateSet = drawable.getStateSet(); - if (stateSet) - _state->pushStateSet(stateSet); + if (!stateSet) return; - update(&drawable); + // remove any modes that won't be appropriate when using shaders, and remap them to the apppropriate Uniform/Define combination - if (stateSet) - _state->popStateSet(); + + osg::StateSet::ModeList& modes = stateSet->getModeList(); + + if (modes.count(GL_LIGHTING)>0) + { + osg::StateAttribute::GLModeValue lightingMode =modes[GL_LIGHTING]; + + stateSet->removeMode(GL_LIGHTING); + stateSet->removeMode(GL_LIGHT0); + + stateSet->setDefine("GL_LIGHTING", lightingMode); + } + + + if (modes.count(GL_FOG)>0) + { + osg::StateAttribute::GLModeValue fogMode = modes[GL_FOG]; + stateSet->removeMode(GL_FOG); + stateSet->setDefine("GL_FOG", fogMode); + } + + + if (!stateSet->getTextureModeList().empty()) + { + osg::StateSet::ModeList& textureModes = stateSet->getTextureModeList()[0]; + + if (textureModes.count(GL_TEXTURE_2D)>0) + { + osg::StateAttribute::GLModeValue textureMode = textureModes[GL_TEXTURE_2D]; + stateSet->removeTextureMode(0, GL_TEXTURE_2D); + stateSet->setDefine("GL_TEXTURE_2D", textureMode); + } + } } -void ShaderGenVisitor::update(osg::Drawable *drawable) -{ - // update only geometry due to compatibility issues with user defined drawables - osg::Geometry *geometry = drawable->asGeometry(); -#if 0 - if (!geometry) - return; -#endif - - StateEx *state = static_cast(_state.get()); - // skip nodes without state sets - if (state->getStateSetStackSize() == (_rootStateSet.valid() ? 1u : 0u)) - return; - - // skip state sets with already attached programs - if (state->getAttribute(osg::StateAttribute::PROGRAM)) - return; - - int stateMask = 0; - //if (state->getMode(GL_BLEND) & osg::StateAttribute::ON) - // stateMask |= ShaderGen::BLEND; - if (state->getMode(GL_LIGHTING) & osg::StateAttribute::ON) - stateMask |= ShaderGenCache::LIGHTING; - if (state->getMode(GL_FOG) & osg::StateAttribute::ON) - stateMask |= ShaderGenCache::FOG; - if (state->getTextureAttribute(0, osg::StateAttribute::TEXTURE)) - stateMask |= ShaderGenCache::DIFFUSE_MAP; - - if (state->getTextureAttribute(1, osg::StateAttribute::TEXTURE) && geometry!=0 && - geometry->getVertexAttribArray(6)) //tangent - stateMask |= ShaderGenCache::NORMAL_MAP; - - // Get program and uniforms for accumulated state. - osg::StateSet *progss = _stateCache->getOrCreateStateSet(stateMask); - // Set program and uniforms to the last state set. - osg::StateSet *ss = const_cast(state->getStateSetStack().back()); - ss->setAttribute(progss->getAttribute(osg::StateAttribute::PROGRAM)); - ss->setUniformList(progss->getUniformList()); - - // remove any modes that won't be appropriate when using shaders - if ((stateMask&ShaderGenCache::LIGHTING)!=0) - { - ss->removeMode(GL_LIGHTING); - ss->removeMode(GL_LIGHT0); - } - if ((stateMask&ShaderGenCache::FOG)!=0) - { - ss->removeMode(GL_FOG); - } - if ((stateMask&ShaderGenCache::DIFFUSE_MAP)!=0) ss->removeTextureMode(0, GL_TEXTURE_2D); - if ((stateMask&ShaderGenCache::NORMAL_MAP)!=0) ss->removeTextureMode(1, GL_TEXTURE_2D); -} +} // namespace osgUtil \ No newline at end of file diff --git a/src/osgUtil/shaders/shadergen_frag.cpp b/src/osgUtil/shaders/shadergen_frag.cpp new file mode 100644 index 000000000..5018219f3 --- /dev/null +++ b/src/osgUtil/shaders/shadergen_frag.cpp @@ -0,0 +1,35 @@ +char shadergen_frag[] = "// ShaderGen shader\n" + "// new version\n" + "#ifdef GL_ES\n" + " precision highp float;\n" + "#endif\n" + "\n" + "#pragma import_defines(GL_LIGHTING, GL_TEXTURE_2D, GL_FOG)\n" + "\n" + "#if defined(GL_LIGHTING)\n" + "varying vec3 normalDir;\n" + "varying vec3 lightDir;\n" + "#endif\n" + "\n" + "#if defined(GL_LIGHTING) || defined(GL_FOG)\n" + "varying vec3 viewDir;\n" + "#endif\n" + "\n" + "varying vec4 vertexColor;\n" + "\n" + "#if defined(GL_TEXTURE_2D)\n" + "uniform sampler2D diffuseMap;\n" + "#endif\n" + "\n" + "void main()\n" + "{\n" + " vec4 color = vertexColor;\n" + "\n" + "#if defined(GL_TEXTURE_2D)\n" + " color = color * texture2D(diffuseMap, gl_TexCoord[0].st);\n" + "#endif\n" + "\n" + "\n" + " gl_FragColor = color;\n" + "}\n" + "\n"; diff --git a/src/osgUtil/shaders/shadergen_vert.cpp b/src/osgUtil/shaders/shadergen_vert.cpp new file mode 100644 index 000000000..08e8dfc8b --- /dev/null +++ b/src/osgUtil/shaders/shadergen_vert.cpp @@ -0,0 +1,44 @@ +char shadergen_vert[] = "// ShaderGen shader\n" + "// new version\n" + "#ifdef GL_ES\n" + " precision highp float;\n" + "#endif\n" + "\n" + "#pragma import_defines(GL_LIGHTING, GL_TEXTURE_2D, GL_FOG)\n" + "\n" + "#if defined(GL_LIGHTING)\n" + "varying vec3 normalDir;\n" + "varying vec3 lightDir;\n" + "#endif\n" + "\n" + "#if defined(GL_LIGHTING) || defined(GL_FOG)\n" + "varying vec3 viewDir;\n" + "#endif\n" + "\n" + "varying vec4 vertexColor;\n" + "\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = ftransform();\n" + "\n" + "#if defined(GL_TEXTURE_2D)\n" + " gl_TexCoord[0] = gl_MultiTexCoord0;\n" + "#endif\n" + "\n" + "#if defined(GL_LIGHTING) || defined(GL_FOG)\n" + " viewDir = -vec3(gl_ModelViewMatrix * gl_Vertex);\n" + "#endif\n" + "\n" + "#if defined(GL_LIGHTING)\n" + " normalDir = gl_NormalMatrix * gl_Normal;\n" + " vec4 lpos = gl_LightSource[0].position;\n" + " if (lpos.w == 0.0)\n" + " lightDir = lpos.xyz;\n" + " else\n" + " lightDir = lpos.xyz + viewDir;\n" + "#endif\n" + "\n" + " vertexColor = gl_Color;\n" + "}\n" + "\n"; From 57f2b1fa27671962601385167a5ccd90b85536b7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 14 Mar 2018 08:39:12 +0000 Subject: [PATCH 7/7] Standardized the MSCV INSTALL lines between applications and examples --- CMakeModules/OsgMacroUtils.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeModules/OsgMacroUtils.cmake b/CMakeModules/OsgMacroUtils.cmake index 506dd2225..fd00c026c 100644 --- a/CMakeModules/OsgMacroUtils.cmake +++ b/CMakeModules/OsgMacroUtils.cmake @@ -458,8 +458,8 @@ MACRO(SETUP_APPLICATION APPLICATION_NAME) ELSE(APPLE) INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION bin COMPONENT openscenegraph ) IF(MSVC) - INSTALL(FILES ${CMAKE_BINARY_DIR}/bin/${TARGET_NAME}${CMAKE_RELWITHDEBINFO_POSTFIX}.pdb DESTINATION bin COMPONENT openscenegraph CONFIGURATIONS RelWithDebInfo) - INSTALL(FILES ${CMAKE_BINARY_DIR}/bin/${TARGET_NAME}${CMAKE_DEBUG_POSTFIX}.pdb DESTINATION bin COMPONENT openscenegraph CONFIGURATIONS Debug) + INSTALL(FILES ${CMAKE_BINARY_DIR}/bin/${TARGET_TARGETNAME}${CMAKE_RELWITHDEBINFO_POSTFIX}.pdb DESTINATION bin COMPONENT openscenegraph CONFIGURATIONS RelWithDebInfo) + INSTALL(FILES ${CMAKE_BINARY_DIR}/bin/${TARGET_TARGETNAME}${CMAKE_DEBUG_POSTFIX}.pdb DESTINATION bin COMPONENT openscenegraph CONFIGURATIONS Debug) ENDIF(MSVC) ENDIF(APPLE) @@ -491,8 +491,8 @@ MACRO(SETUP_EXAMPLE EXAMPLE_NAME) ELSE(APPLE) INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION share/OpenSceneGraph/bin COMPONENT openscenegraph-examples ) IF(MSVC) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_TARGETNAME}${CMAKE_RELWITHDEBINFO_POSTFIX}.pdb DESTINATION share/OpenSceneGraph/bin COMPONENT openscenegraph-examples CONFIGURATIONS RelWithDebInfo) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_TARGETNAME}${CMAKE_DEBUG_POSTFIX}.pdb DESTINATION share/OpenSceneGraph/bin COMPONENT openscenegraph-examples CONFIGURATIONS Debug) + INSTALL(FILES ${CMAKE_BINARY_DIR}/bin/${TARGET_TARGETNAME}${CMAKE_RELWITHDEBINFO_POSTFIX}.pdb DESTINATION share/OpenSceneGraph/bin COMPONENT openscenegraph-examples CONFIGURATIONS RelWithDebInfo) + INSTALL(FILES ${CMAKE_BINARY_DIR}/bin/${TARGET_TARGETNAME}${CMAKE_DEBUG_POSTFIX}.pdb DESTINATION share/OpenSceneGraph/bin COMPONENT openscenegraph-examples CONFIGURATIONS Debug) ENDIF(MSVC) ENDIF(APPLE)