From c3fd90eaaf6863cd8c11bef8fb6b9b9fe39673e8 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 24 Jul 2001 23:31:11 +0000 Subject: [PATCH] add QuickRenderTraverser --- panda/src/cull/cullTraverser.cxx | 2 +- panda/src/pgui/config_pgui.cxx | 22 +++ panda/src/pgui/config_pgui.h | 5 + panda/src/pgui/pgItem.cxx | 21 ++- panda/src/pstatclient/pStatProperties.cxx | 3 + panda/src/sgraphutil/Sources.pp | 14 +- .../src/sgraphutil/directRenderTraverser.cxx | 2 +- panda/src/sgraphutil/quickRenderLevelState.h | 38 ++++ panda/src/sgraphutil/quickRenderTraverser.I | 30 ++++ panda/src/sgraphutil/quickRenderTraverser.cxx | 167 ++++++++++++++++++ panda/src/sgraphutil/quickRenderTraverser.h | 99 +++++++++++ .../src/sgraphutil/sgraphutil_composite2.cxx | 1 + 12 files changed, 392 insertions(+), 12 deletions(-) create mode 100644 panda/src/sgraphutil/quickRenderLevelState.h create mode 100644 panda/src/sgraphutil/quickRenderTraverser.I create mode 100644 panda/src/sgraphutil/quickRenderTraverser.cxx create mode 100644 panda/src/sgraphutil/quickRenderTraverser.h diff --git a/panda/src/cull/cullTraverser.cxx b/panda/src/cull/cullTraverser.cxx index 71a7a8c7f2..844803ec1e 100644 --- a/panda/src/cull/cullTraverser.cxx +++ b/panda/src/cull/cullTraverser.cxx @@ -47,7 +47,7 @@ TypeHandle CullTraverser::_type_handle; #ifndef CPPPARSER PStatCollector CullTraverser::_cull_pcollector("Cull"); -PStatCollector CullTraverser::_draw_pcollector("Draw"); +PStatCollector CullTraverser::_draw_pcollector("Draw:Cull"); PStatCollector CullTraverser::_cull_traverse_pcollector("Cull:Traverse"); PStatCollector CullTraverser::_cull_geom_node_pcollector("Cull:Geom node"); PStatCollector CullTraverser::_cull_direct_node_pcollector("Cull:Direct node"); diff --git a/panda/src/pgui/config_pgui.cxx b/panda/src/pgui/config_pgui.cxx index 9ecf4d256b..887d56fc5a 100644 --- a/panda/src/pgui/config_pgui.cxx +++ b/panda/src/pgui/config_pgui.cxx @@ -32,6 +32,28 @@ Configure(config_pgui); NotifyCategoryDef(pgui, ""); ConfigureFn(config_pgui) { + init_libpgui(); +} + +const bool pgui_quick = config_pgui.GetBool("pgui-quick", false); + + +//////////////////////////////////////////////////////////////////// +// Function: init_libpgui +// Description: Initializes the library. This must be called at +// least once before any of the functions or classes in +// this library can be used. Normally it will be +// called by the static initializers and need not be +// called explicitly, but special cases exist. +//////////////////////////////////////////////////////////////////// +void +init_libpgui() { + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + PGButton::init_type(); PGEntry::init_type(); PGMouseWatcherParameter::init_type(); diff --git a/panda/src/pgui/config_pgui.h b/panda/src/pgui/config_pgui.h index 5cf474340c..d7bacbb198 100644 --- a/panda/src/pgui/config_pgui.h +++ b/panda/src/pgui/config_pgui.h @@ -24,4 +24,9 @@ NotifyCategoryDecl(pgui, EXPCL_PANDA, EXPTP_PANDA); +// Configure variables for pgui package. +extern const bool pgui_quick; + +extern EXPCL_PANDA void init_libpgui(); + #endif diff --git a/panda/src/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index b7d43d494e..233d9d557a 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/panda/src/pgui/pgItem.cxx @@ -19,6 +19,7 @@ #include "pgTop.h" #include "pgItem.h" #include "pgMouseWatcherParameter.h" +#include "config_pgui.h" #include "namedNode.h" #include "throw_event.h" @@ -27,7 +28,9 @@ #include "transformTransition.h" #include "sceneGraphReducer.h" #include "directRenderTraverser.h" +#include "quickRenderTraverser.h" #include "allTransitionsWrapper.h" +#include "graphicsStateGuardian.h" #ifdef HAVE_AUDIO #include "audioSound.h" @@ -202,12 +205,18 @@ draw_item(PGTop *top, GraphicsStateGuardian *gsg, // This item has a current state definition that we should use // to render the item. Node *def = get_state_def(get_state()); - - // We'll use a normal DirectRenderTraverser to do the rendering - // of the subgraph. - DirectRenderTraverser drt(gsg, RenderRelation::get_class_type()); - drt.set_view_frustum_cull(false); - drt.traverse(def, attrib, AllTransitionsWrapper()); + + if (!pgui_quick) { + // We'll use a normal DirectRenderTraverser to do the rendering + // of the subgraph. + DirectRenderTraverser drt(gsg, RenderRelation::get_class_type()); + drt.set_view_frustum_cull(false); + drt.traverse(def, attrib, AllTransitionsWrapper()); + + } else { + QuickRenderTraverser qrt(gsg, RenderRelation::get_class_type()); + qrt.traverse(def, attrib, AllTransitionsWrapper()); + } } } diff --git a/panda/src/pstatclient/pStatProperties.cxx b/panda/src/pstatclient/pStatProperties.cxx index 9a4c73bbe1..0e2a51fc70 100644 --- a/panda/src/pstatclient/pStatProperties.cxx +++ b/panda/src/pstatclient/pStatProperties.cxx @@ -121,6 +121,9 @@ static TimeCollectorProperties time_properties[] = { { 0, "Cull:Bins:Unsorted", { 0.5, 0.5, 1.0 } }, { 0, "Cull:Bins:Fixed", { 0.5, 1.0, 0.5 } }, { 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 }, + { 1, "Draw:Quick", { 1.0, 0.0, 0.8 } }, + { 1, "Draw:Direct", { 0.0, 0.4, 1.0 } }, + { 1, "Draw:Cull", { 0.4, 1.0, 0.0 } }, { 1, "Draw:Swap buffers", { 0.5, 1.0, 0.8 } }, { 1, "Draw:Clear", { 0.5, 0.7, 0.7 } }, { 1, "Draw:Show fps", { 0.5, 0.8, 1.0 } }, diff --git a/panda/src/sgraphutil/Sources.pp b/panda/src/sgraphutil/Sources.pp index 7a8c22ee43..954ce9253c 100644 --- a/panda/src/sgraphutil/Sources.pp +++ b/panda/src/sgraphutil/Sources.pp @@ -13,19 +13,25 @@ appTraverser.I appTraverser.h config_sgraphutil.h \ directRenderTraverser.I directRenderTraverser.h \ frustumCullTraverser.I frustumCullTraverser.h get_rel_pos.I \ - get_rel_pos.h sceneGraphAnalyzer.h sceneGraphReducer.I \ - sceneGraphReducer.h + get_rel_pos.h \ + quickRenderLevelState.h \ + quickRenderTraverser.I quickRenderTraverser.h \ + sceneGraphAnalyzer.h \ + sceneGraphReducer.I sceneGraphReducer.h #define INCLUDED_SOURCES \ appTraverser.cxx config_sgraphutil.cxx directRenderTraverser.cxx \ - frustumCullTraverser.cxx get_rel_pos.cxx sceneGraphAnalyzer.cxx \ - sceneGraphReducer.cxx + frustumCullTraverser.cxx get_rel_pos.cxx \ + quickRenderTraverser.cxx \ + sceneGraphAnalyzer.cxx sceneGraphReducer.cxx #define INSTALL_HEADERS \ appTraverser.I appTraverser.h config_sgraphutil.h \ directRenderLevelState.h directRenderTraverser.I \ directRenderTraverser.h frustumCullTraverser.I \ frustumCullTraverser.h get_rel_pos.I get_rel_pos.h \ + quickRenderLevelState.h \ + quickRenderTraverser.I quickRenderTraverser.h \ sceneGraphAnalyzer.h sceneGraphReducer.I sceneGraphReducer.h #define IGATESCAN all diff --git a/panda/src/sgraphutil/directRenderTraverser.cxx b/panda/src/sgraphutil/directRenderTraverser.cxx index 459148c634..902619b304 100644 --- a/panda/src/sgraphutil/directRenderTraverser.cxx +++ b/panda/src/sgraphutil/directRenderTraverser.cxx @@ -45,7 +45,7 @@ TypeHandle DirectRenderTraverser::_type_handle; #ifndef CPPPARSER -PStatCollector DirectRenderTraverser::_draw_pcollector("Draw"); +PStatCollector DirectRenderTraverser::_draw_pcollector("Draw:Direct"); #endif //////////////////////////////////////////////////////////////////// diff --git a/panda/src/sgraphutil/quickRenderLevelState.h b/panda/src/sgraphutil/quickRenderLevelState.h new file mode 100644 index 0000000000..0fd94e0993 --- /dev/null +++ b/panda/src/sgraphutil/quickRenderLevelState.h @@ -0,0 +1,38 @@ +// Filename: quickRenderLevelState.h +// Created by: drose (24Jul01) +// +//////////////////////////////////////////////////////////////////// +// +// 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 QUICKRENDERLEVELSTATE_H +#define QUICKRENDERLEVELSTATE_H + +#include "pandabase.h" + +#include "updateSeq.h" + +//////////////////////////////////////////////////////////////////// +// Class : QuickRenderLevelState +// Description : This is the state information the +// QuickRenderTraverser retains for each level during +// traversal. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA QuickRenderLevelState { +public: + UpdateSeq _as_of; +}; + +#endif + diff --git a/panda/src/sgraphutil/quickRenderTraverser.I b/panda/src/sgraphutil/quickRenderTraverser.I new file mode 100644 index 0000000000..ca3f95b328 --- /dev/null +++ b/panda/src/sgraphutil/quickRenderTraverser.I @@ -0,0 +1,30 @@ +// Filename: quickRenderTraverser.I +// Created by: drose (24Jul01) +// +//////////////////////////////////////////////////////////////////// +// +// 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: QuickRenderTraverser::backward_arc +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void QuickRenderTraverser:: +backward_arc(NodeRelation *arc, NullTransitionWrapper &, + NullAttributeWrapper &, NullAttributeWrapper &, + const QuickRenderLevelState &) { + mark_backward_arc(arc); +} diff --git a/panda/src/sgraphutil/quickRenderTraverser.cxx b/panda/src/sgraphutil/quickRenderTraverser.cxx new file mode 100644 index 0000000000..b9afac372f --- /dev/null +++ b/panda/src/sgraphutil/quickRenderTraverser.cxx @@ -0,0 +1,167 @@ +// Filename: quickRenderTraverser.cxx +// Created by: drose (24Jul01) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "quickRenderTraverser.h" +#include "config_sgraphutil.h" + +#include "allAttributesWrapper.h" +#include "allTransitionsWrapper.h" +#include "graphicsStateGuardian.h" +#include "dftraverser.h" +#include "pruneTransition.h" +#include "geomNode.h" +#include "pStatTimer.h" + +TypeHandle QuickRenderTraverser::_type_handle; + +#ifndef CPPPARSER +PStatCollector QuickRenderTraverser::_draw_pcollector("Draw:Quick"); +#endif + +//////////////////////////////////////////////////////////////////// +// Function: QuickRenderTraverser::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +QuickRenderTraverser:: +QuickRenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type, + const ArcChain &arc_chain) : + RenderTraverser(gsg, graph_type, arc_chain) +{ + _root = (Node *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: QuickRenderTraverser::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +QuickRenderTraverser:: +~QuickRenderTraverser() { +} + +//////////////////////////////////////////////////////////////////// +// Function: QuickRenderTraverser::traverse +// Access: Public, Virtual +// Description: This performs a normal, complete cull-and-render +// traversal using this QuickRenderTraverser object. State is +// saved within the QuickRenderTraverser object so that the +// next frame will be processed much more quickly than +// the first frame. +//////////////////////////////////////////////////////////////////// +void QuickRenderTraverser:: +traverse(Node *root, + const AllAttributesWrapper &initial_state, + const AllTransitionsWrapper &net_trans) { + // Statistics + PStatTimer timer(_draw_pcollector); + + _root = root; + _initial_state.apply_from(initial_state, net_trans); + + QuickRenderLevelState level_state; + level_state._as_of = UpdateSeq::initial(); + + df_traverse(root, *this, + NullAttributeWrapper(), level_state, _graph_type); + + _root = (Node *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: QuickRenderTraverser::forward_arc +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +bool QuickRenderTraverser:: +forward_arc(NodeRelation *arc, NullTransitionWrapper &, + NullAttributeWrapper &, NullAttributeWrapper &, + QuickRenderLevelState &level_state) { + if (arc->has_transition(PruneTransition::get_class_type())) { + return false; + } + + Node *node = arc->get_child(); + + if (node->get_num_parents(_graph_type) != 1) { + const UpRelationPointers &urp = node->find_connection(_graph_type).get_up(); + int num_parents = urp.size(); + + sgraphutil_cat.warning() + << "Cannot support instancing via QuickRenderTraverser; " + << *node << " has " << num_parents << " parents.\n" + << " parents are: "; + nassertr(num_parents > 1, false); + + NodeRelation *parent_arc = urp[0]; + sgraphutil_cat.warning(false) << *parent_arc->get_parent(); + for (int i = 1; i < num_parents; i++) { + parent_arc = urp[i]; + sgraphutil_cat.warning(false) + << ", " << *parent_arc->get_parent(); + } + sgraphutil_cat.warning(false) << "\n"; + + return false; + } + + if (implicit_app_traversal) { + node->app_traverse(); + } + node->draw_traverse(); + + // We have to get a new _now timestamp, just in case either of the + // above traversals changed it. + UpdateSeq now = last_graph_update(_graph_type); + + UpdateSeq last_update = arc->get_last_update(); + if (level_state._as_of < last_update) { + level_state._as_of = last_update; + } + + mark_forward_arc(arc); + _gsg->_nodes_pcollector.add_level(1); + + if (node->is_of_type(GeomNode::get_class_type())) { + _gsg->_geom_nodes_pcollector.add_level(1); + + // Determine the net transition to this GeomNode, and render it. + GeomNode *gnode = DCAST(GeomNode, node); + AllTransitionsWrapper trans; + Node *top_subtree = + wrt_subtree(arc, NULL, + level_state._as_of, now, + trans, _graph_type); + + /* + cerr << "top_subtree is " << (void *)top_subtree; + if (top_subtree != (Node *)NULL) { + cerr << " is " << *top_subtree; + } + cerr << "\n"; + */ + + AllAttributesWrapper attrib; + attrib.apply_from(_initial_state, trans); + + _gsg->set_state(attrib.get_attributes(), true); + gnode->draw(_gsg); + } + + return true; +} diff --git a/panda/src/sgraphutil/quickRenderTraverser.h b/panda/src/sgraphutil/quickRenderTraverser.h new file mode 100644 index 0000000000..f52ce39d8e --- /dev/null +++ b/panda/src/sgraphutil/quickRenderTraverser.h @@ -0,0 +1,99 @@ +// Filename: quickRenderTraverser.h +// Created by: drose (24Jul01) +// +//////////////////////////////////////////////////////////////////// +// +// 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 QUICKRENDERTRAVERSER_H +#define QUICKRENDERTRAVERSER_H + +#include "pandabase.h" + +#include "quickRenderLevelState.h" + +#include "renderTraverser.h" +#include "traverserVisitor.h" +#include "nullTransitionWrapper.h" +#include "nullAttributeWrapper.h" +#include "allAttributesWrapper.h" +#include "pStatCollector.h" + +class GraphicsStateGuardian; +class AllTransitionsWrapper; + +//////////////////////////////////////////////////////////////////// +// Class : QuickRenderTraverser +// Description : A small RenderTraverser that performs a left-to-right +// depth-first traversal of the scene graph, rendering +// nodes as it encounters them, like a +// DirectRenderTraverser. +// +// However, it does not support instancing, nor +// view-frustum culling. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA QuickRenderTraverser : + public RenderTraverser, + public TraverserVisitor { +public: + QuickRenderTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type, + const ArcChain &arc_chain = ArcChain()); + virtual ~QuickRenderTraverser(); + + virtual void traverse(Node *root, + const AllAttributesWrapper &initial_state, + const AllTransitionsWrapper &net_trans); + +public: + // These methods, from parent class TraverserVisitor, define the + // behavior of the RenderTraverser as it traverses the graph. + // Normally you would never call these directly. + bool forward_arc(NodeRelation *arc, NullTransitionWrapper &trans, + NullAttributeWrapper &pre, NullAttributeWrapper &post, + QuickRenderLevelState &level_state); + + INLINE void + backward_arc(NodeRelation *arc, NullTransitionWrapper &trans, + NullAttributeWrapper &pre, NullAttributeWrapper &post, + const QuickRenderLevelState &level_state); + +private: + Node *_root; + AllAttributesWrapper _initial_state; + + // Statistics + static PStatCollector _draw_pcollector; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + RenderTraverser::init_type(); + register_type(_type_handle, "QuickRenderTraverser", + RenderTraverser::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; +}; + +#include "quickRenderTraverser.I" + +#endif + diff --git a/panda/src/sgraphutil/sgraphutil_composite2.cxx b/panda/src/sgraphutil/sgraphutil_composite2.cxx index cba5c8d62e..61e521b7ba 100644 --- a/panda/src/sgraphutil/sgraphutil_composite2.cxx +++ b/panda/src/sgraphutil/sgraphutil_composite2.cxx @@ -1,4 +1,5 @@ #include "get_rel_pos.cxx" +#include "quickRenderTraverser.cxx" #include "sceneGraphAnalyzer.cxx" #include "sceneGraphReducer.cxx"