new fog node with in-the-world linear fog effects

This commit is contained in:
David Rose 2001-11-02 18:25:11 +00:00
parent c7ca108984
commit 9768ef255e
14 changed files with 713 additions and 346 deletions

View File

@ -2422,20 +2422,24 @@ void GLGraphicsStateGuardian::apply_material(const Material *material) {
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
apply_fog(Fog *fog) {
Fog::Mode fmode=fog->get_mode();
Fog::Mode fmode = fog->get_mode();
call_glFogMode(get_fog_mode_type(fmode));
switch(fmode) {
case Fog::M_linear:
float fog_start,fog_end;
fog->get_range(fog_start,fog_end);
call_glFogStart(fog_start);
call_glFogEnd(fog_end);
break;
case Fog::M_exponential:
case Fog::M_exponential_squared:
call_glFogDensity(fog->get_density());
break;
if (fmode == Fog::M_linear) {
// Linear fog may be world-relative or camera-relative. The fog
// object knows how to decode its parameters into camera-relative
// properties.
float onset, opaque;
fog->compute_linear_range(onset, opaque, _current_projection_node,
_coordinate_system);
call_glFogStart(onset);
call_glFogEnd(opaque);
} else {
// Exponential fog is always camera-relative.
call_glFogDensity(fog->get_exp_density());
}
call_glFogColor(fog->get_color());
report_errors();
}

View File

@ -9,7 +9,7 @@
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
LOD.I LOD.h config_gobj.h drawable.h fog.I fog.h geom.I geom.N \
LOD.I LOD.h config_gobj.h drawable.h geom.I geom.N \
geom.h geomLine.h geomLinestrip.h geomPoint.h geomPolygon.h \
geomQuad.h geomSphere.h geomSprite.I geomSprite.h geomTri.h \
geomTrifan.h geomTristrip.h imageBuffer.I imageBuffer.h \
@ -20,7 +20,7 @@
texturePool.I texturePool.h
#define INCLUDED_SOURCES \
LOD.cxx config_gobj.cxx drawable.cxx fog.cxx geom.cxx \
LOD.cxx config_gobj.cxx drawable.cxx geom.cxx \
geomLine.cxx geomLinestrip.cxx geomPoint.cxx geomPolygon.cxx \
geomQuad.cxx geomSphere.cxx geomSprite.cxx geomTri.cxx \
geomTrifan.cxx geomTristrip.cxx imageBuffer.cxx material.cxx \
@ -30,7 +30,7 @@
#define INSTALL_HEADERS \
LOD.I LOD.h config_gobj.h \
drawable.h fog.I fog.h geom.I geom.h geomLine.h \
drawable.h geom.I geom.h geomLine.h \
geomLinestrip.h geomPoint.h geomPolygon.h geomQuad.h geomSphere.h \
geomSprite.I geomSprite.h geomTri.h geomTrifan.h geomTristrip.h \
geomprimitives.h imageBuffer.I imageBuffer.h material.I material.h \

View File

@ -20,7 +20,6 @@
#include "config_gobj.h"
#include "LOD.h"
#include "drawable.h"
#include "fog.h"
#include "geom.h"
#include "geomprimitives.h"
#include "imageBuffer.h"
@ -163,7 +162,6 @@ ConfigureFn(config_gobj) {
textures_down_square = config_gobj.GetBool("textures-square", false);
}
Fog::init_type();
Geom::init_type();
GeomLine::init_type();
GeomLinestrip::init_type();

View File

@ -1,101 +0,0 @@
// Filename: fog.I
// Created by: krisg (05Feb01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: Fog::get_mode
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE Fog::Mode Fog::get_mode(void) const {
return _mode;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_mode
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Fog::set_mode(Mode mode) {
_mode = mode;
// compute_density();
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_color
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE Colorf Fog::get_color(void) const {
return _color;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_color
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Fog::set_color(const Colorf &color) {
_color = color;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_range
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Fog::get_range(float &onset, float &opaque) const {
onset = _onset_distance;
opaque = _opaque_distance;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_range
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Fog::set_range(float onset, float opaque) {
_onset_distance = onset;
_opaque_distance = opaque;
// compute_density();
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_density
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE float Fog::get_density(void) const {
return _density;
}
INLINE void Fog::set_density(float fDensity) {
assert((fDensity >= 0.0) && (fDensity <= 1.0));
_density = fDensity;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::apply
// Access: Public
// Description: Called during rendering to enable fogging with the
// GSG.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
apply(GraphicsStateGuardianBase *gsg) {
gsg->apply_fog(this);
}

View File

@ -1,113 +0,0 @@
// Filename: fog.cxx
// Created by: mike (09Jan97)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include "fog.h"
#include <mathNumbers.h>
#include <stddef.h>
////////////////////////////////////////////////////////////////////
// Static variables
////////////////////////////////////////////////////////////////////
TypeHandle Fog::_type_handle;
ostream &
operator << (ostream &out, Fog::Mode mode) {
switch (mode) {
case Fog::M_linear:
return out << "linear";
case Fog::M_exponential:
return out << "exponential";
case Fog::M_exponential_squared:
return out << "exponential-squared";
}
return out << "**invalid**(" << (int)mode << ")";
}
////////////////////////////////////////////////////////////////////
// Function: Fog::Constructor
// Access:
// Description:
////////////////////////////////////////////////////////////////////
Fog::Fog(Mode mode, int bits_per_color_channel) {
_bits_per_color_channel = bits_per_color_channel;
set_mode(mode);
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
set_range(0.0f, 100.0f);
_density = 0.5f;
// compute_density();
}
#if 0
// this fn tries to 'match' exponential to linear fog by computing a exponential density
// factor such that exponential fog matches linear fog at the linear fog's 'fog-end' distance.
// usefulness of this is debatable since the exponential fog that matches will be very very
// close to observer, and it's harder to guess a good end fog distance than it is to manipulate
// the [0.0,1.0] density range directly, so taking this out
////////////////////////////////////////////////////////////////////
// Function: Fog::compute_density
// Access:
// Description:
////////////////////////////////////////////////////////////////////
void Fog::compute_density(void) {
_density = 1.0f;
float opaque_multiplier;
switch (_mode) {
case M_linear:
break;
case M_exponential:
// Multiplier = ln(2^bits)
// attempt to compute density based on full
opaque_multiplier = MathNumbers::ln2 * _bits_per_color_channel;
_density = opaque_multiplier / _opaque_distance;
break;
case M_exponential_squared:
// Multiplier = ln(sqrt(2^bits))
opaque_multiplier = 0.5f * MathNumbers::ln2 * _bits_per_color_channel;
opaque_multiplier *= opaque_multiplier;
_density = opaque_multiplier / _opaque_distance;
break;
}
}
#endif
////////////////////////////////////////////////////////////////////
// Function: Fog::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void Fog::
output(ostream &out) const {
out << "fog:" << _mode;
switch (_mode) {
case M_linear:
break;
case M_exponential:
case M_exponential_squared:
out << "(" << _bits_per_color_channel << "," << _density
<< "," << _opaque_distance << ")";
break;
};
}

View File

@ -1,108 +0,0 @@
// Filename: fog.h
// Created by: mike (09Jan97)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef FOG_H
#define FOG_H
//
////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include <graphicsStateGuardianBase.h>
#include <typedReferenceCount.h>
#include <luse.h>
#include <pointerToArray.h>
////////////////////////////////////////////////////////////////////
// Defines
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Fog
// Description : Specifies atmospheric fog parameters
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Fog : public TypedReferenceCount {
PUBLISHED:
enum Mode {
M_linear, // f = (end - z) / (end - start)
M_exponential, // f = e^(-density * z)
M_exponential_squared // f = e^((-density * z)^2)
};
Fog(Mode mode = M_linear, int bits_per_color_channel = 8);
INLINE ~Fog(void) {};
INLINE Mode get_mode(void) const;
INLINE void set_mode(Mode mode);
INLINE Colorf get_color(void) const;
INLINE void set_color(const Colorf &color);
INLINE void get_range(float &onset, float &opaque) const;
INLINE void set_range(float onset, float opaque);
INLINE float get_density(void) const;
INLINE void set_density(float fDensity);
void output(ostream &out) const;
public:
INLINE void apply(GraphicsStateGuardianBase *gsg);
protected:
void compute_density(void);
protected:
Mode _mode;
int _bits_per_color_channel;
Colorf _color;
float _onset_distance;
float _opaque_distance;
float _density;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "Fog",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
ostream &operator << (ostream &out, Fog::Mode mode);
INLINE ostream &operator << (ostream &out, const Fog &fog) {
fog.output(out);
return out;
}
#include "fog.I"
#endif

View File

@ -10,5 +10,4 @@
#include "geomTri.cxx"
#include "geomTrifan.cxx"
#include "geomTristrip.cxx"
#include "fog.cxx"

View File

@ -28,7 +28,7 @@
depthTestTransition.I depthTestTransition.h \
depthWriteTransition.I depthWriteTransition.h \
drawBoundsTransition.I drawBoundsTransition.h \
fogTransition.I fogTransition.h \
fog.I fog.h fogTransition.I fogTransition.h \
linesmoothTransition.I linesmoothTransition.h \
materialTransition.I \
materialTransition.h pointShapeProperty.I \
@ -61,7 +61,7 @@
cullFaceProperty.cxx cullFaceTransition.cxx \
decalTransition.cxx depthTestProperty.cxx \
depthTestTransition.cxx depthWriteTransition.cxx \
drawBoundsTransition.cxx fogTransition.cxx \
drawBoundsTransition.cxx fog.cxx fogTransition.cxx \
linesmoothTransition.cxx \
materialTransition.cxx pointShapeProperty.cxx \
pointShapeTransition.cxx \
@ -96,7 +96,7 @@
depthTestTransition.I depthTestTransition.h \
depthWriteTransition.I depthWriteTransition.h \
drawBoundsTransition.I drawBoundsTransition.h \
fogTransition.I fogTransition.h \
fog.I fog.h fogTransition.I fogTransition.h \
linesmoothTransition.I \
linesmoothTransition.h \
materialTransition.I materialTransition.h \

View File

@ -33,6 +33,7 @@
#include "textureApplyTransition.h"
#include "clipPlaneTransition.h"
#include "transparencyTransition.h"
#include "fog.h"
#include "fogTransition.h"
#include "linesmoothTransition.h"
#include "transformTransition.h"
@ -132,6 +133,7 @@ ConfigureFn(config_sgattrib) {
TextureApplyTransition::init_type();
ClipPlaneTransition::init_type();
TransparencyTransition::init_type();
Fog::init_type();
FogTransition::init_type();
LinesmoothTransition::init_type();
PruneTransition::init_type();

283
panda/src/sgattrib/fog.I Normal file
View File

@ -0,0 +1,283 @@
// Filename: fog.I
// Created by: krisg (05Feb01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: Fog::get_mode
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE Fog::Mode Fog::
get_mode() const {
return _mode;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_mode
// Access: Published
// Description: Specifies the computation that is used to determine
// the fog effect. If this is M_linear, then the fog
// will range from linearly from the onset point to the
// opaque point (or for the distances specified in
// set_linear_range), and the fog object should be
// parented into the scene graph, or to the camera.
//
// If this is anything else, the onset point and opaque
// point are not used, and the fog effect is based on
// the value specified to set_exp_density(), and it
// doesn't matter to which node the fog object is
// parented, or if it is parented anywhere at all.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_mode(Mode mode) {
_mode = mode;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_bits_per_color_channel
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int Fog::
get_bits_per_color_channel() const {
return _bits_per_color_channel;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_bits_per_color_channel
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_bits_per_color_channel(int bits_per_color_channel) {
_bits_per_color_channel = bits_per_color_channel;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_color
// Access: Published
// Description: Returns the color of the fog.
////////////////////////////////////////////////////////////////////
INLINE const Colorf &Fog::
get_color() const {
return _color;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_color
// Access: Published
// Description: Sets the color of the fog.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_color(float r, float g, float b) {
_color[0] = r;
_color[1] = g;
_color[2] = b;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_color
// Access: Published
// Description: Sets the color of the fog. The alpha component is
// not used.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_color(const Colorf &color) {
_color = color;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_linear_range
// Access: Published
// Description: Specifies the effects of the fog in linear distance
// units. This is only used if the mode is M_linear.
//
// This specifies a fog that begins at distance onset
// units from the origin, and becomes totally opaque at
// distance opaque units from the origin, along the
// forward axis (usually Y).
//
// This function also implicitly sets the mode the
// M_linear, if it is not already set.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_linear_range(float onset, float opaque, CoordinateSystem cs) {
LVector3f forward = LVector3f::forward(cs);
_linear_onset_point = onset * forward;
_linear_opaque_point = opaque * forward;
_mode = M_linear;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_linear_onset_point
// Access: Published
// Description: Returns the point in space at which the fog begins.
// This is only used if the mode is M_linear.
////////////////////////////////////////////////////////////////////
INLINE const LPoint3f &Fog::
get_linear_onset_point() const {
return _linear_onset_point;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_linear_onset_point
// Access: Published
// Description: Specifies the point in space at which the fog begins.
// This is only used if the mode is M_linear.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_linear_onset_point(float x, float y, float z) {
_linear_onset_point.set(x, y, z);
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_linear_onset_point
// Access: Published
// Description: Specifies the point in space at which the fog begins.
// This is only used if the mode is M_linear.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_linear_onset_point(const LPoint3f &linear_onset_point) {
_linear_onset_point = linear_onset_point;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_linear_opaque_point
// Access: Published
// Description: Returns the point in space at which the fog
// completely obscures geometry. This is only used if
// the mode is M_linear.
////////////////////////////////////////////////////////////////////
INLINE const LPoint3f &Fog::
get_linear_opaque_point() const {
return _linear_opaque_point;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_linear_opaque_point
// Access: Published
// Description: Specifies the point in space at which the fog
// completely obscures geometry. This is only used if
// the mode is M_linear.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_linear_opaque_point(float x, float y, float z) {
_linear_opaque_point.set(x, y, z);
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_linear_opaque_point
// Access: Published
// Description: Specifies the point in space at which the fog
// completely obscures geometry. This is only used if
// the mode is M_linear.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_linear_opaque_point(const LPoint3f &linear_opaque_point) {
_linear_opaque_point = linear_opaque_point;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_linear_fallback
// Access: Published
// Description: Fog effects are traditionally defined in
// camera-relative space, but the Panda Fog node has a
// special mode in which it can define a linear fog
// effect in an arbitrary coordinate space.
//
// This is done by specifying 3-d onset and opaque
// points, and parenting the Fog object somewhere within
// the scene graph. In this mode, the fog will be
// rendered as if it extended along the vector from the
// onset point to the opaque point, in 3-d space.
//
// However, the underlying fog effect supported by
// hardware is generally only one-dimensional, and must
// be rendered based on linear distance from the camera
// plane. Thus, this in-the-world effect is most
// effective when the fog vector from onset point to
// opaque point is most nearly parallel to the camera's
// eye vector.
//
// As the angle between the fog vector and the eye
// vector increases, the accuracy of the effect
// diminishes, up to a complete breakdown of the effect
// at a 90 degree angle.
//
// This function exists to define the workaround to this
// problem. The linear fallback parameters given here
// specify how the fog should be rendered when the
// parameters are exceeded in this way.
//
// The angle parameter is the minimum angle, in degrees,
// of the fog vector to the eye vector, at which the
// fallback effect should be employed. The onset and
// opaque parameters specify the camera-relative onset
// and opaque distances to pass to the rendering
// hardware when employing the fallback effect. This
// supercedes the 3-d onset point and opaque points.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_linear_fallback(float angle, float onset, float opaque) {
_linear_fallback_cosa = ccos(deg_2_rad(angle));
_linear_fallback_onset = onset;
_linear_fallback_opaque = opaque;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::get_exp_density
// Access: Published
// Description: Returns the density of the fog for exponential
// calculations. This is only used if the mode is not
// M_linear.
////////////////////////////////////////////////////////////////////
INLINE float Fog::
get_exp_density() const {
return _exp_density;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::set_exp_density
// Access: Published
// Description: Sets the density of the fog for exponential
// calculations. This is only used if the mode is not
// M_linear.
//
// If the mode is currently set to M_linear, this
// function implicitly sets it to M_exponential.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
set_exp_density(float exp_density) {
nassertv((exp_density >= 0.0) && (exp_density <= 1.0));
_exp_density = exp_density;
if (_mode == M_linear) {
_mode = M_exponential;
}
}
////////////////////////////////////////////////////////////////////
// Function: Fog::apply
// Access: Public
// Description: Called during rendering to enable fogging with the
// GSG.
////////////////////////////////////////////////////////////////////
INLINE void Fog::
apply(GraphicsStateGuardianBase *gsg) {
gsg->apply_fog(this);
}

258
panda/src/sgattrib/fog.cxx Normal file
View File

@ -0,0 +1,258 @@
// Filename: fog.cxx
// Created by: mike (09Jan97)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "fog.h"
#include "mathNumbers.h"
#include "renderRelation.h"
#include "transformTransition.h"
#include "wrt.h"
#include <stddef.h>
////////////////////////////////////////////////////////////////////
// Static variables
////////////////////////////////////////////////////////////////////
TypeHandle Fog::_type_handle;
ostream &
operator << (ostream &out, Fog::Mode mode) {
switch (mode) {
case Fog::M_linear:
return out << "linear";
case Fog::M_exponential:
return out << "exponential";
case Fog::M_exponential_squared:
return out << "exponential-squared";
}
return out << "**invalid**(" << (int)mode << ")";
}
////////////////////////////////////////////////////////////////////
// Function: Fog::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
Fog::
Fog(const string &name) : NamedNode(name) {
_mode = M_linear;
_bits_per_color_channel = 8;
_color.set(1.0f, 1.0f, 1.0f, 1.0f);
_linear_onset_point.set(0.0f, 0.0f, 0.0f);
_linear_opaque_point.set(0.0, 100.0f, 0.0f);
_exp_density = 0.5f;
_linear_fallback_cosa = -1.0f;
_linear_fallback_onset = 0.0f;
_linear_fallback_opaque = 0.0f;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
Fog::
Fog(const Fog &copy) :
NamedNode(copy)
{
_mode = copy._mode;
_bits_per_color_channel = copy._bits_per_color_channel;
_color = copy._color;
_linear_onset_point = copy._linear_onset_point;
_linear_opaque_point = copy._linear_opaque_point;
_exp_density = copy._exp_density;
_linear_fallback_cosa = copy._linear_fallback_cosa;
_linear_fallback_onset = copy._linear_fallback_onset;
_linear_fallback_opaque = copy._linear_fallback_opaque;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void Fog::
operator = (const Fog &copy) {
NamedNode::operator = (copy);
_mode = copy._mode;
_bits_per_color_channel = copy._bits_per_color_channel;
_color = copy._color;
_linear_onset_point = copy._linear_onset_point;
_linear_opaque_point = copy._linear_opaque_point;
_exp_density = copy._exp_density;
_linear_fallback_cosa = copy._linear_fallback_cosa;
_linear_fallback_onset = copy._linear_fallback_onset;
_linear_fallback_opaque = copy._linear_fallback_opaque;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
Fog::
~Fog() {
}
////////////////////////////////////////////////////////////////////
// Function: Fog::make_copy
// Access: Public, Virtual
// Description: Returns a newly-allocated Node that is a shallow copy
// of this one. It will be a different Node pointer,
// but its internal data may or may not be shared with
// that of the original Node.
////////////////////////////////////////////////////////////////////
Node *Fog::
make_copy() const {
return new Fog(*this);
}
////////////////////////////////////////////////////////////////////
// Function: Fog::xform
// Access: Public, Virtual
// Description: Transforms the contents of this node by the indicated
// matrix, if it means anything to do so. For most
// kinds of nodes, this does nothing.
////////////////////////////////////////////////////////////////////
void Fog::
xform(const LMatrix4f &mat) {
_linear_onset_point = _linear_onset_point * mat;
_linear_opaque_point = _linear_opaque_point * mat;
}
////////////////////////////////////////////////////////////////////
// Function: Fog::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void Fog::
output(ostream &out) const {
out << "fog: " << _mode;
switch (_mode) {
case M_linear:
out << "(" << _linear_onset_point << ") -> ("
<< _linear_opaque_point << ")";
break;
case M_exponential:
case M_exponential_squared:
out << "(" << _bits_per_color_channel << ", " << _exp_density
<< ")";
break;
};
}
////////////////////////////////////////////////////////////////////
// Function: Fog::compute_linear_range
// Access: Public
// Description: This function is intended to be called by GSG's to
// compute the appropriate camera-relative onset and
// opaque distances, based on the fog node's position
// within the scene graph (if linear fog is in effect).
////////////////////////////////////////////////////////////////////
void Fog::
compute_linear_range(float &onset, float &opaque,
Node *camera_node, CoordinateSystem cs) {
LVector3f forward = LVector3f::forward(cs);
LPoint3f onset_point, opaque_point;
if (get_num_parents(RenderRelation::get_class_type()) != 0) {
// Linear fog is relative to the fog's net transform in the scene
// graph.
LMatrix4f mat;
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
wrt(this, camera_node, ntw, RenderRelation::get_class_type());
const TransformTransition *tt;
if (!get_transition_into(tt, ntw)) {
// No relative transform.
mat = LMatrix4f::ident_mat();
} else {
mat = tt->get_matrix();
}
// How far out of whack are we?
LVector3f fog_vector = (_linear_opaque_point - _linear_onset_point) * mat;
fog_vector.normalize();
float cosa = fog_vector.dot(forward);
if (cabs(cosa) < _linear_fallback_cosa) {
// The fog vector is too far from the eye vector; use the
// fallback mode.
onset = _linear_fallback_onset;
opaque = _linear_fallback_opaque;
//cerr << "fallback! " << cosa << " vs. " << _linear_fallback_cosa << "\n";
return;
}
onset_point = _linear_onset_point * mat;
opaque_point = _linear_opaque_point * mat;
} else {
// If the fog object has no parents, we assume the user meant
// camera-relative fog.
onset_point = _linear_onset_point;
opaque_point = _linear_opaque_point;
}
onset = onset_point.dot(forward);
opaque = opaque_point.dot(forward);
}
#if 0
// this fn tries to 'match' exponential to linear fog by computing an
// exponential density factor such that exponential fog matches linear
// fog at the linear fog's 'fog-end' distance. usefulness of this is
// debatable since the exponential fog that matches will be very very
// close to observer, and it's harder to guess a good end fog distance
// than it is to manipulate the [0.0,1.0] density range directly, so
// taking this out
////////////////////////////////////////////////////////////////////
// Function: Fog::compute_density
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void Fog::compute_density(void) {
_density = 1.0f;
float opaque_multiplier;
switch (_mode) {
case M_linear:
break;
case M_exponential:
// Multiplier = ln(2^bits)
// attempt to compute density based on full
opaque_multiplier = MathNumbers::ln2 * _bits_per_color_channel;
_density = opaque_multiplier / _opaque_distance;
break;
case M_exponential_squared:
// Multiplier = ln(sqrt(2^bits))
opaque_multiplier = 0.5f * MathNumbers::ln2 * _bits_per_color_channel;
opaque_multiplier *= opaque_multiplier;
_density = opaque_multiplier / _opaque_distance;
break;
}
}
#endif

144
panda/src/sgattrib/fog.h Normal file
View File

@ -0,0 +1,144 @@
// Filename: fog.h
// Created by: mike (09Jan97)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef FOG_H
#define FOG_H
#include "pandabase.h"
#include "graphicsStateGuardianBase.h"
#include "luse.h"
#include "pointerToArray.h"
#include "namedNode.h"
#include "cmath.h"
#include "deg_2_rad.h"
class ArcChain;
////////////////////////////////////////////////////////////////////
// Class : Fog
// Description : Specifies how atmospheric fog effects are applied to
// geometry. The Fog object is now a Node, which means
// it can be used similar to a Light to define effects
// relative to a particular coordinate system within the
// scene graph.
//
// In exponential mode, the fog effects are always
// camera-relative, and it does not matter where the Fog
// node is parented. However, in linear mode, the onset
// and opaque distances are defined as offsets along the
// local forward axis (e.g. the Y axis). This allows
// the fog effect to be localized to a particular region
// in space, rather than always camera-relative. If the
// fog object is not parented to any node, it is treated
// as if it were parented to the camera.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Fog : public NamedNode {
PUBLISHED:
Fog(const string &name = "");
public:
Fog(const Fog &copy);
void operator = (const Fog &copy);
virtual ~Fog();
virtual Node *make_copy() const;
virtual void xform(const LMatrix4f &mat);
PUBLISHED:
enum Mode {
M_linear, // f = (end - z) / (end - start)
M_exponential, // f = e^(-density * z)
M_exponential_squared // f = e^((-density * z)^2)
};
INLINE Mode get_mode() const;
INLINE void set_mode(Mode mode);
INLINE int get_bits_per_color_channel() const;
INLINE void set_bits_per_color_channel(int bits_per_color_channel);
INLINE const Colorf &get_color() const;
INLINE void set_color(float r, float g, float b);
INLINE void set_color(const Colorf &color);
INLINE void set_linear_range(float onset, float opaque,
CoordinateSystem cs = CS_default);
INLINE const LPoint3f &get_linear_onset_point() const;
INLINE void set_linear_onset_point(float x, float y, float z);
INLINE void set_linear_onset_point(const LPoint3f &linear_onset_point);
INLINE const LPoint3f &get_linear_opaque_point() const;
INLINE void set_linear_opaque_point(const LPoint3f &linear_opaque_point);
INLINE void set_linear_opaque_point(float x, float y, float z);
INLINE void set_linear_fallback(float angle, float onset, float opaque);
INLINE float get_exp_density() const;
INLINE void set_exp_density(float exp_density);
void output(ostream &out) const;
public:
INLINE void apply(GraphicsStateGuardianBase *gsg);
void compute_linear_range(float &onset, float &opaque,
Node *camera_node, CoordinateSystem cs);
protected:
void compute_density();
protected:
Mode _mode;
int _bits_per_color_channel;
Colorf _color;
LPoint3f _linear_onset_point;
LPoint3f _linear_opaque_point;
float _exp_density;
float _linear_fallback_cosa;
float _linear_fallback_onset, _linear_fallback_opaque;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "Fog",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
ostream &operator << (ostream &out, Fog::Mode mode);
INLINE ostream &operator << (ostream &out, const Fog &fog) {
fog.output(out);
return out;
}
#include "fog.I"
#endif

View File

@ -19,10 +19,10 @@
#ifndef FOGTRANSITION_H
#define FOGTRANSITION_H
#include <pandabase.h>
#include "pandabase.h"
#include <onOffTransition.h>
#include <fog.h>
#include "onOffTransition.h"
#include "fog.h"
////////////////////////////////////////////////////////////////////
// Class : FogTransition

View File

@ -11,3 +11,4 @@
#include "depthTestTransition.cxx"
#include "depthWriteTransition.cxx"
#include "drawBoundsTransition.cxx"
#include "fog.cxx"