Panda3D
Loading...
Searching...
No Matches
displayRegion.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 displayRegion.cxx
10 * @author cary
11 * @date 1999-02-10
12 */
13
14#include "displayRegion.h"
15#include "stereoDisplayRegion.h"
16#include "graphicsEngine.h"
17#include "graphicsOutput.h"
18#include "config_display.h"
19#include "texture.h"
20#include "camera.h"
21#include "dcast.h"
22#include "pnmImage.h"
23
24#include <time.h>
25
26using std::string;
27
28TypeHandle DisplayRegion::_type_handle;
29TypeHandle DisplayRegionPipelineReader::_type_handle;
30
31/**
32 *
33 */
34DisplayRegion::
35DisplayRegion(GraphicsOutput *window, const LVecBase4 &dimensions) :
36 _window(window),
37 _incomplete_render(true),
38 _texture_reload_priority(0),
39 _cull_region_pcollector("Cull:Invalid"),
40 _draw_region_pcollector("Draw:Invalid")
41{
42 _screenshot_buffer_type = window->get_draw_buffer_type();
43 _draw_buffer_type = window->get_draw_buffer_type();
44 set_num_regions(1);
45 set_dimensions(0, dimensions);
46 compute_pixels_all_stages();
47
48 _window->add_display_region(this);
49}
50
51/**
52 *
53 */
54DisplayRegion::
55~DisplayRegion() {
56 cleanup();
57
58 // The window pointer should already have been cleared by the time the
59 // DisplayRegion destructs (since the GraphicsOutput class keeps a reference
60 // count on the DisplayRegion).
61 nassertv(_window == nullptr);
62}
63
64/**
65 * Cleans up some pointers associated with the DisplayRegion to help reduce
66 * the chance of memory leaks due to circular reference counts.
67 */
69cleanup() {
70 CDStageWriter cdata(_cycler, 0);
71 if (cdata->_camera_node != nullptr) {
72 // We need to tell the old camera we're not using it anymore.
73 cdata->_camera_node->remove_display_region(this);
74 }
75 cdata->_camera_node = nullptr;
76 cdata->_camera = NodePath();
77
78 CDCullWriter cdata_cull(_cycler_cull, true);
79 cdata_cull->_cull_result = nullptr;
80}
81
82/**
83 * Sets the lens index, allows for multiple lenses to be attached to a camera.
84 * This is useful for a variety of setups, such as fish eye rendering. The
85 * default is 0.
86 *
87 * Don't call this in a downstream thread unless you don't mind it blowing
88 * away other changes you might have recently made in an upstream thread.
89 */
91set_lens_index(int index) {
92 Thread *current_thread = Thread::get_current_thread();
93 CDWriter cdata(_cycler, true, current_thread);
94 cdata->_lens_index = index;
95}
96
97/**
98 * Changes the portion of the framebuffer this DisplayRegion corresponds to.
99 * The parameters range from 0 to 1, where 0,0 is the lower left corner and
100 * 1,1 is the upper right; (0, 1, 0, 1) represents the whole screen.
101 *
102 * Don't call this in a downstream thread unless you don't mind it blowing
103 * away other changes you might have recently made in an upstream thread.
104 */
106set_dimensions(int i, const LVecBase4 &dimensions) {
107 Thread *current_thread = Thread::get_current_thread();
108 CDWriter cdata(_cycler, true, current_thread);
109
110 cdata->_regions[i]._dimensions = dimensions;
111
112 if (_window != nullptr && _window->has_size()) {
113 do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(), cdata);
114 }
115}
116
117/**
118 * Returns the GraphicsPipe that this DisplayRegion is ultimately associated
119 * with, or NULL if no pipe is associated.
120 */
122get_pipe() const {
123 return (_window != nullptr) ? _window->get_pipe() : nullptr;
124}
125
126/**
127 * Returns true if this is a StereoDisplayRegion, false otherwise.
128 */
130is_stereo() const {
131 return false;
132}
133
134/**
135 * Sets the camera that is associated with this DisplayRegion. There is a
136 * one-to-many association between cameras and DisplayRegions; one camera may
137 * be shared by multiple DisplayRegions.
138 *
139 * The camera is actually set via a NodePath, which clarifies which instance
140 * of the camera (if there happen to be multiple instances) we should use.
141 *
142 * Don't call this in a downstream thread unless you don't mind it blowing
143 * away other changes you might have recently made in an upstream thread.
144 */
146set_camera(const NodePath &camera) {
147 CDWriter cdata(_cycler, true);
148
149 Camera *camera_node = nullptr;
150 if (!camera.is_empty()) {
151 DCAST_INTO_V(camera_node, camera.node());
152 }
153
154 if (camera_node != cdata->_camera_node) {
155 // Note that these operations on the DisplayRegion are not pipelined: they
156 // operate across all pipeline stages. Since we have already asserted we
157 // are running in pipeline stage 0, no problem.
158 if (cdata->_camera_node != nullptr) {
159 // We need to tell the old camera we're not using him anymore.
160 cdata->_camera_node->remove_display_region(this);
161 }
162 cdata->_camera_node = camera_node;
163 if (cdata->_camera_node != nullptr) {
164 // Now tell the new camera we are using him.
165 cdata->_camera_node->add_display_region(this);
166 }
167 }
168
169 cdata->_camera = camera;
170}
171
172/**
173 * Sets the active flag associated with the DisplayRegion. If the
174 * DisplayRegion is marked inactive, nothing is rendered.
175 *
176 * Don't call this in a downstream thread unless you don't mind it blowing
177 * away other changes you might have recently made in an upstream thread.
178 */
180set_active(bool active) {
181 Thread *current_thread = Thread::get_current_thread();
182 CDWriter cdata(_cycler, true, current_thread);
183
184 if (active != cdata->_active) {
185 cdata->_active = active;
186 win_display_regions_changed();
187 }
188}
189
190/**
191 * Sets the sort value associated with the DisplayRegion. Within a window,
192 * DisplayRegions will be rendered in order from the lowest sort value to the
193 * highest.
194 *
195 * Don't call this in a downstream thread unless you don't mind it blowing
196 * away other changes you might have recently made in an upstream thread.
197 */
199set_sort(int sort) {
200 Thread *current_thread = Thread::get_current_thread();
201 CDWriter cdata(_cycler, true, current_thread);
202
203 if (sort != cdata->_sort) {
204 cdata->_sort = sort;
205 win_display_regions_changed();
206 }
207}
208
209/**
210 * Specifies whether the DisplayRegion represents the left or right channel of
211 * a stereo pair, or whether it is a normal, monocular image. This
212 * automatically adjusts the lens that is used to render to this DisplayRegion
213 * to its left or right eye, according to the lens's stereo properties.
214 *
215 * When the DisplayRegion is attached to a stereo window (one for which
216 * is_stereo() returns true), this also specifies which physical channel the
217 * DisplayRegion renders to.
218 *
219 * Normally you would create at least two DisplayRegions for a stereo window,
220 * one for each of the left and right channels. The two DisplayRegions may
221 * share the same camera (and thus the same lens); this parameter is used to
222 * control the exact properties of the lens when it is used to render into
223 * this DisplayRegion.
224 *
225 * Also see the StereoDisplayRegion, which automates managing a pair of
226 * left/right DisplayRegions.
227 *
228 * An ordinary DisplayRegion may be set to SC_mono, SC_left, or SC_right. You
229 * may set SC_stereo only on a StereoDisplayRegion.
230 *
231 * This call also resets tex_view_offset to its default value, which is 0 for
232 * the left eye or 1 for the right eye of a stereo display region, or 0 for a
233 * mono display region.
234 */
236set_stereo_channel(Lens::StereoChannel stereo_channel) {
237 nassertv(is_stereo() || stereo_channel != Lens::SC_stereo);
238
239 nassertv(Thread::get_current_pipeline_stage() == 0);
240
241 CDWriter cdata(_cycler);
242 cdata->_stereo_channel = stereo_channel;
243 cdata->_tex_view_offset = (stereo_channel == Lens::SC_right) ? 1 : 0;
244}
245
246/**
247 * Sets the current texture view offset for this DisplayRegion. This is
248 * normally set to zero. If nonzero, it is used to select a particular view
249 * of any multiview textures that are rendered within this DisplayRegion.
250 *
251 * For a StereoDisplayRegion, this is normally 0 for the left eye, and 1 for
252 * the right eye, to support stereo textures. This is set automatically when
253 * you call set_stereo_channel().
254 */
256set_tex_view_offset(int tex_view_offset) {
257 nassertv(Thread::get_current_pipeline_stage() == 0);
258
259 CDWriter cdata(_cycler);
260 cdata->_tex_view_offset = tex_view_offset;
261}
262
263/**
264 * Sets the incomplete_render flag. When this is true, the frame will be
265 * rendered even if some of the geometry or textures in the scene are not
266 * available (e.g. they have been temporarily paged out). When this is
267 * false, the frame will be held up while this data is reloaded.
268 *
269 * This flag may also be set on the GraphicsStateGuardian. It will be
270 * considered true for a given DisplayRegion only if it is true on both the
271 * GSG and on the DisplayRegion.
272 *
273 * See GraphicsStateGuardian::set_incomplete_render() for more detail.
274 */
276set_incomplete_render(bool incomplete_render) {
277 _incomplete_render = incomplete_render;
278}
279
280/**
281 * Specifies an integer priority which is assigned to any asynchronous texture
282 * reload requests spawned while processing this DisplayRegion. This controls
283 * which textures are loaded first when multiple textures need to be reloaded
284 * at once; it also controls the relative priority between asynchronous
285 * texture loads and asynchronous model or animation loads.
286 *
287 * Specifying a larger number here makes the textures rendered by this
288 * DisplayRegion load up first. This may be particularly useful to do, for
289 * instance, for the DisplayRegion that renders the gui.
290 */
292set_texture_reload_priority(int texture_reload_priority) {
293 _texture_reload_priority = texture_reload_priority;
294}
295
296/**
297 * Specifies the CullTraverser that will be used to draw the contents of this
298 * DisplayRegion. Normally the default CullTraverser is sufficient, but this
299 * may be changed to change the default cull behavior.
300 */
303 _trav = trav;
304}
305
306/**
307 * Returns the CullTraverser that will be used to draw the contents of this
308 * DisplayRegion.
309 */
312 if (_trav == nullptr) {
313 _trav = new CullTraverser;
314 }
315 return _trav;
316}
317
318/**
319 * This is a special parameter that is only used when rendering the faces of a
320 * cube map or multipage and/or multiview texture.
321 *
322 * This sets up the DisplayRegion to render to the ith page and jth view of
323 * its associated texture(s); the value must be consistent with the range of
324 * values availble to the texture. A normal DisplayRegion that is not
325 * associated with any particular page should be set to page -1 and view 0.
326 *
327 * This is particularly useful when rendering cube maps and/or stereo
328 * textures.
329 *
330 * Don't call this in a downstream thread unless you don't mind it blowing
331 * away other changes you might have recently made in an upstream thread.
332 */
334set_target_tex_page(int page) {
335 Thread *current_thread = Thread::get_current_thread();
336 CDWriter cdata(_cycler, true, current_thread);
337 cdata->_target_tex_page = page;
338}
339
340/**
341 *
342 */
343void DisplayRegion::
344output(std::ostream &out) const {
345 CDReader cdata(_cycler);
346 out << "DisplayRegion(" << cdata->_regions[0]._dimensions
347 << ")=pixels(" << cdata->_regions[0]._pixels << ")";
348}
349
350/**
351 * Synthesizes a suitable default filename for passing to save_screenshot().
352 *
353 * The default filename is generated from the supplied prefix and from the
354 * Config variable screenshot-filename, which contains the following strings:
355 *
356 * %~p - the supplied prefix %~f - the frame count %~e - the value of
357 * screenshot-extension All other % strings in strftime().
358 */
360make_screenshot_filename(const string &prefix) {
361 time_t now = time(nullptr);
362 struct tm *ttm = localtime(&now);
363 int frame_count = ClockObject::get_global_clock()->get_frame_count();
364
365 static const int buffer_size = 1024;
366 char buffer[buffer_size];
367
368 std::ostringstream filename_strm;
369
370 size_t i = 0;
371 while (i < screenshot_filename.length()) {
372 char ch1 = screenshot_filename[i++];
373 if (ch1 == '%' && i < screenshot_filename.length()) {
374 char ch2 = screenshot_filename[i++];
375 if (ch2 == '~' && i < screenshot_filename.length()) {
376 char ch3 = screenshot_filename[i++];
377 switch (ch3) {
378 case 'p':
379 filename_strm << prefix;
380 break;
381
382 case 'f':
383 filename_strm << frame_count;
384 break;
385
386 case 'e':
387 filename_strm << screenshot_extension;
388 break;
389 }
390
391 } else {
392 // Use strftime() to decode the percent code.
393 char format[3] = {'%', ch2, '\0'};
394 if (strftime(buffer, buffer_size, format, ttm)) {
395 for (char *b = buffer; *b != '\0'; b++) {
396 switch (*b) {
397 case ' ':
398 case ':':
399 case '/':
400 filename_strm << '-';
401 break;
402
403 case '\n':
404 break;
405
406 default:
407 filename_strm << *b;
408 }
409 }
410 }
411 }
412 } else {
413 filename_strm << ch1;
414 }
415 }
416
417 return Filename(filename_strm.str());
418}
419
420
421/**
422 * Saves a screenshot of the region to a default filename, and returns the
423 * filename, or empty string if the screenshot failed. The filename is
424 * generated by make_screenshot_filename().
425 */
427save_screenshot_default(const string &prefix) {
428 Filename filename = make_screenshot_filename(prefix);
429 if (save_screenshot(filename)) {
430 return filename;
431 }
432 return Filename();
433}
434
435/**
436 * Saves a screenshot of the region to the indicated filename. Returns true
437 * on success, false on failure.
438 */
440save_screenshot(const Filename &filename, const string &image_comment) {
441 PNMImage image;
442 if (!get_screenshot(image)) {
443 return false;
444 }
445
446 image.set_comment(image_comment);
447 if (!image.write(filename)) {
448 return false;
449 }
450 return true;
451}
452
453/**
454 * Captures the most-recently rendered image from the framebuffer into the
455 * indicated PNMImage. Returns true on success, false on failure.
456 */
458get_screenshot(PNMImage &image) {
459 PT(Texture) tex = get_screenshot();
460
461 if (tex == nullptr) {
462 return false;
463 }
464
465 if (!tex->store(image)) {
466 return false;
467 }
468
469 return true;
470}
471
472/**
473 * Captures the most-recently rendered image from the framebuffer and returns
474 * it as a Texture, or NULL on failure.
475 */
478 Thread *current_thread = Thread::get_current_thread();
479
480 GraphicsOutput *window = get_window();
481 nassertr(window != nullptr, nullptr);
482
483 GraphicsStateGuardian *gsg = window->get_gsg();
484 nassertr(gsg != nullptr, nullptr);
485
486 // Are we on the draw thread?
487 if (gsg->get_threading_model().get_draw_stage() != current_thread->get_pipeline_stage()) {
488 // Ask the engine to do on the draw thread.
489 GraphicsEngine *engine = window->get_engine();
490 return engine->do_get_screenshot(this, gsg);
491 }
492
493 // We are on the draw thread.
494 if (!window->begin_frame(GraphicsOutput::FM_refresh, current_thread)) {
495 return nullptr;
496 }
497
498 {
499 // Make sure that the correct viewport is active.
500 DisplayRegionPipelineReader dr_reader(this, current_thread);
501 gsg->prepare_display_region(&dr_reader);
502 }
503
504 PT(Texture) tex = new Texture;
505
507 _window->get_fb_properties());
508 if (!gsg->framebuffer_copy_to_ram(tex, 0, -1, this, buffer)) {
509 return nullptr;
510 }
511
512 window->end_frame(GraphicsOutput::FM_refresh, current_thread);
513
514 return tex;
515}
516
517/**
518 *
519 */
520void DisplayRegion::
521clear_cull_result() {
522 CDCullWriter cdata_cull(_cycler_cull, true);
523 cdata_cull->_cull_result = nullptr;
524}
525
526/**
527 * Returns a special scene graph constructed to represent the results of the
528 * last frame's cull operation.
529 *
530 * This will be a hierarchy of nodes, one node for each bin, each of which
531 * will in term be a parent of a number of GeomNodes, representing the
532 * geometry drawn in each bin.
533 *
534 * This is useful mainly for high-level debugging and abstraction tools; it
535 * should not be mistaken for the low-level cull result itself, which is
536 * constructed and maintained internally. No such scene graph is normally
537 * constructed during the rendering of a frame; this is an artificial
538 * construct created for the purpose of making it easy to analyze the results
539 * of the cull operation.
540 */
541PT(PandaNode) DisplayRegion::
542make_cull_result_graph() {
544 if (cull_result == nullptr) {
545 return nullptr;
546 }
547 return cull_result->make_result_graph();
548}
549
550/**
551 * Computes the pixel locations of the DisplayRegion within its window. The
552 * DisplayRegion will request the size from the window.
553 */
556 if (_window != nullptr) {
557 CDWriter cdata(_cycler, false);
558 for (size_t i = 0; i < cdata->_regions.size(); ++i) {
559 do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
560 cdata);
561 }
562 }
563}
564
565/**
566 * Computes the pixel locations of the DisplayRegion within its window. The
567 * DisplayRegion will request the size from the window.
568 */
571 if (_window != nullptr) {
572 OPEN_ITERATE_ALL_STAGES(_cycler) {
573 CDStageWriter cdata(_cycler, pipeline_stage);
574 for (size_t i = 0; i < cdata->_regions.size(); ++i) {
575 do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
576 cdata);
577 }
578 }
579 CLOSE_ITERATE_ALL_STAGES(_cycler);
580 }
581}
582
583/**
584 * Computes the pixel locations of the DisplayRegion within its window, given
585 * the size of the window in pixels.
586 */
588compute_pixels(int x_size, int y_size) {
589 CDWriter cdata(_cycler, false);
590 for (size_t i = 0; i < cdata->_regions.size(); ++i) {
591 do_compute_pixels(i, x_size, y_size, cdata);
592 }
593}
594
595/**
596 * Performs a compute_pixels() operation for all stages of the pipeline. This
597 * is appropriate, for instance, when a window changes sizes, since this is a
598 * global operation; and you want the new window size to be immediately
599 * available even to the downstream stages.
600 */
602compute_pixels_all_stages(int x_size, int y_size) {
603 OPEN_ITERATE_ALL_STAGES(_cycler) {
604 CDStageWriter cdata(_cycler, pipeline_stage);
605 for (size_t i = 0; i < cdata->_regions.size(); ++i) {
606 do_compute_pixels(i, x_size, y_size, cdata);
607 }
608 }
609 CLOSE_ITERATE_ALL_STAGES(_cycler);
610}
611
612/**
613 * Returns true if a call to set_pixel_zoom() will be respected, false if it
614 * will be ignored. If this returns false, then get_pixel_factor() will
615 * always return 1.0, regardless of what value you specify for
616 * set_pixel_zoom().
617 *
618 * This may return false if the underlying renderer doesn't support pixel
619 * zooming, or if you have called this on a DisplayRegion that doesn't have
620 * both set_clear_color() and set_clear_depth() enabled.
621 */
623supports_pixel_zoom() const {
624 if (_window != nullptr) {
625 if (_window->supports_pixel_zoom()) {
627 }
628 }
629 return false;
630}
631
632/**
633 * Intended to be called when the active state on a nested channel or layer or
634 * display region changes, forcing the window to recompute its list of active
635 * display regions. It is assumed the lock is already held.
636 */
637void DisplayRegion::
638win_display_regions_changed() {
639 if (_window != nullptr) {
640 _window->win_display_regions_changed();
641 }
642}
643
644/**
645 * The private implementation of compute_pixels, this assumes that we already
646 * have the lock.
647 */
648void DisplayRegion::
649do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
650 if (display_cat.is_debug()) {
651 display_cat.debug()
652 << "DisplayRegion::do_compute_pixels(" << x_size << ", " << y_size << ")\n";
653 }
654
655 Region &region = cdata->_regions[i];
656
657 region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
658 region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
659 region._pixels_i[0] = region._pixels[0];
660 region._pixels_i[1] = region._pixels[1];
661
662 nassertv(_window != nullptr);
663 if (_window->get_inverted()) {
664 // The window is inverted; compute the DisplayRegion accordingly.
665 region._pixels[2] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
666 region._pixels[3] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
667 region._pixels_i[2] = int((region._dimensions[3] * y_size) + 0.5);
668 region._pixels_i[3] = int((region._dimensions[2] * y_size) + 0.5);
669
670 } else {
671 // The window is normal.
672 region._pixels[2] = int((region._dimensions[2] * y_size) + 0.5);
673 region._pixels[3] = int((region._dimensions[3] * y_size) + 0.5);
674 region._pixels_i[2] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
675 region._pixels_i[3] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
676 }
677}
678
679/**
680 * This is called by GraphicsOutput to indicate that the index of this
681 * DisplayRegion within the window's list of active DisplayRegions might have
682 * changed. The index number will be -1 if the DisplayRegion is not active.
683 *
684 * This is primarily intended only for updating the PStatCollector name
685 * appropriately.
686 */
687void DisplayRegion::
688set_active_index(int index) {
689#if defined(DO_PSTATS) || !defined(NDEBUG)
690 std::ostringstream strm;
691
692 // To make a more useful name for PStats and debug output, we add the scene
693 // graph name and camera name.
694 NodePath camera = get_camera();
695 if (!camera.is_empty()) {
696 Camera *camera_node = DCAST(Camera, camera.node());
697 if (camera_node != nullptr) {
698 NodePath scene_root = camera_node->get_scene();
699 if (scene_root.is_empty()) {
700 scene_root = camera.get_top();
701 }
702 strm << scene_root.get_name();
703 }
704 }
705
706 // And add the index in case we have two scene graphs with the same name.
707 strm << "#" << index;
708
709 _debug_name = strm.str();
710#endif
711
712#ifdef DO_PSTATS
713 _cull_region_pcollector = PStatCollector(_window->get_cull_window_pcollector(), _debug_name);
714 _draw_region_pcollector = PStatCollector(_window->get_draw_window_pcollector(), _debug_name);
715#endif // DO_PSTATS
716}
717
718/**
719 * Performs a cull traversal. The default implementation simply calls
720 * GraphicsEngine::do_cull.
721 */
722void DisplayRegion::
723do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
724 GraphicsStateGuardian *gsg, Thread *current_thread) {
725
726 GraphicsEngine::do_cull(cull_handler, scene_setup, gsg, current_thread);
727}
728
729/**
730 *
731 */
732DisplayRegion::CData::
733CData() :
734 _lens_index(0),
735 _camera_node(nullptr),
736 _active(true),
737 _sort(0),
738 _stereo_channel(Lens::SC_mono),
739 _tex_view_offset(0),
740 _target_tex_page(-1),
741 _scissor_enabled(true)
742{
743 _regions.push_back(Region());
744}
745
746/**
747 *
748 */
749DisplayRegion::CData::
750CData(const DisplayRegion::CData &copy) :
751 _regions(copy._regions),
752 _lens_index(copy._lens_index),
753 _camera(copy._camera),
754 _camera_node(copy._camera_node),
755 _active(copy._active),
756 _sort(copy._sort),
757 _stereo_channel(copy._stereo_channel),
758 _tex_view_offset(copy._tex_view_offset),
759 _target_tex_page(copy._target_tex_page),
760 _scissor_enabled(copy._scissor_enabled)
761{
762}
763
764/**
765 *
766 */
767CycleData *DisplayRegion::CData::
768make_copy() const {
769 return new CData(*this);
770}
771
772/**
773 *
774 */
775CycleData *DisplayRegion::CDataCull::
776make_copy() const {
777 return new CDataCull(*this);
778}
779
780/**
781 * Returns the GraphicsPipe that this DisplayRegion is ultimately associated
782 * with, or NULL if no pipe is associated.
783 */
785get_pipe() const {
786 return (_object->_window != nullptr) ? _object->_window->get_pipe() : nullptr;
787}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition camera.h:35
get_scene
Returns the scene that will be rendered by the camera.
Definition camera.h:54
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
Definition clockObject.h:94
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
This defines the abstract interface for an object that receives Geoms identified by the CullTraverser...
Definition cullHandler.h:28
This stores the result of a BinCullHandler traversal: an ordered collection of CullBins,...
Definition cullResult.h:44
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A single page of data maintained by a PipelineCycler.
Definition cycleData.h:50
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
GraphicsPipe * get_pipe() const
Returns the GraphicsPipe that this DisplayRegion is ultimately associated with, or NULL if no pipe is...
is_stereo
Returns true if this is a StereoDisplayRegion, false otherwise.
get_cull_traverser
Returns the CullTraverser that will be used to draw the contents of this DisplayRegion.
void compute_pixels()
Computes the pixel locations of the DisplayRegion within its window.
bool save_screenshot(const Filename &filename, const std::string &image_comment="")
Saves a screenshot of the region to the indicated filename.
CullResult * get_cull_result(Thread *current_thread) const
Returns the CullResult value that was stored on this DisplayRegion, presumably by the last successful...
set_camera
Sets the camera that is associated with this DisplayRegion.
set_tex_view_offset
Sets the current texture view offset for this DisplayRegion.
set_target_tex_page
This is a special parameter that is only used when rendering the faces of a cube map or multipage and...
bool get_screenshot(PNMImage &image)
Captures the most-recently rendered image from the framebuffer into the indicated PNMImage.
get_camera
Returns the camera associated with this DisplayRegion, or an empty NodePath if no camera is associate...
set_lens_index
Sets the lens index, allows for multiple lenses to be attached to a camera.
get_window
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
void cleanup()
Cleans up some pointers associated with the DisplayRegion to help reduce the chance of memory leaks d...
void compute_pixels_all_stages()
Computes the pixel locations of the DisplayRegion within its window.
get_pipe
Returns the GraphicsPipe that this DisplayRegion is ultimately associated with, or NULL if no pipe is...
set_sort
Sets the sort value associated with the DisplayRegion.
static Filename make_screenshot_filename(const std::string &prefix="screenshot")
Synthesizes a suitable default filename for passing to save_screenshot().
set_cull_traverser
Specifies the CullTraverser that will be used to draw the contents of this DisplayRegion.
set_dimensions
Changes the portion of the framebuffer this DisplayRegion corresponds to.
set_active
Sets the active flag associated with the DisplayRegion.
set_stereo_channel
Specifies whether the DisplayRegion represents the left or right channel of a stereo pair,...
set_texture_reload_priority
Specifies an integer priority which is assigned to any asynchronous texture reload requests spawned w...
virtual bool supports_pixel_zoom() const
Returns true if a call to set_pixel_zoom() will be respected, false if it will be ignored.
Filename save_screenshot_default(const std::string &prefix="screenshot")
Saves a screenshot of the region to a default filename, and returns the filename, or empty string if ...
set_incomplete_render
Sets the incomplete_render flag.
int get_draw_buffer_type() const
Returns the RenderBuffer into which the GSG should issue draw commands.
virtual bool supports_pixel_zoom() const
Returns true if a call to set_pixel_zoom() will be respected, false if it will be ignored.
bool get_clear_depth_active() const
Returns the current setting of the flag that indicates whether the depth buffer should be cleared eve...
bool get_clear_color_active() const
Returns the current setting of the flag that indicates whether the color buffer should be cleared eve...
int get_screenshot_buffer_type() const
Returns the RenderBuffer that should be used for capturing screenshots from this particular DrawableR...
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
This class is the main interface to controlling the render process.
static void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, GraphicsStateGuardian *gsg, Thread *current_thread)
Fires off a cull traversal using the indicated camera.
This is a base class for the various different classes that represent the result of a frame of render...
int get_fb_x_size() const
Returns the internal width of the window or buffer.
get_inverted
Returns the current setting of the inverted flag.
get_pipe
Returns the GraphicsPipe that this window is associated with.
bool has_size() const
Returns true if the size of the window/frame buffer is known, false otherwise.
get_gsg
Returns the GSG that is associated with this window.
PStatCollector & get_draw_window_pcollector()
Returns a PStatCollector for timing the draw operation for just this GraphicsOutput.
PStatCollector & get_cull_window_pcollector()
Returns a PStatCollector for timing the cull operation for just this GraphicsOutput.
virtual void end_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread after rendering is completed for a given frame.
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
virtual bool begin_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread before beginning rendering for a given frame.
int get_fb_y_size() const
Returns the internal height of the window or buffer.
get_engine
Returns the graphics engine that created this output.
An object to create GraphicsOutputs that share a particular 3-D API.
Encapsulates all the communication with a particular instance of a given rendering backend.
virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into system memory,...
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop)
Returns a RenderBuffer object suitable for operating on the requested set of buffers.
const GraphicsThreadingModel & get_threading_model() const
Returns the threading model that was used to create this GSG.
int get_draw_stage() const
Returns the pipeline stage from which the draw thread should access data.
A base class for any number of different kinds of lenses, linear and otherwise.
Definition lens.h:41
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition nodePath.I:188
PandaNode * node() const
Returns the referenced node of the path.
Definition nodePath.I:227
NodePath get_top(Thread *current_thread=Thread::get_current_thread()) const
Returns a singleton NodePath that represents the top of the path, or empty NodePath if this path is e...
Definition nodePath.cxx:208
get_name
Returns the name of the referenced node.
Definition nodePath.h:951
set_comment
Writes a user comment string to the image (header).
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
Definition pnmImage.h:58
bool write(const Filename &filename, PNMFileType *type=nullptr) const
Writes the image to the indicated filename.
Definition pnmImage.cxx:385
A lightweight class that represents a single element that may be timed and/or counted via stats.
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer,...
This object holds the camera position, etc., and other general setup information for rendering a part...
Definition sceneSetup.h:32
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition texture.h:72
A thread; that is, a lightweight process.
Definition thread.h:46
get_pipeline_stage
Returns the Pipeline stage number associated with this thread.
Definition thread.h:105
get_current_pipeline_stage
Returns the integer pipeline stage associated with the current thread.
Definition thread.h:110
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.