mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 12:12:10 -04:00
new fog node with in-the-world linear fog effects
This commit is contained in:
parent
c7ca108984
commit
9768ef255e
@ -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();
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
@ -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
|
@ -10,5 +10,4 @@
|
||||
#include "geomTri.cxx"
|
||||
#include "geomTrifan.cxx"
|
||||
#include "geomTristrip.cxx"
|
||||
#include "fog.cxx"
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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
283
panda/src/sgattrib/fog.I
Normal 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
258
panda/src/sgattrib/fog.cxx
Normal 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 ©) :
|
||||
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 ©) {
|
||||
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
144
panda/src/sgattrib/fog.h
Normal 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 ©);
|
||||
void operator = (const Fog ©);
|
||||
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
|
@ -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
|
||||
|
@ -11,3 +11,4 @@
|
||||
#include "depthTestTransition.cxx"
|
||||
#include "depthWriteTransition.cxx"
|
||||
#include "drawBoundsTransition.cxx"
|
||||
#include "fog.cxx"
|
||||
|
Loading…
x
Reference in New Issue
Block a user