Added missing osgFX files.

This commit is contained in:
Robert Osfield 2003-08-26 22:09:15 +00:00
parent 2c4c2ad068
commit f7d7a746f3
15 changed files with 1438 additions and 0 deletions

View File

@ -0,0 +1,122 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_ANISOTROPICLIGHTING_
#define OSGFX_ANISOTROPICLIGHTING_
#include <osgFX/Export>
#include <osgFX/Effect>
#include <osg/ref_ptr>
#include <osg/Texture2D>
namespace osgFX
{
/**
This single-pass effect implements a sort of anisotropic
lighting that replaces the standard OpenGL lighting model.
The final color of vertices is not computed directly, it is
the result of a texture lookup on a user-supplied lighting
image map. A vertex program is used to compute the s and t
texture coordinates as follows: s = (N dot H) ; t = (N dot L)
where N is the vertex normal, L is the light-to-vertex vector,
H is the half-way vector. This is a good example of how you
can use the State::getInitialViewMatrix() method to retrieve
the view matrix and perform view-dependant effects without
fakes of any kind.
This effect requires the ARB_vertex_program extension.
*/
class OSGFX_EXPORT AnisotropicLighting: public Effect {
public:
AnisotropicLighting();
AnisotropicLighting(const AnisotropicLighting &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
META_Effect(osgFX, AnisotropicLighting,
"Anisotropic Lighting",
"This single-pass effect implements a sort of anisotropic "
"lighting that replaces the standard OpenGL lighting model.\n"
"The final color of vertices is not computed directly, it is "
"the result of a texture lookup on a user-supplied lighting "
"image map. A vertex program is used to compute the s and t "
"texture coordinates as follows: s = (N dot H) ; t = (N dot L) "
"where N is the vertex normal, L is the light-to-vertex vector, "
"H is the half-way vector. This is a good example of how you "
"can use the State::getInitialViewMatrix() method to retrieve "
"the view matrix and perform view-dependant effects without "
"fakes of any kind.\n"
"This effect requires the ARB_vertex_program extension.",
"Marco Jez");
/** get the lighting map */
inline osg::Image *getLightingMap();
/** get the const lighting map */
inline const osg::Image *getLightingMap() const;
/** set the lighting map */
inline void setLightingMap(osg::Image *image);
/** get the OpenGL light number */
inline int getLightNumber() const;
/** set the OpenGL light number that will be used in lighting computations */
inline void setLightNumber(int n);
protected:
virtual ~AnisotropicLighting() {}
AnisotropicLighting &operator=(const AnisotropicLighting &) { return *this; }
bool define_techniques();
private:
int lightnum_;
osg::ref_ptr<osg::Texture2D> texture_;
};
// INLINE METHODS
inline osg::Image *AnisotropicLighting::getLightingMap()
{
return texture_->getImage();
}
inline const osg::Image *AnisotropicLighting::getLightingMap() const
{
return texture_->getImage();
}
inline void AnisotropicLighting::setLightingMap(osg::Image *image)
{
texture_->setImage(image);
}
inline int AnisotropicLighting::getLightNumber() const
{
return lightnum_;
}
inline void AnisotropicLighting::setLightNumber(int n)
{
lightnum_ = n;
dirtyTechniques();
}
}
#endif

121
include/osgFX/Cartoon Normal file
View File

@ -0,0 +1,121 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_CARTOON_
#define OSGFX_CARTOON_
#include <osgFX/Export>
#include <osgFX/Effect>
#include <osg/Material>
#include <osg/LineWidth>
namespace osgFX
{
/**
This effect implements a technique called 'Cel-Shading' to produce a
cartoon-style (non photorealistic) rendering. Two passes are required:
the first one draws solid surfaces, the second one draws the outlines.
A vertex program is used to setup texture coordinates for a sharp lighting
texture on unit 0 which is generated on-the-fly.
This effect requires the ARB_vertex_program extension.
*/
class OSGFX_EXPORT Cartoon: public Effect {
public:
Cartoon();
Cartoon(const Cartoon &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
// effect class informations
META_Effect(
osgFX,
Cartoon,
"Cartoon",
"This effect implements a technique called 'Cel-Shading' to produce a "
"cartoon-style (non photorealistic) rendering. Two passes are required: "
"the first one draws solid surfaces, the second one draws the outlines. "
"A vertex program is used to setup texture coordinates for a sharp lighting "
"texture on unit 0 which is generated on-the-fly.\n"
"This effect requires the ARB_vertex_program extension.",
"Marco Jez");
/** get the outline color */
inline const osg::Vec4 &getOutlineColor() const;
/** set the outline color */
inline void setOutlineColor(const osg::Vec4 &color);
/** get the outline line width */
inline float getOutlineLineWidth() const;
/** set the outline line width */
inline void setOutlineLineWidth(float w);
/** get the OpenGL light number */
inline int getLightNumber() const;
/** set the OpenGL light number that will be used in lighting computations */
inline void setLightNumber(int n);
protected:
virtual ~Cartoon() {}
Cartoon &operator=(const Cartoon &) { return *this; }
bool define_techniques();
private:
osg::ref_ptr<osg::Material> wf_mat_;
osg::ref_ptr<osg::LineWidth> wf_lw_;
int lightnum_;
};
// INLINE METHODS
inline const osg::Vec4 &Cartoon::getOutlineColor() const
{
return wf_mat_->getEmission(osg::Material::FRONT_AND_BACK);
}
inline void Cartoon::setOutlineColor(const osg::Vec4 &color)
{
wf_mat_->setEmission(osg::Material::FRONT_AND_BACK, color);
}
inline float Cartoon::getOutlineLineWidth() const
{
return wf_lw_->getWidth();
}
inline void Cartoon::setOutlineLineWidth(float w)
{
wf_lw_->setWidth(w);
}
inline int Cartoon::getLightNumber() const
{
return lightnum_;
}
inline void Cartoon::setLightNumber(int n)
{
lightnum_ = n;
dirtyTechniques();
}
}
#endif

246
include/osgFX/Effect Normal file
View File

@ -0,0 +1,246 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_EFFECT_
#define OSGFX_EFFECT_
#include <osgFX/Export>
#include <osgFX/Technique>
#include <osg/buffered_value>
#include <osg/ref_ptr>
#include <osg/Node>
#include <osg/Group>
#include <osg/Geode>
#include <osg/OccluderNode>
#include <vector>
/**
An helper macro that defines the methods like effectName() and effectDescription()
making them return the strings passed as parameters, after the usual library name
and class name.
*/
#define META_Effect(library, classname, effectname, effectdescription, effectauthor) \
META_Node(library, classname) \
virtual const char *effectName() const { return effectname; } \
virtual const char *effectDescription() const { return effectdescription; } \
virtual const char *effectAuthor() const { return effectauthor; }
namespace osgFX
{
/**
The base class for special effects. An effect is basically a collection of
state attributes and an interface for configuring them in a predefined
fashion. The Effect class does more however, as it handles multipass
rendering transparently and it allows more than one "technique" to be
defined. Each technique tries to implement the effect in a different way,
often using different OpenGL extensions. The active technique can be
selected either manually, with selectTechnique(), or automatically, in which
case the first technique that is supported by all active rendering contexts
is chosen.
If you are an Effect user, then simply use it as a single-child group.
Create an instance of your desired effect, add it to your scene graph (it
is a Node) and call its setChild() method to set its child node as you
would do with a Group.
If you are an Effect developer, you will have to implement the method
define_techniques() to define the different techniques that can be used
for obtaining the desired effect. In define_techniques() you will usually
create one or more instances of custom classes derived from Technique and
you will add them to the effect with addTechnique(). The order is important:
techniques added first will have higher priority and will be used first as
soon as all rendering contexts support it.
*/
class OSGFX_EXPORT Effect: public osg::Node {
public:
Effect();
Effect(const Effect &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
virtual inline bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const Effect *>(obj) != NULL; }
virtual inline const char *libraryName() const { return "osgFX"; }
virtual inline const char *className() const { return "Effect"; }
/** get the name of this effect */
virtual const char *effectName() const = 0;
/** get a brief description of this effect */
virtual const char *effectDescription() const = 0;
/** get the effect author's name */
virtual const char *effectAuthor() const = 0;
/** get whether the effect is enabled or not */
inline bool getEnabled() const;
/** set whether the effect is enabled or not */
inline void setEnabled(bool v);
/**
optional: set effect parameters to produce a visually significant
result to be used in demo applications like osgfxbrowser. Default
is to do nothing.
*/
inline virtual void setUpDemo() {}
/** get the const child node */
inline const osg::Node *getChild() const;
/** get the child node */
inline osg::Node *getChild();
/** set the child node */
inline void setChild(osg::Node *child);
/** get the number of techniques defined for this effect */
inline int getNumTechniques() const;
/** get the i-th technique */
inline Technique *getTechnique(int i);
/** get the i-th const technique */
inline const Technique *getTechnique(int i) const;
/** get the index of the currently selected technique */
inline int getSelectedTechnique() const;
enum TechniqueSelection {
AUTO_DETECT = -1
};
/** select a technique or enable automatic detection */
inline void selectTechnique(int i = AUTO_DETECT);
virtual void traverse(osg::NodeVisitor &nv);
protected:
virtual ~Effect() {}
Effect &operator=(const Effect &) { return *this; }
virtual bool computeBound() const;
/** force rebuilding of techniques on next traversal */
inline void dirtyTechniques();
/** add a technique to the effect */
inline void addTechnique(Technique *tech);
/**
abstract method to be implemented in derived classes; its purpose
if to create the techniques that can be used for obtaining the
desired effect. You will usually call addTechnique() inside
this method.
*/
virtual bool define_techniques() = 0;
private:
friend class Validator;
bool enabled_;
typedef std::vector<osg::ref_ptr<Technique> > Technique_list;
Technique_list techs_;
mutable osg::buffered_value<int> sel_tech_;
// use int instead of bool to avoid errors
mutable osg::buffered_value<int> tech_selected_;
int global_sel_tech_;
bool techs_defined_;
osg::ref_ptr<osg::Node> child_;
osg::ref_ptr<osg::Geode> dummy_for_validation_;
void build_dummy_node();
};
// INLINE METHODS
inline bool Effect::getEnabled() const
{
return enabled_;
}
inline void Effect::setEnabled(bool v)
{
enabled_ = v;
}
inline const osg::Node *Effect::getChild() const
{
return child_.get();
}
inline osg::Node *Effect::getChild()
{
return child_.get();
}
inline void Effect::setChild(osg::Node *child)
{
child_ = child;
setNumChildrenRequiringUpdateTraversal(0);
setNumChildrenWithCullingDisabled(0);
setNumChildrenWithOccluderNodes(0);
if (child) {
if (child->getNumChildrenRequiringUpdateTraversal() > 0 || child->getUpdateCallback())
setNumChildrenRequiringUpdateTraversal(1);
if (child->getNumChildrenWithCullingDisabled() > 0 || !child->getCullingActive())
setNumChildrenWithCullingDisabled(1);
if (child->getNumChildrenWithOccluderNodes() > 0 || dynamic_cast<osg::OccluderNode *>(child))
setNumChildrenWithOccluderNodes(1);
}
dirtyBound();
}
inline int Effect::getNumTechniques() const
{
return static_cast<int>(techs_.size());
}
inline Technique *Effect::getTechnique(int i)
{
return techs_[i].get();
}
inline const Technique *Effect::getTechnique(int i) const
{
return techs_[i].get();
}
inline int Effect::getSelectedTechnique() const
{
return global_sel_tech_;
}
inline void Effect::selectTechnique(int i)
{
global_sel_tech_ = i;
}
inline void Effect::addTechnique(Technique *tech)
{
techs_.push_back(tech);
}
inline void Effect::dirtyTechniques()
{
techs_defined_ = false;
}
}
#endif

28
include/osgFX/Export Normal file
View File

@ -0,0 +1,28 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_EXPORT_
#define OSGFX_EXPORT_
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
# ifdef OSGFX_LIBRARY
# define OSGFX_EXPORT __declspec(dllexport)
# else
# define OSGFX_EXPORT __declspec(dllimport)
# endif /* OSGFX_LIBRARY */
#else
# define OSGFX_EXPORT
#endif
#endif

80
include/osgFX/Registry Normal file
View File

@ -0,0 +1,80 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_REGISTRY_
#define OSGFX_REGISTRY_
#include <osgFX/Export>
#include <osgFX/Effect>
#include <osg/ref_ptr>
#include <map>
#include <string>
namespace osgFX
{
class OSGFX_EXPORT Registry {
public:
struct Proxy {
Proxy(const Effect *effect)
{
Registry::instance()->registerEffect(effect);
}
};
typedef std::map<std::string, osg::ref_ptr<const Effect> > Effect_map;
inline static Registry *instance();
inline void registerEffect(const Effect *effect);
inline const Effect_map &getEffectMap() const;
protected:
// Registry is a singleton; constructor and destructor must be protected
Registry();
~Registry() {}
private:
static Registry *instance_;
Effect_map effects_;
};
// INLINE METHODS
inline Registry *Registry::instance()
{
if (!instance_) {
instance_ = new Registry;
}
return instance_;
}
inline const Registry::Effect_map &Registry::getEffectMap() const
{
return effects_;
}
inline void Registry::registerEffect(const Effect *effect)
{
effects_[effect->effectName()] = effect;
}
}
#endif

101
include/osgFX/Scribe Normal file
View File

@ -0,0 +1,101 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_SCRIBE_
#define OSGFX_SCRIBE_
#include <osgFX/Export>
#include <osgFX/Effect>
#include <osg/Material>
#include <osg/LineWidth>
namespace osgFX
{
/**
This is a two-passes effect; the first pass renders the subgraph as usual
while the second pass switches to wireframe mode, sets up lighting and
material to obtain a fixed (user-defined) color and then renders the subgraph.
This effect uses the PolygonOffset attribute to avoid Z-fighting, so it
requires at least OpenGL version 1.1.
*/
class OSGFX_EXPORT Scribe: public Effect {
public:
Scribe();
Scribe(const Scribe &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
// effect class informations
META_Effect(
osgFX,
Scribe,
"Scribe",
"This is a two-passes effect; the first pass renders the subgraph as usual "
"while the second pass switches to wireframe mode, sets up lighting and "
"material to obtain a fixed (user-defined) color and then renders the subgraph.\n"
"This effect uses the PolygonOffset attribute to avoid Z-fighting, so it "
"requires at least OpenGL version 1.1.",
"Marco Jez");
/** get the wireframe color */
inline const osg::Vec4 &getWireframeColor() const;
/** set the wireframe color */
inline void setWireframeColor(const osg::Vec4 &color);
/** get the wireframe line width */
inline float getWireframeLineWidth() const;
/** set the wireframe line width */
inline void setWireframeLineWidth(float w);
protected:
virtual ~Scribe() {}
Scribe &operator=(const Scribe &) { return *this; }
bool define_techniques();
private:
osg::ref_ptr<osg::Material> wf_mat_;
osg::ref_ptr<osg::LineWidth> wf_lw_;
};
// INLINE METHODS
inline const osg::Vec4 &Scribe::getWireframeColor() const
{
return wf_mat_->getEmission(osg::Material::FRONT_AND_BACK);
}
inline void Scribe::setWireframeColor(const osg::Vec4 &color)
{
wf_mat_->setEmission(osg::Material::FRONT_AND_BACK, color);
}
inline float Scribe::getWireframeLineWidth() const
{
return wf_lw_->getWidth();
}
inline void Scribe::setWireframeLineWidth(float w)
{
wf_lw_->setWidth(w);
}
}
#endif

View File

@ -0,0 +1,138 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_SPECULARHIGHLIGHTS_
#define OSGFX_SPECULARHIGHLIGHTS_
#include <osgFX/Export>
#include <osgFX/Effect>
namespace osgFX
{
/**
This effect applies additive specular highlights at fragment level (instead
of OpenGL's vertex-level lighting) by using a cube map and reflective texgen.
A texture matrix is computed to rotate the cube map automatically; this makes
the specular effect consistent with respect to view direction and light position.
The user can choose which light should be used to compute the texture matrix.
This effect requires the GL_ARB_texture_env_add extension and one of the cube map
extensions (GL_EXT_texture_cube_map, GL_ARB_texture_cube_map or OpenGL v1.3).
*/
class OSGFX_EXPORT SpecularHighlights: public Effect {
public:
SpecularHighlights();
SpecularHighlights(const SpecularHighlights &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
META_Effect(osgFX, SpecularHighlights,
"Specular Highlights",
"This effect applies additive specular highlights at fragment level (instead "
"of OpenGL's vertex-level lighting) by using a cube map and reflective texgen. "
"A texture matrix is computed to rotate the cube map automatically; this makes "
"the specular effect consistent with respect to view direction and light position. "
"The user can choose which light should be used to compute the texture matrix.\n"
"This effect requires the GL_ARB_texture_env_add extension and one of the cube map "
"extensions (GL_EXT_texture_cube_map, GL_ARB_texture_cube_map or OpenGL v1.3).",
"Marco Jez");
/** get the OpenGL light number */
inline int getLightNumber() const;
/** set the OpenGL light number that will be used in lighting computations */
inline void setLightNumber(int n);
/** get the texture unit number */
inline int getTextureUnit() const;
/** set the texture unit that will be used to apply the cube map */
inline void setTextureUnit(int n);
/** get the specular color */
inline const osg::Vec4 &getSpecularColor() const;
/** set the specular color */
inline void setSpecularColor(const osg::Vec4 &color);
/** get the specular exponent */
inline float getSpecularExponent() const;
/** set the specular exponent */
inline void setSpecularExponent(float e);
protected:
virtual ~SpecularHighlights() {}
SpecularHighlights &operator=(const SpecularHighlights &) { return *this; }
bool define_techniques();
private:
int lightnum_;
int unit_;
osg::Vec4 color_;
float sexp_;
};
// INLINE METHODS
inline int SpecularHighlights::getLightNumber() const
{
return lightnum_;
}
inline void SpecularHighlights::setLightNumber(int n)
{
lightnum_ = n;
dirtyTechniques();
}
inline int SpecularHighlights::getTextureUnit() const
{
return unit_;
}
inline void SpecularHighlights::setTextureUnit(int n)
{
unit_ = n;
dirtyTechniques();
}
inline const osg::Vec4 &SpecularHighlights::getSpecularColor() const
{
return color_;
}
inline void SpecularHighlights::setSpecularColor(const osg::Vec4 &color)
{
color_ = color;
dirtyTechniques();
}
inline float SpecularHighlights::getSpecularExponent() const
{
return sexp_;
}
inline void SpecularHighlights::setSpecularExponent(float e)
{
sexp_ = e;
dirtyTechniques();
}
}
#endif

188
include/osgFX/Technique Normal file
View File

@ -0,0 +1,188 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_TECHNIQUE_
#define OSGFX_TECHNIQUE_
#include <osgFX/Export>
#include <osg/Referenced>
#include <osg/State>
#include <osg/Group>
#include <osg/NodeVisitor>
#include <vector>
#include <string>
/**
An helper macro that defines the methods techniqueName() and
techniqueDescription() making them return the strings passed as parameters.
*/
#define META_Technique(name, description) \
inline virtual const char *techniqueName() { return name; } \
inline virtual const char *techniqueDescription() { return description; }
namespace osgFX
{
/**
This is the base class for effect techniques. A technique represents one
of the possible ways to implement a special effect. This base class is
abstract, you will have to subclass your own techniques for your custom
effects.
Derived classes will have to implement the define_passes() method to
configure the rendering pass(es) that make up the technique. Usually
you will create one StateSet object for each rendering pass and then
you'll call addPass(stateset).
The validate() method should return true if the technique is valid within
the current rendering context, false otherwise. The default implementation
of validate() calls getRequiredExtensions() and tests whether all required
extensions are supported or not, returning false if at least one extension
is not supported.
*/
class OSGFX_EXPORT Technique: public osg::Referenced {
public:
Technique();
/** get the name of this technique */
virtual const char *techniqueName() { return "Default"; }
/** get a brief description of this technique */
virtual const char *techniqueDescription() { return "This is the default technique"; }
/**
collect the GL extension strings which are required for this technique
to work properly. This method is called from the default implementation
of validate().
*/
virtual void getRequiredExtensions(std::vector<std::string> & /*extensions*/) const {};
/**
tests whether this technique is valid for the current rendering context.
The default behavior is to call getRequiredExtensions() and check for
extension availability.
*/
virtual bool validate(osg::State &) const;
/** get the number of rendering passes defined in this technique */
inline int getNumPasses() const;
/** get the Group object associated to the i-th pass */
inline osg::Group *getPassGroup(int i);
/** get the const Group object associated to the i-th pass */
inline const osg::Group *getPassGroup(int i) const;
/** get the StateSet object associated to the i-th pass */
inline osg::StateSet *getPassStateSet(int i);
/** get the const StateSet object associated to the i-th pass */
inline const osg::StateSet *getPassStateSet(int i) const;
/**
traverses the child nodes with multipass if necessary.
Don't call this method directly as it is called by osgFX::Effect
*/
virtual void accept(osg::NodeVisitor &nv, osg::Node *child);
protected:
Technique(const Technique &): osg::Referenced() {} // copying is nonsense ;)
virtual ~Technique() {}
Technique &operator=(const Technique &) { return *this; }
/** force rebuilding of pass nodes on next traversal */
inline void dirtyPasses();
/** optional: return a node that overrides the child node on a specified pass */
inline virtual osg::Node *getOverrideChild(int) { return 0; }
/** create a new pass node, add it to the technique and associate a StateSet */
void addPass(osg::StateSet *ss = 0);
/**
add a new pass to the technique specifying an user-defined pass node.
You should call this version of addPass() only when you need to gain direct
control over the pass node (i.e. for setting up a cull callback); otherwise
please use addPass(StateSet*) and let the class create the pass node for you.
*/
void addPass(osg::Group *pass);
/**
get the control node which holds the user's subgraph.
You may want to do something on it like applying a cull callback.
*/
inline osg::Group *getControlNode();
/** get the const control node which holds the user's subgraph */
inline const osg::Group *getControlNode() const;
/**
define the rendering passes that make up this technique. You must
implement this method in derived classes to add the required passes.
*/
virtual void define_passes() = 0;
private:
bool passes_defined_;
osg::ref_ptr<osg::Group> control_node_;
osg::ref_ptr<osg::Node> prev_child_;
};
// INLINE METHODS
inline int Technique::getNumPasses() const
{
return static_cast<int>(control_node_->getNumChildren());
}
inline osg::Group *Technique::getPassGroup(int i)
{
return static_cast<osg::Group *>(control_node_->getChild(i));
}
inline const osg::Group *Technique::getPassGroup(int i) const
{
return static_cast<const osg::Group *>(control_node_->getChild(i));
}
inline osg::StateSet *Technique::getPassStateSet(int i)
{
return control_node_->getChild(i)->getStateSet();
}
inline const osg::StateSet *Technique::getPassStateSet(int i) const
{
return control_node_->getChild(i)->getStateSet();
}
inline osg::Group *Technique::getControlNode()
{
return control_node_.get();
}
inline const osg::Group *Technique::getControlNode() const
{
return control_node_.get();
}
inline void Technique::dirtyPasses()
{
passes_defined_ = false;
}
}
#endif

73
include/osgFX/Validator Normal file
View File

@ -0,0 +1,73 @@
/* -*-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.
*/
//osgFX - Copyright (C) 2003 Marco Jez
#ifndef OSGFX_VALIDATOR_
#define OSGFX_VALIDATOR_
#include <osgFX/Export>
#include <osg/ref_ptr>
#include <osg/StateAttribute>
#include <vector>
namespace osgFX
{
// forward declaration
class Effect;
/**
This class is used internally by osgFX::Effect to choose between different
techniques dynamically. The apply() method will call each technique's
validate() method and store the results in a buffered array. The Effect
class will then choose the first technique that could be validated in all
active rendering contexts.
*/
class OSGFX_EXPORT Validator: public osg::StateAttribute {
public:
Validator();
Validator(Effect *effect);
Validator(const Validator &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
META_StateAttribute(osgFX, Validator, 0x56616C69);
void apply(osg::State &state) const;
inline int compare(const osg::StateAttribute &sa) const;
protected:
virtual ~Validator() {}
Validator &operator=(const Validator &) { return *this; }
private:
mutable osg::ref_ptr<Effect> effect_;
};
// INLINE METHODS
inline int Validator::compare(const osg::StateAttribute &sa) const
{
const Validator *v = dynamic_cast<const Validator *>(&sa);
if (!v) return -1;
if (effect_.get() < v->effect_.get()) return -1;
if (effect_.get() > v->effect_.get()) return 1;
return 0;
}
}
#endif

View File

@ -0,0 +1,18 @@
TOPDIR = ../../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
IO_AnisotropicLighting.cpp\
IO_Cartoon.cpp\
IO_Scribe.cpp\
IO_SpecularHighlights.cpp\
IO_Effect.cpp\
LIBS += -losgFX $(OSG_LIBS) $(OTHER_LIBS)
TARGET_BASENAME = osgFX
include $(TOPDIR)/Make/cygwin_plugin_def
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,59 @@
#include <osgFX/AnisotropicLighting>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
bool AnisotropicLighting_readLocalData(osg::Object &obj, osgDB::Input &fr);
bool AnisotropicLighting_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
osgDB::RegisterDotOsgWrapperProxy AnisotropicLighting_Proxy
(
new osgFX::AnisotropicLighting,
"osgFX::AnisotropicLighting",
"Object Node osgFX::Effect osgFX::AnisotropicLighting",
AnisotropicLighting_readLocalData,
AnisotropicLighting_writeLocalData
);
bool AnisotropicLighting_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgFX::AnisotropicLighting &myobj = static_cast<osgFX::AnisotropicLighting &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("lightNumber")) {
int n;
if (fr[1].getInt(n)) {
myobj.setLightNumber(n);
fr += 2;
itAdvanced = true;
}
}
if (fr[0].matchWord("lightingMapFileName") && fr[1].isString()) {
osg::Image *lmap = fr.readImage(fr[1].getStr());
if (lmap) {
myobj.setLightingMap(lmap);
}
fr += 2;
itAdvanced = true;
}
return itAdvanced;
}
bool AnisotropicLighting_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgFX::AnisotropicLighting &myobj = static_cast<const osgFX::AnisotropicLighting &>(obj);
fw.indent() << "lightNumber " << myobj.getLightNumber() << "\n";
const osg::Image *lmap = myobj.getLightingMap();
if (lmap) {
if (!lmap->getFileName().empty()) {
fw.indent() << "lightingMapFileName \"" << lmap->getFileName() << "\"\n";
}
}
return true;
}

View File

@ -0,0 +1,64 @@
#include <osgFX/Cartoon>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
bool Cartoon_readLocalData(osg::Object &obj, osgDB::Input &fr);
bool Cartoon_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
osgDB::RegisterDotOsgWrapperProxy Cartoon_Proxy
(
new osgFX::Cartoon,
"osgFX::Cartoon",
"Object Node osgFX::Effect osgFX::Cartoon",
Cartoon_readLocalData,
Cartoon_writeLocalData
);
bool Cartoon_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgFX::Cartoon &myobj = static_cast<osgFX::Cartoon &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("lightNumber")) {
int n;
if (fr[1].getInt(n)) {
myobj.setLightNumber(n);
fr += 2;
itAdvanced = true;
}
}
if (fr[0].matchWord("outlineColor")) {
osg::Vec4 w;
if (fr[1].getFloat(w.x()) && fr[2].getFloat(w.y()) &&
fr[3].getFloat(w.z()) && fr[4].getFloat(w.w())) {
myobj.setOutlineColor(w);
fr += 5;
itAdvanced = true;
}
}
if (fr[0].matchWord("outlineLineWidth")) {
float f;
if (fr[1].getFloat(f)) {
myobj.setOutlineLineWidth(f);
fr += 2;
itAdvanced = true;
}
}
return itAdvanced;
}
bool Cartoon_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgFX::Cartoon &myobj = static_cast<const osgFX::Cartoon &>(obj);
fw.indent() << "lightNumber " << myobj.getLightNumber() << "\n";
fw.indent() << "outlineColor " << myobj.getOutlineColor() << "\n";
fw.indent() << "outlineLineWidth " << myobj.getOutlineLineWidth() << "\n";
return true;
}

