fix pgraph fog

This commit is contained in:
David Rose 2002-03-21 20:55:58 +00:00
parent 9e3a93beba
commit 986e2b5cc2
11 changed files with 106 additions and 42 deletions

View File

@ -2515,14 +2515,8 @@ apply_fog(qpFog *fog) {
call_glFogMode(get_fog_mode_type((Fog::Mode)fmode));
if (fmode == qpFog::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,
qpNodePath(),
// _current_camera,
_coordinate_system);
fog->get_linear_range(onset, opaque);
call_glFogStart(onset);
call_glFogEnd(opaque);

View File

@ -69,7 +69,8 @@ apply_transform_and_state(qpCullTraverser *trav) {
}
}
_state = _state->compose(node()->get_state());
const RenderState *node_state = node()->get_state();
_state = _state->compose(node_state);
const RenderEffects *node_effects = node()->get_effects();
const BillboardEffect *billboard = node_effects->get_billboard();

View File

@ -20,6 +20,7 @@
#include "cullTraverserData.h"
#include "transformState.h"
#include "renderState.h"
#include "fogAttrib.h"
#include "cullHandler.h"
#include "dcast.h"
#include "qpgeomNode.h"
@ -91,6 +92,16 @@ traverse(CullTraverserData &data) {
data.apply_transform_and_state(this);
PandaNode *node = data.node();
const FogAttrib *fog = node->get_state()->get_fog();
if (fog != (const FogAttrib *)NULL && fog->get_fog() != (qpFog *)NULL) {
// If we just introduced a FogAttrib here, call adjust_to_camera()
// now. This maybe isn't the perfect time to call it, but it's
// good enough; and at this time we have all the information we
// need for it.
fog->get_fog()->adjust_to_camera(_camera_transform);
}
if (node->has_cull_callback()) {
if (!node->cull_callback(this, data)) {
return;

View File

@ -96,10 +96,12 @@ set_color(const Colorf &color) {
// M_linear, if it is not already set.
////////////////////////////////////////////////////////////////////
INLINE void qpFog::
set_linear_range(float onset, float opaque, CoordinateSystem cs) {
LVector3f forward = LVector3f::forward(cs);
set_linear_range(float onset, float opaque) {
LVector3f forward = LVector3f::forward();
_linear_onset_point = onset * forward;
_linear_opaque_point = opaque * forward;
_transformed_onset = onset;
_transformed_opaque = opaque;
_mode = M_linear;
}

View File

@ -22,6 +22,7 @@
#include "mathNumbers.h"
#include "qpnodePath.h"
#include "transformState.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "datagram.h"
@ -64,6 +65,8 @@ qpFog(const string &name) :
_linear_fallback_cosa = -1.0f;
_linear_fallback_onset = 0.0f;
_linear_fallback_opaque = 0.0f;
_transformed_onset = 0.0f;
_transformed_opaque = 0.0f;
}
////////////////////////////////////////////////////////////////////
@ -83,6 +86,8 @@ qpFog(const qpFog &copy) :
_linear_fallback_cosa = copy._linear_fallback_cosa;
_linear_fallback_onset = copy._linear_fallback_onset;
_linear_fallback_opaque = copy._linear_fallback_opaque;
_transformed_onset = copy._transformed_onset;
_transformed_opaque = copy._transformed_opaque;
}
////////////////////////////////////////////////////////////////////
@ -142,17 +147,17 @@ output(ostream &out) const {
}
////////////////////////////////////////////////////////////////////
// Function: qpFog::compute_linear_range
// Function: qpFog::adjust_to_camera
// 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).
// Description: This function is intended to be called by the cull
// traverser 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 qpFog::
compute_linear_range(float &onset, float &opaque,
const qpNodePath &camera, CoordinateSystem cs) {
LVector3f forward = LVector3f::forward(cs);
adjust_to_camera(const TransformState *camera_transform) {
LVector3f forward = LVector3f::forward();
LPoint3f onset_point, opaque_point;
if (get_num_parents() != 0) {
@ -160,7 +165,10 @@ compute_linear_range(float &onset, float &opaque,
// graph.
qpNodePath this_np(this);
const LMatrix4f &mat = this_np.get_mat(camera);
CPT(TransformState) rel_transform =
camera_transform->invert_compose(this_np.get_net_transform());
const LMatrix4f &mat = rel_transform->get_mat();
// How far out of whack are we?
LVector3f fog_vector = (_linear_opaque_point - _linear_onset_point) * mat;
@ -169,24 +177,30 @@ compute_linear_range(float &onset, float &opaque,
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;
_transformed_onset = _linear_fallback_onset;
_transformed_opaque = _linear_fallback_opaque;
} else {
_transformed_onset = forward.dot(_linear_onset_point * mat);
_transformed_opaque = forward.dot(_linear_opaque_point * mat);
}
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;
// Not a camera-relative fog.
_transformed_onset = forward.dot(_linear_onset_point);
_transformed_opaque = forward.dot(_linear_opaque_point);
}
onset = onset_point.dot(forward);
opaque = opaque_point.dot(forward);
}
////////////////////////////////////////////////////////////////////
// Function: qpFog::get_linear_range
// Access: Public
// Description: Retrieves the current onset and offset ranges.
////////////////////////////////////////////////////////////////////
void qpFog::
get_linear_range(float &onset, float &opaque) {
onset = _transformed_onset;
opaque = _transformed_opaque;
}
////////////////////////////////////////////////////////////////////

View File

@ -26,7 +26,7 @@
#include "cmath.h"
#include "deg_2_rad.h"
class qpNodePath;
class TransformState;
////////////////////////////////////////////////////////////////////
// Class : Fog
@ -74,8 +74,7 @@ PUBLISHED:
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 void set_linear_range(float onset, float opaque);
INLINE const LPoint3f &get_linear_onset_point() const;
INLINE void set_linear_onset_point(float x, float y, float z);
@ -93,8 +92,8 @@ PUBLISHED:
void output(ostream &out) const;
public:
void compute_linear_range(float &onset, float &opaque,
const qpNodePath &camera, CoordinateSystem cs);
void adjust_to_camera(const TransformState *camera_transform);
void get_linear_range(float &onset, float &opaque);
protected:
void compute_density();
@ -116,6 +115,8 @@ protected:
float _linear_fallback_cosa;
float _linear_fallback_onset, _linear_fallback_opaque;
float _transformed_onset, _transformed_opaque;
public:
static TypeHandle get_class_type() {

View File

@ -123,8 +123,8 @@ private:
typedef ov_set<Effect> Effects;
Effects _effects;
// We cache the pointer to the some critical effects stored in
// the state, if they exist.
// We cache the pointer to some critical effects stored in the
// state, if they exist.
const BillboardEffect *_billboard;
enum Flags {

View File

@ -197,3 +197,22 @@ get_draw_order() const {
}
return _draw_order;
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::get_fog
// Access: Public
// Description: This function is provided as an optimization, to
// speed up the render-time checking for the existance
// of a FogAttrib on this state. It returns a
// pointer to the FogAttrib, if there is one, or
// NULL if there is not.
////////////////////////////////////////////////////////////////////
INLINE const FogAttrib *RenderState::
get_fog() const {
if ((_flags & F_checked_fog) == 0) {
// We pretend this function is const, even though it transparently
// modifies the internal fog cache.
((RenderState *)this)->determine_fog();
}
return _fog;
}

View File

@ -20,6 +20,7 @@
#include "transparencyAttrib.h"
#include "cullBinAttrib.h"
#include "cullBinManager.h"
#include "fogAttrib.h"
#include "config_pgraph.h"
#include "bamReader.h"
#include "bamWriter.h"
@ -927,6 +928,21 @@ determine_bin_index() {
_flags |= F_checked_bin_index;
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::determine_fog
// Access: Private
// Description: This is the private implementation of get_fog().
////////////////////////////////////////////////////////////////////
void RenderState::
determine_fog() {
const RenderAttrib *attrib = get_attrib(FogAttrib::get_class_type());
_fog = (const FogAttrib *)NULL;
if (attrib != (const RenderAttrib *)NULL) {
_fog = DCAST(FogAttrib, attrib);
}
_flags |= F_checked_fog;
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::register_with_read_factory
// Access: Public, Static

View File

@ -28,6 +28,7 @@
#include "ordered_vector.h"
class GraphicsStateGuardianBase;
class FogAttrib;
////////////////////////////////////////////////////////////////////
// Class : RenderState
@ -90,6 +91,7 @@ PUBLISHED:
public:
INLINE int get_bin_index() const;
INLINE int get_draw_order() const;
INLINE const FogAttrib *get_fog() const;
CPT(RenderState) issue_delta_modify(const RenderState *other,
GraphicsStateGuardianBase *gsg) const;
@ -103,6 +105,7 @@ private:
CPT(RenderState) do_compose(const RenderState *other) const;
CPT(RenderState) do_invert_compose(const RenderState *other) const;
void determine_bin_index();
void determine_fog();
private:
typedef pset<const RenderState *, IndirectLess<RenderState> > States;
@ -161,8 +164,13 @@ private:
int _bin_index;
int _draw_order;
// We also cache the pointer to some critical attribs stored in the
// state, if they exist.
const FogAttrib *_fog;
enum Flags {
F_checked_bin_index = 0x0001,
F_checked_fog = 0x0002,
};
short _flags;

View File

@ -442,14 +442,12 @@ decode_text(const string &text) const {
StringUtf8Decoder decoder(text);
return decode_text_impl(decoder);
}
break;
case E_unicode:
{
StringUnicodeDecoder decoder(text);
return decode_text_impl(decoder);
}
break;
case E_iso8859:
default: