Panda3D
sceneGraphAnalyzerMeter.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file sceneGraphAnalyzerMeter.cxx
10  * @author pratt
11  * @date 2007-02-14
12  */
13 
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 "omniBoundingVolume.h"
23 #include <stdio.h> // For sprintf/snprintf
24 
25 PStatCollector SceneGraphAnalyzerMeter::_show_analyzer_pcollector("*:Show scene graph analysis");
26 
27 TypeHandle SceneGraphAnalyzerMeter::_type_handle;
28 
29 /**
30  *
31  */
32 SceneGraphAnalyzerMeter::
33 SceneGraphAnalyzerMeter(const std::string &name, PandaNode *node) :
34  TextNode(name),
35  _last_aspect_ratio(-1) {
36 
37  set_cull_callback();
38 
39  // Don't do frustum culling, as the text will always be in view.
41  set_final(true);
42 
43  Thread *current_thread = Thread::get_current_thread();
44 
45  _update_interval = scene_graph_analyzer_meter_update_interval;
46  _last_update = 0.0f;
47  _node = node;
48  _clock_object = ClockObject::get_global_clock();
49 
50  set_align(A_left);
51  set_transform(LMatrix4::scale_mat(scene_graph_analyzer_meter_scale) *
52  LMatrix4::translate_mat(LVector3::rfu(scene_graph_analyzer_meter_side_margins * scene_graph_analyzer_meter_scale, 0.0f, -scene_graph_analyzer_meter_scale)));
53  set_card_color(0.0f, 0.0f, 0.0f, 0.4);
54  set_card_as_margin(scene_graph_analyzer_meter_side_margins, scene_graph_analyzer_meter_side_margins, 0.1f, 0.0f);
55  set_usage_hint(Geom::UH_client);
56 
57  do_update(current_thread);
58 }
59 
60 /**
61  *
62  */
63 SceneGraphAnalyzerMeter::
64 ~SceneGraphAnalyzerMeter() {
65  clear_window();
66 }
67 
68 /**
69  * Sets up the frame rate meter to create a DisplayRegion to render itself
70  * into the indicated window.
71  */
74  clear_window();
75 
76  _window = window;
77 
78  _root = NodePath("scene_graph_analyzer_root");
79  _root.attach_new_node(this);
80 
81  CPT(RenderAttrib) dt = DepthTestAttrib::make(DepthTestAttrib::M_none);
82  CPT(RenderAttrib) dw = DepthWriteAttrib::make(DepthWriteAttrib::M_off);
83  _root.node()->set_attrib(dt, 1);
84  _root.node()->set_attrib(dw, 1);
85  _root.set_material_off(1);
86  _root.set_two_sided(1, 1);
87 
88  // If we don't set this explicitly, Panda will cause it to be rendered
89  // in a back-to-front cull bin, which will cause the bounding volume
90  // to be computed unnecessarily. Saves a little bit of overhead.
91  _root.set_bin("unsorted", 0);
92 
93  // Create a display region that covers the entire window.
94  _display_region = _window->make_display_region();
95  _display_region->set_sort(scene_graph_analyzer_meter_layer_sort);
96 
97  // Finally, we need a camera to associate with the display region.
98  PT(Camera) camera = new Camera("scene_graph_analyzer_camera");
99  NodePath camera_np = _root.attach_new_node(camera);
100 
101  PT(Lens) lens = new OrthographicLens;
102 
103  // We choose these values such that we can place the text against (0, 0).
104  static const PN_stdfloat left = 0.0f;
105  static const PN_stdfloat right = 2.0f;
106  static const PN_stdfloat bottom = -2.0f;
107  static const PN_stdfloat top = 0.0f;
108  lens->set_film_size(right - left, top - bottom);
109  lens->set_film_offset((right + left) * 0.5, (top + bottom) * 0.5);
110  lens->set_near_far(-1000, 1000);
111 
112  camera->set_lens(lens);
113  camera->set_scene(_root);
114  _display_region->set_camera(camera_np);
115 }
116 
117 /**
118  * Undoes the effect of a previous call to setup_window().
119  */
121 clear_window() {
122  if (_window != nullptr) {
123  _window->remove_display_region(_display_region);
124  _window = nullptr;
125  _display_region = nullptr;
126  }
127  _root = NodePath();
128 }
129 
130 /**
131  * This function will be called during the cull traversal to perform any
132  * additional operations that should be performed at cull time. This may
133  * include additional manipulation of render state or additional
134  * visible/invisible decisions, or any other arbitrary operation.
135  *
136  * Note that this function will *not* be called unless set_cull_callback() is
137  * called in the constructor of the derived class. It is necessary to call
138  * set_cull_callback() to indicated that we require cull_callback() to be
139  * called.
140  *
141  * By the time this function is called, the node has already passed the
142  * bounding-volume test for the viewing frustum, and the node's transform and
143  * state have already been applied to the indicated CullTraverserData object.
144  *
145  * The return value is true if this node should be visible, or false if it
146  * should be culled.
147  */
148 bool SceneGraphAnalyzerMeter::
149 cull_callback(CullTraverser *trav, CullTraverserData &data) {
150  Thread *current_thread = trav->get_current_thread();
151 
152  // Statistics
153  PStatTimer timer(_show_analyzer_pcollector, current_thread);
154 
155  // This is probably a good time to check if the aspect ratio on the window
156  // has changed.
157  int width = _display_region->get_pixel_width();
158  int height = _display_region->get_pixel_height();
159  PN_stdfloat aspect_ratio = 1;
160  if (width != 0 && height != 0) {
161  aspect_ratio = (PN_stdfloat)height / (PN_stdfloat)width;
162  }
163 
164  // Scale the transform by the calculated aspect ratio.
165  if (aspect_ratio != _last_aspect_ratio) {
166  _aspect_ratio_transform = TransformState::make_scale(LVecBase3(aspect_ratio, 1, 1));
167  _last_aspect_ratio = aspect_ratio;
168  }
169  data._net_transform = data._net_transform->compose(_aspect_ratio_transform);
170 
171  // Check to see if it's time to update.
172  double now = _clock_object->get_frame_time(current_thread);
173  double elapsed = now - _last_update;
174  if (elapsed < 0.0 || elapsed >= _update_interval) {
175  do_update(current_thread);
176  }
177 
178  return TextNode::cull_callback(trav, data);
179 }
180 
181 /**
182  * Resets the text according to the current frame rate.
183  */
184 void SceneGraphAnalyzerMeter::
185 do_update(Thread *current_thread) {
186  _last_update = _clock_object->get_frame_time(current_thread);
187 
188  _scene_graph_analyzer.clear();
189  _scene_graph_analyzer.add_node( _node );
190 
191  static const size_t buffer_size = 1024;
192  char buffer[buffer_size];
193 
194  const char *pattern = "Nodes: %d\n"
195  "Instances: %d\n"
196  "Transforms: %d\n"
197  "Nodes with Attribs: %d\n"
198  "GeomNodes: %d\n"
199  "Geoms: %d\n"
200  "GeomVertexDatas: %d\n"
201  "Vertices: %d\n"
202  "Normals: %d\n"
203  "TexCoords: %d\n"
204  "Tris: %d\n"
205  "Lines: %d\n"
206  "Points: %d\n"
207  "Texture memory: %.1f KB\n";
208 
209 #if defined(WIN32_VC) || defined(WIN64_VC)
210  _snprintf(buffer, buffer_size, pattern,
211  _scene_graph_analyzer.get_num_nodes(),
212  _scene_graph_analyzer.get_num_instances(),
213  _scene_graph_analyzer.get_num_transforms(),
214  _scene_graph_analyzer.get_num_nodes_with_attribs(),
215  _scene_graph_analyzer.get_num_geom_nodes(),
216  _scene_graph_analyzer.get_num_geoms(),
217  _scene_graph_analyzer.get_num_geom_vertex_datas(),
218  _scene_graph_analyzer.get_num_vertices(),
219  _scene_graph_analyzer.get_num_normals(),
220  _scene_graph_analyzer.get_num_texcoords(),
221  _scene_graph_analyzer.get_num_tris(),
222  _scene_graph_analyzer.get_num_lines(),
223  _scene_graph_analyzer.get_num_points(),
224  _scene_graph_analyzer.get_texture_bytes()/1024.0);
225 #else
226  snprintf(buffer, buffer_size, pattern,
227  _scene_graph_analyzer.get_num_nodes(),
228  _scene_graph_analyzer.get_num_instances(),
229  _scene_graph_analyzer.get_num_transforms(),
230  _scene_graph_analyzer.get_num_nodes_with_attribs(),
231  _scene_graph_analyzer.get_num_geom_nodes(),
232  _scene_graph_analyzer.get_num_geoms(),
233  _scene_graph_analyzer.get_num_geom_vertex_datas(),
234  _scene_graph_analyzer.get_num_vertices(),
235  _scene_graph_analyzer.get_num_normals(),
236  _scene_graph_analyzer.get_num_texcoords(),
237  _scene_graph_analyzer.get_num_tris(),
238  _scene_graph_analyzer.get_num_lines(),
239  _scene_graph_analyzer.get_num_points(),
240  _scene_graph_analyzer.get_texture_bytes()/1024.0);
241 #endif
242  nassertv(strlen(buffer) < buffer_size);
243 
244  if (get_text() == buffer) {
245  // Never mind; the data hasn't changed.
246  return;
247  }
248 
249  set_text(buffer);
250 }
PandaNode::set_bounds
void set_bounds(const BoundingVolume *volume)
Resets the bounding volume so that it is the indicated volume.
Definition: pandaNode.cxx:1907
Camera
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition: camera.h:35
NodePath::set_bin
void set_bin(const std::string &bin_name, int draw_order, int priority=0)
Assigns the geometry at this level and below to the named rendering bin.
Definition: nodePath.cxx:2801
pStatTimer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ClockObject::get_global_clock
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:215
CullTraverser
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
RenderAttrib
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
TextNode
The primary interface to this module.
Definition: textNode.h:48
orthographicLens.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Thread::get_current_thread
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition: thread.h:109
PStatTimer
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:30
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
GraphicsOutput
This is a base class for the various different classes that represent the result of a frame of render...
Definition: graphicsOutput.h:63
displayRegion.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PandaNode::set_attrib
void set_attrib(const RenderAttrib *attrib, int override=0)
Adds the indicated render attribute to the scene graph on this node.
Definition: pandaNode.cxx:938
SceneGraphAnalyzer::add_node
void add_node(PandaNode *node)
Adds a new node to the set of data for analysis.
Definition: sceneGraphAnalyzer.cxx:106
Lens::set_film_size
set_film_size
Sets the horizontal size of the film without changing its shape.
Definition: lens.h:82
CullTraverser::get_current_thread
Thread * get_current_thread() const
Returns the currently-executing thread object, as passed to the CullTraverser constructor.
Definition: cullTraverser.I:27
SceneGraphAnalyzerMeter::clear_window
void clear_window()
Undoes the effect of a previous call to setup_window().
Definition: sceneGraphAnalyzerMeter.cxx:121
PStatCollector
A lightweight class that represents a single element that may be timed and/or counted via stats.
Definition: pStatCollector.h:43
CullTraverserData
This collects together the pieces of data that are accumulated for each node while walking the scene ...
Definition: cullTraverserData.h:40
TextEncoder::set_text
set_text
Changes the text that is stored in the encoder.
Definition: textEncoder.h:124
depthWriteAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
OmniBoundingVolume
This is a special kind of GeometricBoundingVolume that fills all of space.
Definition: omniBoundingVolume.h:24
Lens
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:41
SceneGraphAnalyzer::clear
void clear()
Resets all of the data in the analyzer in preparation for a new run.
Definition: sceneGraphAnalyzer.cxx:55
OrthographicLens
An orthographic lens.
Definition: orthographicLens.h:30
camera.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
depthTestAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
omniBoundingVolume.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ClockObject::get_frame_time
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
Definition: clockObject.h:91
config_grutil.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PandaNode::set_transform
set_transform
Sets the transform that will be applied to this node and below.
Definition: pandaNode.h:183
NodePath::set_material_off
void set_material_off(int priority=0)
Sets the geometry at this level and below to render using no material.
Definition: nodePath.cxx:4128
NodePath::set_two_sided
void set_two_sided(bool two_sided, int priority=0)
Specifically sets or disables two-sided rendering mode on this particular node.
Definition: nodePath.cxx:4445
NodePath::attach_new_node
NodePath attach_new_node(PandaNode *node, int sort=0, Thread *current_thread=Thread::get_current_thread()) const
Attaches a new node, with or without existing parents, to the scene graph below the referenced node o...
Definition: nodePath.cxx:563
sceneGraphAnalyzerMeter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TextEncoder::get_text
get_text
Returns the current text, as encoded via the current encoding system.
Definition: textEncoder.h:124
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
NodePath::node
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
Thread
A thread; that is, a lightweight process.
Definition: thread.h:46
SceneGraphAnalyzerMeter::setup_window
void setup_window(GraphicsOutput *window)
Sets up the frame rate meter to create a DisplayRegion to render itself into the indicated window.
Definition: sceneGraphAnalyzerMeter.cxx:73