Browse Source

more pstats options with z-buffer

David Rose 20 years ago
parent
commit
5173168621

+ 6 - 0
panda/src/cull/config_cull.cxx

@@ -47,6 +47,12 @@ ConfigVariableDouble octree_multiassign_ratio
           "order to be assigned to the node itself.  If the object is smaller "
           "than this, it will be multiply assigned to the node's children."));
 
+ConfigVariableBool show_octree
+("show-octree", false,
+ PRC_DESC("When true, visualizes the octree created for the hierarchical "
+          "Z-buffer algorithm, by drawing wireframe cubes around each "
+          "nonempty octree cell."));
+
 ////////////////////////////////////////////////////////////////////
 //     Function: init_libcull
 //  Description: Initializes the library.  This must be called at

+ 2 - 0
panda/src/cull/config_cull.h

@@ -24,6 +24,7 @@
 #include "dconfig.h"
 #include "configVariableInt.h"
 #include "configVariableDouble.h"
+#include "configVariableBool.h"
 
 class DSearchPath;
 
@@ -32,6 +33,7 @@ NotifyCategoryDecl(cull, EXPCL_PANDA, EXPTP_PANDA);
 
 extern ConfigVariableInt max_objects_per_octree_node;
 extern ConfigVariableDouble octree_multiassign_ratio;
+extern ConfigVariableBool show_octree;
 
 extern EXPCL_PANDA void init_libcull();
 

+ 14 - 1
panda/src/cull/cullBinHierarchicalZBuffer.I

