Panda3D

Loading...
Searching...
No Matches
frameRateMeter.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 frameRateMeter.cxx
10 * @author drose
11 * @date 2003-12-23
12 */
13
14#include "frameRateMeter.h"
15#include "camera.h"
16#include "displayRegion.h"
17#include "orthographicLens.h"
18#include "clockObject.h"
19#include "config_grutil.h"
20#include "depthTestAttrib.h"
21#include "depthWriteAttrib.h"
22#include "pStatTimer.h"
23#include "omniBoundingVolume.h"
24#include <stdio.h> // For sprintf/snprintf
25
26 PStatCollector FrameRateMeter::_show_fps_pcollector("*:Show fps");
27
28 TypeHandle FrameRateMeter::_type_handle;
29
30/**
31 *
32 */
33FrameRateMeter::
34FrameRateMeter(const std::string &name) :
35 TextNode(name),
36 _last_aspect_ratio(-1) {
37
38 set_cull_callback();
39
40 // Don't do frustum culling, as the text will always be in view.
41 set_bounds(new OmniBoundingVolume());
42 set_final(true);
43
44 Thread *current_thread = Thread::get_current_thread();
45
46 _show_milliseconds = frame_rate_meter_milliseconds;
47 if (_show_milliseconds) {
48 _text_pattern = frame_rate_meter_ms_text_pattern;
49 } else {
50 _text_pattern = frame_rate_meter_text_pattern;
51 }
52
53 _update_interval = frame_rate_meter_update_interval;
54 _last_update = 0.0f;
55 _clock_object = ClockObject::get_global_clock();
56
57 // The top of the visible frame is 80% of the line height, based on the
58 // calculation within TextAssembler.
59 PN_stdfloat height = 1.0f;
60 TextFont *font = get_font();
61 if (font != nullptr){
62 height = font->get_line_height() * 0.8;
63 }
64
65 set_align(A_right);
66 set_transform(LMatrix4::scale_mat(frame_rate_meter_scale) *
67 LMatrix4::translate_mat(LVector3::rfu(-frame_rate_meter_side_margins * frame_rate_meter_scale, 0.0f, -frame_rate_meter_scale * height)));
68 set_card_color(0.0f, 0.0f, 0.0f, 0.4);
69 set_card_as_margin(frame_rate_meter_side_margins, frame_rate_meter_side_margins, 0.1f, 0.0f);
70 // set_usage_hint(Geom::UH_client);
71
72 do_update(current_thread);
73}
74
75/**
76 *
77 */
78FrameRateMeter::
79~FrameRateMeter() {
80 clear_window();
81}
82
83/**
84 * Sets up the frame rate meter to create a DisplayRegion to render itself
85 * into the indicated window.
86 */
87 void FrameRateMeter::
88 setup_window(GraphicsOutput *window) {
89 clear_window();
90
91 _window = window;
92
93 _root = NodePath("frame_rate_root");
94 _root.attach_new_node(this);
95
96 CPT(RenderAttrib) dt = DepthTestAttrib::make(DepthTestAttrib::M_none);
97 CPT(RenderAttrib) dw = DepthWriteAttrib::make(DepthWriteAttrib::M_off);
98 _root.node()->set_attrib(dt, 1);
99 _root.node()->set_attrib(dw, 1);
100 _root.set_material_off(1);
101 _root.set_two_sided(1, 1);
102
103 // If we don't set this explicitly, Panda will cause it to be rendered in a
104 // back-to-front cull bin, which will cause the bounding volume to be
105 // computed unnecessarily. Saves a little bit of overhead.
106 _root.set_bin("unsorted", 0);
107
108 // Create a display region that covers the entire window.
109 _display_region = _window->make_mono_display_region();
110 _display_region->set_sort(frame_rate_meter_layer_sort);
111
112 // Finally, we need a camera to associate with the display region.
113 PT(Camera) camera = new Camera("frame_rate_camera");
114 NodePath camera_np = _root.attach_new_node(camera);
115
116 PT(Lens) lens = new OrthographicLens;
117
118 // We choose these values such that we can place the text against (0, 0).
119 static const PN_stdfloat left = -2.0f;
120 static const PN_stdfloat right = 0.0f;
121 static const PN_stdfloat bottom = -2.0f;
122 static const PN_stdfloat top = 0.0f;
123 lens->set_film_size(right - left, top - bottom);
124 lens->set_film_offset((right + left) * 0.5, (top + bottom) * 0.5);
125 lens->set_near_far(-1000, 1000);
126
127 camera->set_lens(lens);
128 camera->set_scene(_root);
129 _display_region->set_camera(camera_np);
130}
131
132/**
133 * Undoes the effect of a previous call to setup_window().
134 */
135 void FrameRateMeter::
136 clear_window() {
137 if (_window != nullptr) {
138 _window->remove_display_region(_display_region);
139 _window = nullptr;
140 _display_region = nullptr;
141 }
142 _root = NodePath();
143}
144
145/**
146 * This function will be called during the cull traversal to perform any
147 * additional operations that should be performed at cull time. This may
148 * include additional manipulation of render state or additional
149 * visible/invisible decisions, or any other arbitrary operation.
150 *
151 * Note that this function will *not* be called unless set_cull_callback() is
152 * called in the constructor of the derived class. It is necessary to call
153 * set_cull_callback() to indicated that we require cull_callback() to be
154 * called.
155 *
156 * By the time this function is called, the node has already passed the
157 * bounding-volume test for the viewing frustum, and the node's transform and
158 * state have already been applied to the indicated CullTraverserData object.
159 *
160 * The return value is true if this node should be visible, or false if it
161 * should be culled.
162 */
163 bool FrameRateMeter::
164cull_callback(CullTraverser *trav, CullTraverserData &data) {
165 // This triggers when you try to parent a frame rate meter into the scene
166 // graph yourself. Instead, use setup_window().
167 nassertr(_display_region != nullptr, false);
168
169 Thread *current_thread = trav->get_current_thread();
170
171 // Statistics
172 PStatTimer timer(_show_fps_pcollector, current_thread);
173
174 // This is probably a good time to check if the aspect ratio on the window
175 // has changed.
176 int width = _display_region->get_pixel_width();
177 int height = _display_region->get_pixel_height();
178 PN_stdfloat aspect_ratio = 1;
179 if (width != 0 && height != 0) {
180 aspect_ratio = (PN_stdfloat)height / (PN_stdfloat)width;
181 }
182
183 // Scale the transform by the calculated aspect ratio.
184 if (aspect_ratio != _last_aspect_ratio) {
185 _aspect_ratio_transform = TransformState::make_scale(LVecBase3(aspect_ratio, 1, 1));
186 _last_aspect_ratio = aspect_ratio;
187 }
188 data._net_transform = data._net_transform->compose(_aspect_ratio_transform);
189
190 // Check to see if it's time to update.
191 double now = _clock_object->get_frame_time(current_thread);
192 double elapsed = now - _last_update;
193 if (elapsed < 0.0 || elapsed >= _update_interval) {
194 do_update(current_thread);
195 }
196
197 return TextNode::cull_callback(trav, data);
198}
199
200/**
201 * Resets the text according to the current frame rate.
202 */
203 void FrameRateMeter::
204do_update(Thread *current_thread) {
205 _last_update = _clock_object->get_frame_time(current_thread);
206
207 double value = _clock_object->get_average_frame_rate(current_thread);
208 double deviation = _clock_object->calc_frame_rate_deviation(current_thread);
209
210 if (_show_milliseconds) {
211 value = 1000.0 / value;
212 deviation = 1000.0 / deviation;
213 }
214
215 static const size_t buffer_size = 1024;
216 char buffer[buffer_size];
217#if defined(WIN32_VC) || defined(WIN64_VC)
218 // Windows doesn't define snprintf(). Hope we don't overflow.
219 sprintf(buffer, _text_pattern.c_str(), value, deviation);
220#else
221 snprintf(buffer, buffer_size, _text_pattern.c_str(), value, deviation);
222#endif
223 nassertv(strlen(buffer) < buffer_size);
224
225 if (get_text() == buffer) {
226 // Never mind; the frame rate hasn't changed.
227 return;
228 }
229
230 set_text(buffer);
231}
camera.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
ClockObject::get_global_clock
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition clockObject.I:215
CullTraverserData
This collects together the pieces of data that are accumulated for each node while walking the scene ...
Definition cullTraverserData.h:40
CullTraverser
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition cullTraverser.h:45
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
DepthTestAttrib::make
static ConstPointerTo< RenderAttrib > make(PandaCompareFunc mode)
Constructs a new DepthTestAttrib object.
Definition depthTestAttrib.cxx:29
DepthWriteAttrib::make
static ConstPointerTo< RenderAttrib > make(Mode mode)
Constructs a new DepthWriteAttrib object.
Definition depthWriteAttrib.cxx:29
FrameRateMeter::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 frameRateMeter.cxx:88
FrameRateMeter::clear_window
void clear_window()
Undoes the effect of a previous call to setup_window().
Definition frameRateMeter.cxx:136
GraphicsOutput
This is a base class for the various different classes that represent the result of a frame of render...
Definition graphicsOutput.h:63
Lens
A base class for any number of different kinds of lenses, linear and otherwise.
Definition lens.h:41
Lens::set_film_size
set_film_size
Sets the horizontal size of the film without changing its shape.
Definition lens.h:82
OmniBoundingVolume
This is a special kind of GeometricBoundingVolume that fills all of space.
Definition omniBoundingVolume.h:24
OrthographicLens
An orthographic lens.
Definition orthographicLens.h:30
PStatCollector
A lightweight class that represents a single element that may be timed and/or counted via stats.
Definition pStatCollector.h:43
PStatTimer
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition pStatTimer.h:30
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
TextEncoder::set_text
set_text
Changes the text that is stored in the encoder.
Definition textEncoder.h:124
TextEncoder::get_text
get_text
Returns the current text, as encoded via the current encoding system.
Definition textEncoder.h:124
TextFont
An encapsulation of a font; i.e.
Definition textFont.h:32
TextFont::get_line_height
get_line_height
Returns the number of units high each line of text is.
Definition textFont.h:69
TextNode
The primary interface to this module.
Definition textNode.h:48
TextNode::cull_callback
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
Thread
A thread; that is, a lightweight process.
Definition thread.h:46
Thread::get_current_thread
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
clockObject.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_grutil.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
depthTestAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
depthWriteAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
displayRegion.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
frameRateMeter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
omniBoundingVolume.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
orthographicLens.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pStatTimer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.