David Rose 15 years ago
parent
commit
f85ccdf0f3

+ 3 - 3
panda/src/speedtree/config_speedtree.cxx

@@ -56,9 +56,9 @@ ConfigVariableDouble speedtree_max_anisotropy
 ConfigVariableBool speedtree_horizontal_billboards
 ("speedtree-horizontal-billboards", true,
  PRC_DESC("Set this true to allow the use of horizontal billboards in "
-	  "SpeedTree, or false to disallow them.  Documentation on this "
-	  "feature is sparse, but presumably enabling them increases "
-	  "visual quality and also causes a greater performance impact."));
+	  "SpeedTree, or false to disallow them.  Horizontal billboards "
+	  "may be defined for some trees to provide a billboard LOD "
+	  "when the tree is seen from above."));
 
 ConfigVariableDouble speedtree_alpha_test_scalar
 ("speedtree-alpha-test-scalar", 0.57,

+ 44 - 17
panda/src/speedtree/speedTreeNode.cxx

@@ -33,6 +33,7 @@
 #include "loader.h"
 #include "deg_2_rad.h"
 #include "sceneGraphReducer.h"
+#include "pStatTimer.h"
 
 #ifdef SPEEDTREE_OPENGL
 #include "glew/glew.h"
@@ -47,6 +48,16 @@ bool SpeedTreeNode::_done_first_init;
 TypeHandle SpeedTreeNode::_type_handle;
 TypeHandle SpeedTreeNode::DrawCallback::_type_handle;
 
+PStatCollector SpeedTreeNode::_cull_speedtree_pcollector("Cull:SpeedTree");
+PStatCollector SpeedTreeNode::_cull_speedtree_shadows_pcollector("Cull:SpeedTree:Shadows");
+PStatCollector SpeedTreeNode::_cull_speedtree_trees_pcollector("Cull:SpeedTree:Trees");
+PStatCollector SpeedTreeNode::_cull_speedtree_terrain_pcollector("Cull:SpeedTree:Terrain");
+PStatCollector SpeedTreeNode::_draw_speedtree_pcollector("Draw:SpeedTree");
+PStatCollector SpeedTreeNode::_draw_speedtree_shadows_pcollector("Draw:SpeedTree:Shadows");
+PStatCollector SpeedTreeNode::_draw_speedtree_trees_pcollector("Draw:SpeedTree:Trees");
+PStatCollector SpeedTreeNode::_draw_speedtree_terrain_pcollector("Draw:SpeedTree:Terrain");
+PStatCollector SpeedTreeNode::_draw_speedtree_terrain_update_pcollector("Draw:SpeedTree:Terrain:Update");
+
 ////////////////////////////////////////////////////////////////////
 //     Function: SpeedTreeNode::Constructor
 //       Access: Published
@@ -873,6 +884,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
   if (!_is_valid) {
     return false;
   }
+  PStatTimer timer(_cull_speedtree_pcollector);
 
   GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, trav->get_gsg());
   nassertr(gsg != (GraphicsStateGuardian *)NULL, true);
@@ -948,6 +960,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
   if (dlight != (DirectionalLight *)NULL) {
     CPT(TransformState) transform = dlight_np.get_transform(trav->get_scene()->get_scene_root().get_parent());
     LVector3f dir = dlight->get_direction() * transform->get_mat();
+    dir.normalize();
     _light_dir = SpeedTree::Vec3(dir[0], dir[1], dir[2]);
     diffuse_color = dlight->get_color();
 
@@ -1372,6 +1385,7 @@ validate_api(GraphicsStateGuardian *gsg) {
 ////////////////////////////////////////////////////////////////////
 void SpeedTreeNode::
 draw_callback(CallbackData *data) {
+  PStatTimer timer(_draw_speedtree_pcollector);
   GeomDrawCallbackData *geom_cbdata;
   DCAST_INTO_V(geom_cbdata, data);
 
@@ -1389,6 +1403,7 @@ draw_callback(CallbackData *data) {
     // Update the shadow maps.  TODO: consider updating these only
     // every once in a while, instead of every frame, as a simple
     // optimization.
+    PStatTimer timer(_draw_speedtree_shadows_pcollector);
     render_forest_into_shadow_maps();
     _forest_render.ClearBoundTextures( );
   }
@@ -1400,6 +1415,7 @@ draw_callback(CallbackData *data) {
   }
   
   if (has_terrain()) {
+    PStatTimer timer1(_draw_speedtree_terrain_pcollector);
     // Is this needed for terrain?
     _terrain_render.UploadShaderConstants
       (&_forest_render, _light_dir, 
@@ -1424,23 +1440,28 @@ draw_callback(CallbackData *data) {
     }
   }
 
-  //  SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TESTING;
-  //  SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TO_COVERAGE;
-  //  SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_BLENDING;
-  SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_NOTHING;
-  set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode(mode));
-  
-  bool branches = _forest_render.RenderBranches(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
-  bool fronds = _forest_render.RenderFronds(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
-  bool leaf_meshes = _forest_render.RenderLeafMeshes(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
-  bool leaf_cards = _forest_render.RenderLeafCards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
-  bool billboards = _forest_render.RenderBillboards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
+  {
+    // Now draw the actual trees.
+    PStatTimer timer1(_draw_speedtree_trees_pcollector);
 
-  if (!branches || !fronds || !leaf_meshes || !leaf_cards || !billboards) {
-    speedtree_cat.warning()
-      << "Failed to render forest completely: "
-      << branches << " " << fronds << " " << leaf_meshes << " " << leaf_cards << " " << billboards << "\n";
-    write_error(speedtree_cat.warning());
+    //  SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TESTING;
+    //  SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TO_COVERAGE;
+    //  SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_BLENDING;
+    SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_NOTHING;
+    set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode(mode));
+    
+    bool branches = _forest_render.RenderBranches(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
+    bool fronds = _forest_render.RenderFronds(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
+    bool leaf_meshes = _forest_render.RenderLeafMeshes(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
+    bool leaf_cards = _forest_render.RenderLeafCards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
+    bool billboards = _forest_render.RenderBillboards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
+    
+    if (!branches || !fronds || !leaf_meshes || !leaf_cards || !billboards) {
+      speedtree_cat.warning()
+	<< "Failed to render forest completely: "
+	<< branches << " " << fronds << " " << leaf_meshes << " " << leaf_cards << " " << billboards << "\n";
+      write_error(speedtree_cat.warning());
+    }
   }
 
   _forest_render.EndRender();
@@ -1637,6 +1658,7 @@ setup_for_render(GraphicsStateGuardian *gsg) {
     _needs_repopulate = false;
   }
   if (has_terrain()) {
+    PStatTimer timer1(_draw_speedtree_terrain_update_pcollector);
     update_terrain_cells();
   }
 }
@@ -1649,12 +1671,17 @@ setup_for_render(GraphicsStateGuardian *gsg) {
 ////////////////////////////////////////////////////////////////////
 void SpeedTreeNode::
 cull_forest() {
-  _forest_render.CullAndComputeLOD(_view, _visible_trees);
+  {
+    PStatTimer timer1(_cull_speedtree_trees_pcollector);
+    _forest_render.CullAndComputeLOD(_view, _visible_trees);
+  }
   if (has_terrain()) {
+    PStatTimer timer1(_cull_speedtree_terrain_pcollector);
     _terrain_render.CullAndComputeLOD(_view, _visible_terrain);
   }
 
   if (_forest_render.ShadowsAreEnabled()) {
+    PStatTimer timer1(_cull_speedtree_shadows_pcollector);
     for (int smi = 0; smi < (int)_shadow_infos.size(); ++smi) {
       SpeedTree::CView &light_view = _shadow_infos[smi]._light_view;
       SpeedTree::SForestCullResultsRender &light_cull = _shadow_infos[smi]._light_cull;

+ 11 - 1
panda/src/speedtree/speedTreeNode.h

@@ -25,7 +25,7 @@
 #include "loaderOptions.h"
 #include "transformState.h"
 #include "nodePath.h"
-
+#include "pStatCollector.h"
 #include "speedtree_api.h"
 
 class Loader;
@@ -240,6 +240,16 @@ private:
   static bool _authorized;
   static bool _done_first_init;
 
+  static PStatCollector _cull_speedtree_pcollector;
+  static PStatCollector _cull_speedtree_shadows_pcollector;
+  static PStatCollector _cull_speedtree_trees_pcollector;
+  static PStatCollector _cull_speedtree_terrain_pcollector;
+  static PStatCollector _draw_speedtree_pcollector;
+  static PStatCollector _draw_speedtree_shadows_pcollector;
+  static PStatCollector _draw_speedtree_trees_pcollector;
+  static PStatCollector _draw_speedtree_terrain_pcollector;
+  static PStatCollector _draw_speedtree_terrain_update_pcollector;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &dg);