From 986e2b5cc22f1533f5b042e14f160ee133245d5f Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 21 Mar 2002 20:55:58 +0000 Subject: [PATCH] fix pgraph fog --- panda/src/glgsg/glGraphicsStateGuardian.cxx | 8 +-- panda/src/pgraph/cullTraverserData.cxx | 3 +- panda/src/pgraph/qpcullTraverser.cxx | 11 ++++ panda/src/pgraph/qpfog.I | 6 ++- panda/src/pgraph/qpfog.cxx | 60 +++++++++++++-------- panda/src/pgraph/qpfog.h | 11 ++-- panda/src/pgraph/renderEffects.h | 4 +- panda/src/pgraph/renderState.I | 19 +++++++ panda/src/pgraph/renderState.cxx | 16 ++++++ panda/src/pgraph/renderState.h | 8 +++ panda/src/text/qptextNode.cxx | 2 - 11 files changed, 106 insertions(+), 42 deletions(-) diff --git a/panda/src/glgsg/glGraphicsStateGuardian.cxx b/panda/src/glgsg/glGraphicsStateGuardian.cxx index 433d7111ef..5916d29799 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.cxx +++ b/panda/src/glgsg/glGraphicsStateGuardian.cxx @@ -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); diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index 1e2ffb4882..9ba14418c0 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -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(); diff --git a/panda/src/pgraph/qpcullTraverser.cxx b/panda/src/pgraph/qpcullTraverser.cxx index e1c694be5f..63c04af876 100644 --- a/panda/src/pgraph/qpcullTraverser.cxx +++ b/panda/src/pgraph/qpcullTraverser.cxx @@ -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; diff --git a/panda/src/pgraph/qpfog.I b/panda/src/pgraph/qpfog.I index 45808d6131..605e4564c1 100644 --- a/panda/src/pgraph/qpfog.I +++ b/panda/src/pgraph/qpfog.I @@ -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; } diff --git a/panda/src/pgraph/qpfog.cxx b/panda/src/pgraph/qpfog.cxx index 50b3e5ff3c..411c562dd4 100644 --- a/panda/src/pgraph/qpfog.cxx +++ b/panda/src/pgraph/qpfog.cxx @@ -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 ©) : _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; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/qpfog.h b/panda/src/pgraph/qpfog.h index 34171d53fc..a52d48ce16 100644 --- a/panda/src/pgraph/qpfog.h +++ b/panda/src/pgraph/qpfog.h @@ -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() { diff --git a/panda/src/pgraph/renderEffects.h b/panda/src/pgraph/renderEffects.h index b6101944a8..43c8a016ad 100644 --- a/panda/src/pgraph/renderEffects.h +++ b/panda/src/pgraph/renderEffects.h @@ -123,8 +123,8 @@ private: typedef ov_set 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 { diff --git a/panda/src/pgraph/renderState.I b/panda/src/pgraph/renderState.I index 7b3b1df85a..39f486820f 100644 --- a/panda/src/pgraph/renderState.I +++ b/panda/src/pgraph/renderState.I @@ -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; +} diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 43dffd9520..acf70f633d 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -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 diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 53b1ed1266..9a9f0f59ac 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -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 > 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; diff --git a/panda/src/text/qptextNode.cxx b/panda/src/text/qptextNode.cxx index edee94a51b..96e3285f97 100644 --- a/panda/src/text/qptextNode.cxx +++ b/panda/src/text/qptextNode.cxx @@ -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: