Panda3D

sceneGraphAnalyzerMeter.cxx

00001 // Filename: sceneGraphAnalyzerMeter.cxx
00002 // Created by:  pratt (14Feb07)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "sceneGraphAnalyzerMeter.h"
00016 #include "camera.h"
00017 #include "displayRegion.h"
00018 #include "orthographicLens.h"
00019 #include "config_grutil.h"
00020 #include "depthTestAttrib.h"
00021 #include "depthWriteAttrib.h"
00022 #include "pStatTimer.h"
00023 #include <stdio.h>  // For sprintf/snprintf
00024 
00025 PStatCollector SceneGraphAnalyzerMeter::_show_analyzer_pcollector("*:Show scene graph analysis");
00026 
00027 TypeHandle SceneGraphAnalyzerMeter::_type_handle;
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: SceneGraphAnalyzerMeter::Constructor
00031 //       Access: Published
00032 //  Description: 
00033 ////////////////////////////////////////////////////////////////////
00034 SceneGraphAnalyzerMeter::
00035 SceneGraphAnalyzerMeter(const string &name, PandaNode *node) : TextNode(name) {
00036   set_cull_callback();
00037 
00038   Thread *current_thread = Thread::get_current_thread();
00039 
00040   _update_interval = scene_graph_analyzer_meter_update_interval;
00041   _last_update = 0.0f;
00042   _node = node;
00043   _clock_object = ClockObject::get_global_clock();
00044 
00045   set_align(A_left);
00046   set_transform(LMatrix4::scale_mat(scene_graph_analyzer_meter_scale) * 
00047                 LMatrix4::translate_mat(LVector3::rfu(-1.0f + scene_graph_analyzer_meter_side_margins * scene_graph_analyzer_meter_scale, 0.0f, 1.0f - scene_graph_analyzer_meter_scale)));
00048   set_card_color(0.0f, 0.0f, 0.0f, 0.4);
00049   set_card_as_margin(scene_graph_analyzer_meter_side_margins, scene_graph_analyzer_meter_side_margins, 0.1f, 0.0f);
00050   set_usage_hint(Geom::UH_client);
00051 
00052   do_update(current_thread);
00053 }
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //     Function: SceneGraphAnalyzerMeter::Destructor
00057 //       Access: Published, Virtual
00058 //  Description: 
00059 ////////////////////////////////////////////////////////////////////
00060 SceneGraphAnalyzerMeter::
00061 ~SceneGraphAnalyzerMeter() {
00062   clear_window();
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: SceneGraphAnalyzerMeter::setup_window
00067 //       Access: Published
00068 //  Description: Sets up the frame rate meter to create a
00069 //               DisplayRegion to render itself into the indicated
00070 //               window.
00071 ////////////////////////////////////////////////////////////////////
00072 void SceneGraphAnalyzerMeter::
00073 setup_window(GraphicsOutput *window) {
00074   clear_window();
00075 
00076   _window = window;
00077 
00078   _root = NodePath("scene_graph_analyzer_root");
00079   _root.attach_new_node(this);
00080 
00081   CPT(RenderAttrib) dt = DepthTestAttrib::make(DepthTestAttrib::M_none);
00082   CPT(RenderAttrib) dw = DepthWriteAttrib::make(DepthWriteAttrib::M_off);
00083   _root.node()->set_attrib(dt, 1);
00084   _root.node()->set_attrib(dw, 1);
00085   _root.set_material_off(1);
00086   _root.set_two_sided(1, 1);
00087 
00088   // Create a display region that covers the entire window.
00089   _display_region = _window->make_display_region();
00090   _display_region->set_sort(scene_graph_analyzer_meter_layer_sort);
00091 
00092   // Finally, we need a camera to associate with the display region.
00093   PT(Camera) camera = new Camera("scene_graph_analyzer_camera");
00094   NodePath camera_np = _root.attach_new_node(camera);
00095 
00096   PT(Lens) lens = new OrthographicLens;
00097   
00098   static const PN_stdfloat left = -1.0f;
00099   static const PN_stdfloat right = 1.0f;
00100   static const PN_stdfloat bottom = -1.0f;
00101   static const PN_stdfloat top = 1.0f;
00102   lens->set_film_size(right - left, top - bottom);
00103   lens->set_film_offset((right + left) * 0.5, (top + bottom) * 0.5);
00104   lens->set_near_far(-1000, 1000);
00105   
00106   camera->set_lens(lens);
00107   camera->set_scene(_root);
00108   _display_region->set_camera(camera_np);
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: SceneGraphAnalyzerMeter::clear_window
00113 //       Access: Published
00114 //  Description: Undoes the effect of a previous call to
00115 //               setup_window().
00116 ////////////////////////////////////////////////////////////////////
00117 void SceneGraphAnalyzerMeter::
00118 clear_window() {
00119   if (_window != (GraphicsOutput *)NULL) {
00120     _window->remove_display_region(_display_region);
00121     _window = (GraphicsOutput *)NULL;
00122     _display_region = (DisplayRegion *)NULL;
00123   }
00124   _root = NodePath();
00125 }
00126 
00127 ////////////////////////////////////////////////////////////////////
00128 //     Function: SceneGraphAnalyzerMeter::cull_callback
00129 //       Access: Protected, Virtual
00130 //  Description: This function will be called during the cull
00131 //               traversal to perform any additional operations that
00132 //               should be performed at cull time.  This may include
00133 //               additional manipulation of render state or additional
00134 //               visible/invisible decisions, or any other arbitrary
00135 //               operation.
00136 //
00137 //               Note that this function will *not* be called unless
00138 //               set_cull_callback() is called in the constructor of
00139 //               the derived class.  It is necessary to call
00140 //               set_cull_callback() to indicated that we require
00141 //               cull_callback() to be called.
00142 //
00143 //               By the time this function is called, the node has
00144 //               already passed the bounding-volume test for the
00145 //               viewing frustum, and the node's transform and state
00146 //               have already been applied to the indicated
00147 //               CullTraverserData object.
00148 //
00149 //               The return value is true if this node should be
00150 //               visible, or false if it should be culled.
00151 ////////////////////////////////////////////////////////////////////
00152 bool SceneGraphAnalyzerMeter::
00153 cull_callback(CullTraverser *trav, CullTraverserData &data) {
00154   Thread *current_thread = trav->get_current_thread();
00155 
00156   // Statistics
00157   PStatTimer timer(_show_analyzer_pcollector, current_thread);
00158   
00159   // Check to see if it's time to update.
00160   double now = _clock_object->get_frame_time(current_thread);
00161   double elapsed = now - _last_update;
00162   if (elapsed < 0.0 || elapsed >= _update_interval) {
00163     do_update(current_thread);
00164   }
00165 
00166   return TextNode::cull_callback(trav, data);
00167 }
00168 
00169 ////////////////////////////////////////////////////////////////////
00170 //     Function: SceneGraphAnalyzerMeter::do_update
00171 //       Access: Private
00172 //  Description: Resets the text according to the current frame rate.
00173 ////////////////////////////////////////////////////////////////////
00174 void SceneGraphAnalyzerMeter::
00175 do_update(Thread *current_thread) {
00176   _last_update = _clock_object->get_frame_time(current_thread);
00177 
00178   _scene_graph_analyzer.clear();
00179   _scene_graph_analyzer.add_node( _node );
00180 
00181   static const size_t buffer_size = 1024;
00182   char buffer[buffer_size];
00183 
00184   const char *pattern = "Nodes: %d\n"
00185                         "Instances: %d\n"
00186                         "Transforms: %d\n"
00187                         "Nodes with Attribs: %d\n"
00188                         "GeomNodes: %d\n"
00189                         "Geoms: %d\n"
00190                         "GeomVertexDatas: %d\n"
00191                         "Vertices: %d\n"
00192                         "Normals: %d\n"
00193                         "TexCoords: %d\n"
00194                         "Tris: %d\n"
00195                         "Lines: %d\n"
00196                         "Points: %d\n"
00197                         "Texture memory: %.1f KB\n";
00198 
00199 #if defined(WIN32_VC) || defined(WIN64_VC)
00200   _snprintf(buffer, buffer_size, pattern,
00201           _scene_graph_analyzer.get_num_nodes(),
00202           _scene_graph_analyzer.get_num_instances(),
00203           _scene_graph_analyzer.get_num_transforms(),
00204           _scene_graph_analyzer.get_num_nodes_with_attribs(),
00205           _scene_graph_analyzer.get_num_geom_nodes(),
00206           _scene_graph_analyzer.get_num_geoms(),
00207           _scene_graph_analyzer.get_num_geom_vertex_datas(),
00208           _scene_graph_analyzer.get_num_vertices(),
00209           _scene_graph_analyzer.get_num_normals(),
00210           _scene_graph_analyzer.get_num_texcoords(),
00211           _scene_graph_analyzer.get_num_tris(),
00212           _scene_graph_analyzer.get_num_lines(),
00213           _scene_graph_analyzer.get_num_points(),
00214           _scene_graph_analyzer.get_texture_bytes()/1024.0);
00215 #else
00216   snprintf(buffer, buffer_size, pattern,
00217            _scene_graph_analyzer.get_num_nodes(),
00218            _scene_graph_analyzer.get_num_instances(),
00219            _scene_graph_analyzer.get_num_transforms(),
00220            _scene_graph_analyzer.get_num_nodes_with_attribs(),
00221            _scene_graph_analyzer.get_num_geom_nodes(),
00222            _scene_graph_analyzer.get_num_geoms(),
00223            _scene_graph_analyzer.get_num_geom_vertex_datas(),
00224            _scene_graph_analyzer.get_num_vertices(),
00225            _scene_graph_analyzer.get_num_normals(),
00226            _scene_graph_analyzer.get_num_texcoords(),
00227            _scene_graph_analyzer.get_num_tris(),
00228            _scene_graph_analyzer.get_num_lines(),
00229            _scene_graph_analyzer.get_num_points(),
00230            _scene_graph_analyzer.get_texture_bytes()/1024.0);
00231 #endif
00232   nassertv(strlen(buffer) < buffer_size);
00233 
00234   if (get_text() == buffer) {
00235     // Never mind; the data hasn't changed.
00236     return;
00237   }
00238 
00239   set_text(buffer);
00240 }
 All Classes Functions Variables Enumerations