DYT/Tool/OpenSceneGraph-3.6.5/include/osgEarth/Lighting
2024-12-25 07:49:36 +08:00

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