sceneGraphAnalyzerMeter.cxx 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // Filename: sceneGraphAnalyzerMeter.cxx
  2. // Created by: pratt (14Feb07)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #include "sceneGraphAnalyzerMeter.h"
  15. #include "camera.h"
  16. #include "displayRegion.h"
  17. #include "orthographicLens.h"
  18. #include "config_grutil.h"
  19. #include "depthTestAttrib.h"
  20. #include "depthWriteAttrib.h"
  21. #include "pStatTimer.h"
  22. #include <stdio.h> // For sprintf/snprintf
  23. PStatCollector SceneGraphAnalyzerMeter::_show_analyzer_pcollector("*:Show scene graph analysis");
  24. TypeHandle SceneGraphAnalyzerMeter::_type_handle;
  25. ////////////////////////////////////////////////////////////////////
  26. // Function: SceneGraphAnalyzerMeter::Constructor
  27. // Access: Published
  28. // Description:
  29. ////////////////////////////////////////////////////////////////////
  30. SceneGraphAnalyzerMeter::
  31. SceneGraphAnalyzerMeter(const string &name, PandaNode *node) : TextNode(name) {
  32. set_cull_callback();
  33. Thread *current_thread = Thread::get_current_thread();
  34. _update_interval = scene_graph_analyzer_meter_update_interval;
  35. _last_update = 0.0f;
  36. _node = node;
  37. _clock_object = ClockObject::get_global_clock();
  38. set_align(A_left);
  39. set_transform(LMatrix4::scale_mat(scene_graph_analyzer_meter_scale) *
  40. 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)));
  41. set_card_color(0.0f, 0.0f, 0.0f, 0.4);
  42. set_card_as_margin(scene_graph_analyzer_meter_side_margins, scene_graph_analyzer_meter_side_margins, 0.1f, 0.0f);
  43. set_usage_hint(Geom::UH_client);
  44. do_update(current_thread);
  45. }
  46. ////////////////////////////////////////////////////////////////////
  47. // Function: SceneGraphAnalyzerMeter::Destructor
  48. // Access: Published, Virtual
  49. // Description:
  50. ////////////////////////////////////////////////////////////////////
  51. SceneGraphAnalyzerMeter::
  52. ~SceneGraphAnalyzerMeter() {
  53. clear_window();
  54. }
  55. ////////////////////////////////////////////////////////////////////
  56. // Function: SceneGraphAnalyzerMeter::setup_window
  57. // Access: Published
  58. // Description: Sets up the frame rate meter to create a
  59. // DisplayRegion to render itself into the indicated
  60. // window.
  61. ////////////////////////////////////////////////////////////////////
  62. void SceneGraphAnalyzerMeter::
  63. setup_window(GraphicsOutput *window) {
  64. clear_window();
  65. _window = window;
  66. _root = NodePath("scene_graph_analyzer_root");
  67. _root.attach_new_node(this);
  68. CPT(RenderAttrib) dt = DepthTestAttrib::make(DepthTestAttrib::M_none);
  69. CPT(RenderAttrib) dw = DepthWriteAttrib::make(DepthWriteAttrib::M_off);
  70. _root.node()->set_attrib(dt, 1);
  71. _root.node()->set_attrib(dw, 1);
  72. _root.set_material_off(1);
  73. _root.set_two_sided(1, 1);
  74. // Create a display region that covers the entire window.
  75. _display_region = _window->make_display_region();
  76. _display_region->set_sort(scene_graph_analyzer_meter_layer_sort);
  77. // Finally, we need a camera to associate with the display region.
  78. PT(Camera) camera = new Camera("scene_graph_analyzer_camera");
  79. NodePath camera_np = _root.attach_new_node(camera);
  80. PT(Lens) lens = new OrthographicLens;
  81. static const PN_stdfloat left = -1.0f;
  82. static const PN_stdfloat right = 1.0f;
  83. static const PN_stdfloat bottom = -1.0f;
  84. static const PN_stdfloat top = 1.0f;
  85. lens->set_film_size(right - left, top - bottom);
  86. lens->set_film_offset((right + left) * 0.5, (top + bottom) * 0.5);
  87. lens->set_near_far(-1000, 1000);
  88. camera->set_lens(lens);
  89. camera->set_scene(_root);
  90. _display_region->set_camera(camera_np);
  91. }
  92. ////////////////////////////////////////////////////////////////////
  93. // Function: SceneGraphAnalyzerMeter::clear_window
  94. // Access: Published
  95. // Description: Undoes the effect of a previous call to
  96. // setup_window().
  97. ////////////////////////////////////////////////////////////////////
  98. void SceneGraphAnalyzerMeter::
  99. clear_window() {
  100. if (_window != (GraphicsOutput *)NULL) {
  101. _window->remove_display_region(_display_region);
  102. _window = (GraphicsOutput *)NULL;
  103. _display_region = (DisplayRegion *)NULL;
  104. }
  105. _root = NodePath();
  106. }
  107. ////////////////////////////////////////////////////////////////////
  108. // Function: SceneGraphAnalyzerMeter::cull_callback
  109. // Access: Protected, Virtual
  110. // Description: This function will be called during the cull
  111. // traversal to perform any additional operations that
  112. // should be performed at cull time. This may include
  113. // additional manipulation of render state or additional
  114. // visible/invisible decisions, or any other arbitrary
  115. // operation.
  116. //
  117. // Note that this function will *not* be called unless
  118. // set_cull_callback() is called in the constructor of
  119. // the derived class. It is necessary to call
  120. // set_cull_callback() to indicated that we require
  121. // cull_callback() to be called.
  122. //
  123. // By the time this function is called, the node has
  124. // already passed the bounding-volume test for the
  125. // viewing frustum, and the node's transform and state
  126. // have already been applied to the indicated
  127. // CullTraverserData object.
  128. //
  129. // The return value is true if this node should be
  130. // visible, or false if it should be culled.
  131. ////////////////////////////////////////////////////////////////////
  132. bool SceneGraphAnalyzerMeter::
  133. cull_callback(CullTraverser *trav, CullTraverserData &data) {
  134. Thread *current_thread = trav->get_current_thread();
  135. // Statistics
  136. PStatTimer timer(_show_analyzer_pcollector, current_thread);
  137. // Check to see if it's time to update.
  138. double now = _clock_object->get_frame_time(current_thread);
  139. double elapsed = now - _last_update;
  140. if (elapsed < 0.0 || elapsed >= _update_interval) {
  141. do_update(current_thread);
  142. }
  143. return TextNode::cull_callback(trav, data);
  144. }
  145. ////////////////////////////////////////////////////////////////////
  146. // Function: SceneGraphAnalyzerMeter::do_update
  147. // Access: Private
  148. // Description: Resets the text according to the current frame rate.
  149. ////////////////////////////////////////////////////////////////////
  150. void SceneGraphAnalyzerMeter::
  151. do_update(Thread *current_thread) {
  152. _last_update = _clock_object->get_frame_time(current_thread);
  153. _scene_graph_analyzer.clear();
  154. _scene_graph_analyzer.add_node( _node );
  155. static const size_t buffer_size = 1024;
  156. char buffer[buffer_size];
  157. const char *pattern = "Nodes: %d\n"
  158. "Instances: %d\n"
  159. "Transforms: %d\n"
  160. "Nodes with Attribs: %d\n"
  161. "GeomNodes: %d\n"
  162. "Geoms: %d\n"
  163. "GeomVertexDatas: %d\n"
  164. "Vertices: %d\n"
  165. "Normals: %d\n"
  166. "TexCoords: %d\n"
  167. "Tris: %d\n"
  168. "Lines: %d\n"
  169. "Points: %d\n"
  170. "Texture memory: %.1f KB\n";
  171. #if defined(WIN32_VC) || defined(WIN64_VC)
  172. _snprintf(buffer, buffer_size, pattern,
  173. _scene_graph_analyzer.get_num_nodes(),
  174. _scene_graph_analyzer.get_num_instances(),
  175. _scene_graph_analyzer.get_num_transforms(),
  176. _scene_graph_analyzer.get_num_nodes_with_attribs(),
  177. _scene_graph_analyzer.get_num_geom_nodes(),
  178. _scene_graph_analyzer.get_num_geoms(),
  179. _scene_graph_analyzer.get_num_geom_vertex_datas(),
  180. _scene_graph_analyzer.get_num_vertices(),
  181. _scene_graph_analyzer.get_num_normals(),
  182. _scene_graph_analyzer.get_num_texcoords(),
  183. _scene_graph_analyzer.get_num_tris(),
  184. _scene_graph_analyzer.get_num_lines(),
  185. _scene_graph_analyzer.get_num_points(),
  186. _scene_graph_analyzer.get_texture_bytes()/1024.0);
  187. #else
  188. snprintf(buffer, buffer_size, pattern,
  189. _scene_graph_analyzer.get_num_nodes(),
  190. _scene_graph_analyzer.get_num_instances(),
  191. _scene_graph_analyzer.get_num_transforms(),
  192. _scene_graph_analyzer.get_num_nodes_with_attribs(),
  193. _scene_graph_analyzer.get_num_geom_nodes(),
  194. _scene_graph_analyzer.get_num_geoms(),
  195. _scene_graph_analyzer.get_num_geom_vertex_datas(),
  196. _scene_graph_analyzer.get_num_vertices(),
  197. _scene_graph_analyzer.get_num_normals(),
  198. _scene_graph_analyzer.get_num_texcoords(),
  199. _scene_graph_analyzer.get_num_tris(),
  200. _scene_graph_analyzer.get_num_lines(),
  201. _scene_graph_analyzer.get_num_points(),
  202. _scene_graph_analyzer.get_texture_bytes()/1024.0);
  203. #endif
  204. nassertv(strlen(buffer) < buffer_size);
  205. if (get_text() == buffer) {
  206. // Never mind; the data hasn't changed.
  207. return;
  208. }
  209. set_text(buffer);
  210. }