View File

@ -0,0 +1,71 @@
#include <osgFX/Effect>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
bool Effect_readLocalData(osg::Object &obj, osgDB::Input &fr);
bool Effect_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
osgDB::RegisterDotOsgWrapperProxy Effect_Proxy
(
0,
"osgFX::Effect",
"Object Node osgFX::Effect",
Effect_readLocalData,
Effect_writeLocalData
);
bool Effect_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgFX::Effect &myobj = static_cast<osgFX::Effect &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("enabled")) {
if (fr[1].matchWord("FALSE")) {
myobj.setEnabled(false);
} else {
myobj.setEnabled(true);
}
fr += 2;
itAdvanced = true;
}
if (fr[0].matchWord("selectedTechnique")) {
if (fr[1].matchWord("AUTO_DETECT")) {
myobj.selectTechnique(osgFX::Effect::AUTO_DETECT);
fr += 2;
itAdvanced = true;
} else {
int i;
if (fr[1].getInt(i)) {
myobj.selectTechnique(i);
fr += 2;
itAdvanced = true;
}
}
}
osg::ref_ptr<osg::Node> node = static_cast<osg::Node *>(fr.readObjectOfType(osgDB::type_wrapper<osg::Node>()));
if (node.valid()) {
myobj.setChild(node.get());
}
return itAdvanced;
}
bool Effect_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgFX::Effect &myobj = static_cast<const osgFX::Effect &>(obj);
fw.indent() << "enabled " << (myobj.getEnabled() ? "TRUE" : "FALSE") << "\n";
fw.indent() << "selectedTechnique ";
if (myobj.getSelectedTechnique() == osgFX::Effect::AUTO_DETECT) {
fw << "AUTO_DETECT\n";
} else {
fw << myobj.getSelectedTechnique() << "\n";
}
fw.writeObject(*myobj.getChild());
return true;
}

View File

@ -0,0 +1,54 @@
#include <osgFX/Scribe>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
bool Scribe_readLocalData(osg::Object &obj, osgDB::Input &fr);
bool Scribe_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
osgDB::RegisterDotOsgWrapperProxy Scribe_Proxy
(
new osgFX::Scribe,
"osgFX::Scribe",
"Object Node osgFX::Effect osgFX::Scribe",
Scribe_readLocalData,
Scribe_writeLocalData
);
bool Scribe_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgFX::Scribe &myobj = static_cast<osgFX::Scribe &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("wireframeColor")) {
osg::Vec4 w;
if (fr[1].getFloat(w.x()) && fr[2].getFloat(w.y()) &&
fr[3].getFloat(w.z()) && fr[4].getFloat(w.w())) {
myobj.setWireframeColor(w);
fr += 5;
itAdvanced = true;
}
}
if (fr[0].matchWord("wireframeLineWidth")) {
float f;
if (fr[1].getFloat(f)) {
myobj.setWireframeLineWidth(f);
fr += 2;
itAdvanced = true;
}
}
return itAdvanced;
}
bool Scribe_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgFX::Scribe &myobj = static_cast<const osgFX::Scribe &>(obj);
fw.indent() << "wireframeColor " << myobj.getWireframeColor() << "\n";
fw.indent() << "wireframeLineWidth " << myobj.getWireframeLineWidth() << "\n";
return true;
}