@@ -59,7 +59,8 @@ operator = (const CullBinHierarchicalZBuffer::ObjectData &copy) {
 ////////////////////////////////////////////////////////////////////
 INLINE CullBinHierarchicalZBuffer::
 CullBinHierarchicalZBuffer(const string &name, GraphicsStateGuardianBase *gsg) :
-  CullBin(name, gsg)
+  CullBin(name, gsg),
+  _draw_occlusion_pcollector(_draw_this_pcollector, "Occlusion")
 {
   nassertv(_gsg->get_supports_occlusion_query());
 }
@@ -75,6 +76,17 @@ initial_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
   _objects.push_back(object_data);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinHierarchicalZBuffer::OctreeNode::get_total_num_objects
+//       Access: Public
+//  Description: Returns the total number of objects in this node and
+//               all nested nodes.
+////////////////////////////////////////////////////////////////////
+INLINE int CullBinHierarchicalZBuffer::OctreeNode::
+get_total_num_objects() const {
+  return _total_num_objects;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CullBinHierarchicalZBuffer::OctreeNode::reassign
 //       Access: Public
@@ -84,6 +96,7 @@ initial_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
 ////////////////////////////////////////////////////////////////////
 INLINE void CullBinHierarchicalZBuffer::OctreeNode::
 reassign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
+  ++_total_num_objects;
   if (object_data._bounds->get_radius() / _half_side >= octree_multiassign_ratio) {
     // The object is large enough to keep in this node.
     //cerr << "    reassigning.\n";

+ 20 - 19
panda/src/cull/cullBinHierarchicalZBuffer.cxx

@@ -32,6 +32,7 @@
 #include "thread.h"
 
 PStatCollector CullBinHierarchicalZBuffer::_wait_occlusion_pcollector("Wait:Occlusion test");
+PStatCollector CullBinHierarchicalZBuffer::_geoms_occluded_pcollector("Geoms:Occluded");
 
 PT(Geom) CullBinHierarchicalZBuffer::_octree_solid_test;
 PT(Geom) CullBinHierarchicalZBuffer::_octree_wireframe_viz;
@@ -160,8 +161,13 @@ draw() {
       // The octree cell is at least partially visible.  Draw it, and
       // continue recursion.
       pending._octree_node->draw(*this);
+      if (show_octree) {
+        pending._octree_node->draw_wireframe(*this);
+      }
     } else {
-      pending._octree_node->draw_wireframe(*this);
+      // The octree cell is completely occluded.  Don't draw any of
+      // it, and don't recurse into it.
+      _geoms_occluded_pcollector.add_level(pending._octree_node->get_total_num_objects());
     }
     _pending_nodes.pop_front();
   }
@@ -175,6 +181,7 @@ draw() {
 ////////////////////////////////////////////////////////////////////
 CullBinHierarchicalZBuffer::OctreeNode::
 OctreeNode() {
+  _total_num_objects = 0;
   for (int i = 0; i < 8; ++i) {
     _corners[i] = (OctreeNode *)NULL;
   }
@@ -190,6 +197,7 @@ OctreeNode(float mid_x, float mid_y, float mid_z, float half_side) :
   _mid(mid_x, mid_y, mid_z),
   _half_side(half_side)
 {
+  _total_num_objects = 0;
   for (int i = 0; i < 8; ++i) {
     _corners[i] = (OctreeNode *)NULL;
   }
@@ -254,10 +262,9 @@ make_initial_bounds() {
 ////////////////////////////////////////////////////////////////////
 void CullBinHierarchicalZBuffer::OctreeNode::
 group_objects() {
-  //cerr << "group_objects, " << _objects.size() << " objects.\n";
   if ((int)_objects.size() <= max_objects_per_octree_node) {
     // No need to do any more subdividing.
-    //cerr << "  small enough.\n";
+    _total_num_objects += (int)_objects.size();
     return;
   }
 
@@ -268,7 +275,6 @@ group_objects() {
 
   Objects::const_iterator oi;
   for (oi = old_objects.begin(); oi != old_objects.end(); ++oi) {
-    //cerr << "  object " << (oi - old_objects.begin()) << "\n";
     const ObjectData &object_data = (*oi);
     const LPoint3f &c = object_data._bounds->get_center();
     float r = object_data._bounds->get_radius();
@@ -354,7 +360,7 @@ group_objects() {
 //               occlusion query object representing this test.
 ////////////////////////////////////////////////////////////////////
 PT(OcclusionQueryContext) CullBinHierarchicalZBuffer::OctreeNode::
-occlusion_test(GraphicsStateGuardianBase *gsg) {
+occlusion_test(CullBinHierarchicalZBuffer &bin) {
   // Draw the bounding volume for visualization.  This is
   // complicated because we're doing this at such a low level, here
   // in the middle of the draw task--we've already completed the
@@ -364,21 +370,22 @@ occlusion_test(GraphicsStateGuardianBase *gsg) {
   CPT(TransformState) net_transform = TransformState::make_pos_hpr_scale
     (_mid, LVecBase3f(0.0f, 0.0f, 0.0f), 
      LVecBase3f(_half_side, _half_side, _half_side));
-  CPT(TransformState) world_transform = gsg->get_scene()->get_world_transform();
+  CPT(TransformState) world_transform = bin._gsg->get_scene()->get_world_transform();
   CPT(TransformState) modelview_transform = world_transform->compose(net_transform);
   
   CPT(RenderState) state = get_octree_solid_test_state();
-  PT(GeomMunger) munger = gsg->get_geom_munger(state);
+  PT(GeomMunger) munger = bin._gsg->get_geom_munger(state);
   
   CPT(Geom) viz = get_octree_solid_test();
   CPT(GeomVertexData) munged_data = viz->get_vertex_data();
   munger->munge_geom(viz, munged_data);
   
-  gsg->set_state_and_transform(state, modelview_transform);
+  bin._gsg->set_state_and_transform(state, modelview_transform);
 
-  gsg->begin_occlusion_query();
-  viz->draw(gsg, munger, munged_data);
-  return gsg->end_occlusion_query();
+  PStatTimer timer(bin._draw_occlusion_pcollector);
+  bin._gsg->begin_occlusion_query();
+  viz->draw(bin._gsg, munger, munged_data);
+  return bin._gsg->end_occlusion_query();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -395,10 +402,7 @@ draw(CullBinHierarchicalZBuffer &bin) {
     Objects::const_iterator oi;
     for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
       CullableObject *object = (*oi)._object;
-      if (object->_already_drawn) {
-        //cerr << "skipping object.\n";
-      } else {
-        //cerr << "drawing object.\n";
+      if (!object->_already_drawn) {
         CullHandler::draw(object, bin._gsg);
         object->_already_drawn = true;
       }
@@ -409,7 +413,7 @@ draw(CullBinHierarchicalZBuffer &bin) {
     if (_corners[i] != (OctreeNode *)NULL) {
       PendingNode pending;
       pending._octree_node = _corners[i];
-      pending._query = _corners[i]->occlusion_test(bin._gsg);
+      pending._query = _corners[i]->occlusion_test(bin);
       bin._pending_nodes.push_back(pending);
     }
   }
@@ -560,8 +564,6 @@ multi_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
   const LPoint3f &c = object_data._bounds->get_center();
   float r = object_data._bounds->get_radius();
 
-  //cerr << "multi_assigning " << c << " vs. " << _mid << "\n";
-  
   if (c[0] + r <= _mid[0]) {
     // -X
     if (c[1] + r <= _mid[1]) {
@@ -726,7 +728,6 @@ multi_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
 ////////////////////////////////////////////////////////////////////
 INLINE void CullBinHierarchicalZBuffer::OctreeNode::
 make_corner(int index) {
-  //cerr << "making corner " << hex << index << dec << "\n";
   nassertv(_corners[index] == NULL);
 
   OctreeNode *node = NULL;

+ 6 - 1
panda/src/cull/cullBinHierarchicalZBuffer.h

@@ -98,18 +98,21 @@ private:
 
     void make_initial_bounds();
     void group_objects();
-    PT(OcclusionQueryContext) occlusion_test(GraphicsStateGuardianBase *gsg);
+    PT(OcclusionQueryContext) occlusion_test(CullBinHierarchicalZBuffer &bin);
     void draw(CullBinHierarchicalZBuffer &bin);
     void draw_wireframe(CullBinHierarchicalZBuffer &bin);
 
     INLINE void initial_assign(const ObjectData &object_data);
 
+    INLINE int get_total_num_objects() const;
+
   private:
     INLINE void reassign(const ObjectData &object_data);
     INLINE void assign_to_corner(int index, const ObjectData &object_data);
     void multi_assign(const ObjectData &object_data);
     void make_corner(int index);
 
+    int _total_num_objects;
     Objects _objects;
     OctreeNode *_corners[8];
     LPoint3f _mid;
@@ -129,7 +132,9 @@ private:
   typedef pdeque<PendingNode> PendingNodes;
   PendingNodes _pending_nodes;
 
+  PStatCollector _draw_occlusion_pcollector;
   static PStatCollector _wait_occlusion_pcollector;
+  static PStatCollector _geoms_occluded_pcollector;
 
   static PT(Geom) _octree_solid_test;
   static PT(Geom) _octree_wireframe_viz;

+ 2 - 1
panda/src/display/graphicsEngine.cxx

@@ -45,7 +45,7 @@
   #include <sys/time.h>
 #endif
 
-PStatCollector GraphicsEngine::_wait_pcollector("Wait");
+PStatCollector GraphicsEngine::_wait_pcollector("Wait:Thread sync");
 PStatCollector GraphicsEngine::_cycle_pcollector("App:Cycle");
 PStatCollector GraphicsEngine::_app_pcollector("App:Show code");
 PStatCollector GraphicsEngine::_render_frame_pcollector("App:render_frame");
@@ -640,6 +640,7 @@ render_frame() {
   CullTraverser::_nodes_pcollector.clear_level();
   CullTraverser::_geom_nodes_pcollector.clear_level();
   CullTraverser::_geoms_pcollector.clear_level();
+  CullTraverser::_geoms_occluded_pcollector.clear_level();
   GeomCacheManager::_geom_cache_active_pcollector.clear_level();
   GeomCacheManager::_geom_cache_record_pcollector.clear_level();
   GeomCacheManager::_geom_cache_erase_pcollector.clear_level();

+ 1 - 0
panda/src/pgraph/cullTraverser.cxx

@@ -40,6 +40,7 @@
 PStatCollector CullTraverser::_nodes_pcollector("Nodes");
 PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
 PStatCollector CullTraverser::_geoms_pcollector("Geoms");
+PStatCollector CullTraverser::_geoms_occluded_pcollector("Geoms:Occluded");
 
 TypeHandle CullTraverser::_type_handle;
 

+ 1 - 0
panda/src/pgraph/cullTraverser.h

@@ -93,6 +93,7 @@ public:
   static PStatCollector _nodes_pcollector;
   static PStatCollector _geom_nodes_pcollector;
   static PStatCollector _geoms_pcollector;
+  static PStatCollector _geoms_occluded_pcollector;
 
 private:
   void show_bounds(CullTraverserData &data, bool tight);

+ 4 - 1
panda/src/pstatclient/pStatProperties.cxx

@@ -108,7 +108,9 @@ struct LevelCollectorProperties {
 
 static TimeCollectorProperties time_properties[] = {
   { 1, "Wait",                             { 0.6, 0.6, 0.6 } },
-  { 0, "Wait:Mutex block",                 { 1.0, 0.0, 0.0 } },
+  { 0, "Wait:Mutex block",                 { 0.5, 0.0, 1.0 } },
+  { 1, "Wait:Thread sync",                 { 0.0, 1.0, 0.5 } },
+  { 1, "Wait:Occlusion test",              { 1.0, 0.5, 0.0 } },
   { 1, "App",                              { 0.0, 0.8, 0.4 },  1.0 / 30.0 },
   { 1, "App:Collisions",                   { 1.0, 0.5, 0.0 } },
   { 1, "App:Collisions:Reset",             { 0.0, 0.0, 0.5 } },
@@ -181,6 +183,7 @@ static LevelCollectorProperties level_properties[] = {
   { 1, "Nodes",                            { 0.4, 0.2, 0.8 },  "", 500.0 },
   { 1, "Nodes:GeomNodes",                  { 0.8, 0.2, 0.0 } },
   { 1, "Geoms",                            { 0.4, 0.8, 0.3 },  "", 500.0 },
+  { 1, "Geoms:Occluded",                   { 0.8, 0.2, 0.2 } },
   { 1, "Cull volumes",                     { 0.7, 0.6, 0.9 },  "", 500.0 },
   { 1, "Cull volumes:Transforms",          { 0.9, 0.6, 0.0 } },
   { 1, "State changes",                    { 1.0, 0.5, 0.2 },  "", 500.0 },