161 lines
5.8 KiB
C++
161 lines
5.8 KiB
C++
/* -*-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.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
#ifndef OSGEARTH_LIGHTING_H
|
|
#define OSGEARTH_LIGHTING_H 1
|
|
|
|
#include <osgEarth/Common>
|
|
#include <osgEarth/Threading>
|
|
#include <osg/Node>
|
|
#include <osg/NodeVisitor>
|
|
#include <osg/LightSource>
|
|
#include <osg/Light>
|
|
#include <osg/Material>
|
|
#include <set>
|
|
|
|
// Use this with StateSet::setDefine to toggle lighting in osgEarth lighting shaders.
|
|
#define OE_LIGHTING_DEFINE "OE_LIGHTING"
|
|
|
|
namespace osgEarth
|
|
{
|
|
struct OSGEARTH_EXPORT Lighting
|
|
{
|
|
//! Sets the lighting mode on a stateset
|
|
static void set(osg::StateSet* stateSet, osg::StateAttribute::OverrideValue value);
|
|
|
|
//! Removed the lighting mode from a stateset
|
|
static void remove(osg::StateSet* stateSet);
|
|
|
|
//! Installs a default material on a stateset
|
|
static void installDefaultMaterial(osg::StateSet* stateSet);
|
|
};
|
|
|
|
/**
|
|
* Traverses a graph, looking for Lights and Materials, and generates either static
|
|
* uniforms or dynamic cull callbacks for them so they will work with core profile
|
|
* shaders. (This is necessary for GL3+ core, OSX, Mesa etc. that don't support
|
|
* compatibility mode.)
|
|
*/
|
|
class OSGEARTH_EXPORT GenerateGL3LightingUniforms : public osg::NodeVisitor
|
|
{
|
|
public:
|
|
GenerateGL3LightingUniforms();
|
|
|
|
public: // osg::NodeVisitor
|
|
virtual void apply(osg::Node& node);
|
|
virtual void apply(osg::LightSource& node);
|
|
|
|
protected:
|
|
std::set<osg::StateSet*> _statesets;
|
|
|
|
template<typename T> bool alreadyInstalled(osg::Callback* cb) const {
|
|
return !cb ? false : dynamic_cast<T*>(cb)!=0L ? true : alreadyInstalled<T>(cb->getNestedCallback());
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Material that will work in both FFP and non-FFP mode, by using the uniform
|
|
* osg_FrontMaterial in place of gl_FrontMaterial.
|
|
*/
|
|
class OSGEARTH_EXPORT MaterialGL3 : public osg::Material
|
|
{
|
|
public:
|
|
MaterialGL3() : osg::Material() { }
|
|
MaterialGL3(const MaterialGL3& mat, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) : osg::Material(mat, copyop) {}
|
|
MaterialGL3(const osg::Material& mat) : osg::Material(mat) { }
|
|
|
|
META_StateAttribute(osgEarth, MaterialGL3, MATERIAL);
|
|
|
|
void apply(osg::State&) const override;
|
|
};
|
|
|
|
/**
|
|
* StateAttributeCallback that will update osg::Material properties as Uniforms
|
|
*/
|
|
class OSGEARTH_EXPORT MaterialCallback : public osg::StateAttributeCallback
|
|
{
|
|
public:
|
|
virtual void operator() (osg::StateAttribute* attr, osg::NodeVisitor* nv);
|
|
};
|
|
|
|
/**
|
|
* Light that will work in both FFP and non-FFP mode.
|
|
* To use this, find a LightSource and replace the Light with a LightGL3.
|
|
* Then install the LightSourceGL3UniformGenerator cull callback on the LightSource.
|
|
*/
|
|
class OSGEARTH_EXPORT LightGL3 : public osg::Light
|
|
{
|
|
public:
|
|
LightGL3() : osg::Light(), _enabled(true) { }
|
|
LightGL3(int lightnum) : osg::Light(lightnum), _enabled(true) { }
|
|
LightGL3(const LightGL3& light, const osg::CopyOp& copyop =osg::CopyOp::SHALLOW_COPY)
|
|
: osg::Light(light, copyop), _enabled(light._enabled) {}
|
|
LightGL3(const osg::Light& light)
|
|
: osg::Light(light), _enabled(true) { }
|
|
|
|
void setEnabled(bool value) { _enabled = value; }
|
|
bool getEnabled() const { return _enabled; }
|
|
|
|
virtual osg::Object* cloneType() const { return new LightGL3(_lightnum); }
|
|
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new LightGL3(*this,copyop); }
|
|
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const LightGL3 *>(obj)!=NULL; }
|
|
virtual const char* libraryName() const { return "osgEarth"; }
|
|
virtual const char* className() const { return "LightGL3"; }
|
|
virtual Type getType() const { return LIGHT; }
|
|
|
|
virtual void apply(osg::State&) const;
|
|
|
|
protected:
|
|
bool _enabled;
|
|
};
|
|
|
|
/**
|
|
* Cull callback that will install Light uniforms based on the Light in a LightSource.
|
|
* Install this directly on the LightSource node.
|
|
*/
|
|
class OSGEARTH_EXPORT LightSourceGL3UniformGenerator : public osg::NodeCallback
|
|
{
|
|
public:
|
|
LightSourceGL3UniformGenerator();
|
|
|
|
/**
|
|
* Creates and installs Uniforms on the stateset for the Light components
|
|
* of the Light that are non-positional (everything but the position and direction)
|
|
*/
|
|
void generateNonPositionalData(osg::StateSet* ss, osg::Light* light);
|
|
|
|
public: // osg::NodeCallback
|
|
|
|
bool run(osg::Object* obj, osg::Object* data);
|
|
|
|
public: // osg::Object
|
|
|
|
void resizeGLBufferObjects(unsigned maxSize);
|
|
void releaseGLObjects(osg::State* state) const;
|
|
|
|
mutable std::vector<osg::ref_ptr<osg::StateSet> > _statesets;
|
|
mutable std::mutex _statesetsMutex;
|
|
};
|
|
}
|
|
|
|
#endif // OSGEARTH_LIGHTING_H
|