View File

@ -0,0 +1,75 @@
#include <osgFX/SpecularHighlights>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
bool SpecularHighlights_readLocalData(osg::Object &obj, osgDB::Input &fr);
bool SpecularHighlights_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
osgDB::RegisterDotOsgWrapperProxy SpecularHighlights_Proxy
(
new osgFX::SpecularHighlights,
"osgFX::SpecularHighlights",
"Object Node osgFX::Effect osgFX::SpecularHighlights",
SpecularHighlights_readLocalData,
SpecularHighlights_writeLocalData
);
bool SpecularHighlights_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgFX::SpecularHighlights &myobj = static_cast<osgFX::SpecularHighlights &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("lightNumber")) {
int n;
if (fr[1].getInt(n)) {
myobj.setLightNumber(n);
fr += 2;
itAdvanced = true;
}
}
if (fr[0].matchWord("textureUnit")) {
int n;
if (fr[1].getInt(n)) {
myobj.setTextureUnit(n);
fr += 2;
itAdvanced = true;
}
}
if (fr[0].matchWord("specularColor")) {
osg::Vec4 w;
if (fr[1].getFloat(w.x()) && fr[2].getFloat(w.y()) &&
fr[3].getFloat(w.z()) && fr[4].getFloat(w.w())) {
myobj.setSpecularColor(w);
fr += 5;
itAdvanced = true;
}
}
if (fr[0].matchWord("specularExponent")) {
float f;
if (fr[1].getFloat(f)) {
myobj.setSpecularExponent(f);
fr += 2;
itAdvanced = true;
}
}
return itAdvanced;
}
bool SpecularHighlights_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgFX::SpecularHighlights &myobj = static_cast<const osgFX::SpecularHighlights &>(obj);
fw.indent() << "lightNumber " << myobj.getLightNumber() << "\n";
fw.indent() << "textureUnit " << myobj.getTextureUnit() << "\n";
fw.indent() << "specularColor " << myobj.getSpecularColor() << "\n";
fw.indent() << "specularExponent " << myobj.getSpecularExponent() << "\n";
return true;
}