/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #ifndef OSGEARTH_SHADER_UTILS_H #define OSGEARTH_SHADER_UTILS_H 1 #include #include #include #include #include #include #include #include #include #include #include namespace osgEarth { /** * ShaderPolicy encodes general behavior when deciding how to * employ shaders in certain situations */ enum ShaderPolicy { SHADERPOLICY_DISABLE, SHADERPOLICY_GENERATE, SHADERPOLICY_INHERIT }; } namespace osgEarth { namespace Util { struct OSGEARTH_EXPORT ShaderUtils { // Installs a default, one-texture shader on a stateset // for basic rendering. static void installDefaultShader(osg::StateSet*); }; /** * Preprocesses GLES shader source to include our osg_LightProducts and osg_LightSourceParameters * definitions and uniforms. */ class OSGEARTH_EXPORT ShaderPreProcessor { public: static void runPre(std::string& source); static void runPost(osg::Shader* shader); struct PreCallbackInfo { osg::observer_ptr host; std::function function; }; struct PostCallbackInfo { osg::observer_ptr host; std::function function; }; static std::unordered_map< UID, PreCallbackInfo> _pre_callbacks; static std::unordered_map< UID, PostCallbackInfo> _post_callbacks; }; /** * Helper class for dealing with array uniforms. Array uniform naming works * differently on different drivers (ATI vs NVIDIA), so this class helps mitigate * those differences. */ class OSGEARTH_EXPORT ArrayUniform // : public osg::Referenced { public: /** Empty array uniform */ ArrayUniform() { } /** * Creates or retrieves a named uniform array. */ ArrayUniform( const std::string& name, osg::Uniform::Type type, osg::StateSet* stateSet, unsigned size =1 ); /** dtor */ virtual ~ArrayUniform() { } void attach( const std::string& name, osg::Uniform::Type type, osg::StateSet* stateSet, unsigned size =1 ); void detach(); void setElement( unsigned index, int value ); void setElement( unsigned index, unsigned value ); void setElement( unsigned index, bool value ); void setElement( unsigned index, float value ); void setElement( unsigned index, const osg::Matrixf& value ); void setElement( unsigned index, const osg::Vec3f& value ); void setElement( unsigned index, const osg::Vec4f& value); bool getElement( unsigned index, int& out_value ) const; bool getElement( unsigned index, unsigned& out_value ) const; bool getElement( unsigned index, bool& out_value ) const; bool getElement( unsigned index, float& out_value ) const; bool getElement( unsigned index, osg::Matrixf& out_value ) const; bool getElement( unsigned index, osg::Vec3f& out_value ) const; bool getElement( unsigned index, osg::Vec4f& out_value) const; bool isValid() const { return _uniform.valid() && _uniformAlt.valid(); } int getNumElements() const { return isValid() ? _uniform->getNumElements() : -1; } bool isDirty() const { return (_uniform.valid() && _uniform->getModifiedCount() > 0) || (_uniformAlt.valid() && _uniformAlt->getModifiedCount() > 0); } private: osg::ref_ptr _uniform; osg::ref_ptr _uniformAlt; osg::observer_ptr _stateSet; void ensureCapacity( unsigned newSize ); }; /** * Cull callback that installs a range (distance to view point) uniform * in the State based on the bounding center of the node being culled. * The actual name of the range uniform can is returned by * ShaderFactory::getRangeUniformName(). */ class OSGEARTH_EXPORT RangeUniformCullCallback : public osg::NodeCallback { public: RangeUniformCullCallback(); void operator()(osg::Node*, osg::NodeVisitor* nv); // testing void setDump(bool v) { _dump = true; } private: osg::ref_ptr _stateSet; osg::ref_ptr _uniform; bool _dump; }; /** * Shader that will discard fragments whose alpha component falls below * the specified threshold. */ class OSGEARTH_EXPORT DiscardAlphaFragments { public: void install(osg::StateSet* ss, float minAlpha) const; void uninstall(osg::StateSet* ss) const; }; /** * Class to parse messages from an info log. */ class OSGEARTH_EXPORT ShaderInfoLog { public: ShaderInfoLog( const osg::Program* program, const std::string& log); void dumpErrors( osg::State&) const; private: osg::ref_ptr _program; std::string _log; struct Message { unsigned line; unsigned column; std::string message; }; }; } } #endif // OSGEARTH_SHADER_UTILS_H