15 #include "displayRegion.h" 16 #include "stereoDisplayRegion.h" 17 #include "graphicsEngine.h" 18 #include "graphicsOutput.h" 19 #include "config_display.h" 28 TypeHandle DisplayRegionPipelineReader::_type_handle;
38 _incomplete_render(true),
39 _texture_reload_priority(0),
40 _cull_region_pcollector(
"Cull:Invalid"),
41 _draw_region_pcollector(
"Draw:Invalid")
46 set_dimensions(0, dimensions);
47 compute_pixels_all_stages();
49 _window->add_display_region(
this);
60 _cull_region_pcollector(
"Cull:Invalid"),
61 _draw_region_pcollector(
"Draw:Invalid")
102 cdata->_cull_result = NULL;
116 nassertv(pipeline_stage == 0);
118 cdata->_lens_index = index;
133 nassertv(pipeline_stage == 0);
136 cdata->_regions[i]._dimensions = dimensions;
139 do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(), cdata);
152 return (_window != (
GraphicsOutput *)NULL) ? _window->get_pipe() : NULL;
184 nassertv(pipeline_stage == 0 || camera.
is_empty());
189 DCAST_INTO_V(camera_node, camera.
node());
192 if (camera_node != cdata->_camera_node) {
197 if (cdata->_camera_node != (
Camera *)NULL) {
199 cdata->_camera_node->remove_display_region(
this);
201 cdata->_camera_node = camera_node;
202 if (cdata->_camera_node != (
Camera *)NULL) {
204 cdata->_camera_node->add_display_region(
this);
208 cdata->_camera = camera;
221 nassertv(pipeline_stage == 0);
224 if (active != cdata->_active) {
226 cdataw->_active = active;
227 win_display_regions_changed();
244 if (sort != cdata->_sort) {
246 cdataw->_sort = sort;
247 win_display_regions_changed();
287 nassertv(is_stereo() || stereo_channel != Lens::SC_stereo);
292 cdata->_stereo_channel = stereo_channel;
293 cdata->_tex_view_offset = (stereo_channel == Lens::SC_right) ? 1 : 0;
315 cdata->_tex_view_offset = tex_view_offset;
338 _incomplete_render = incomplete_render;
360 _texture_reload_priority = texture_reload_priority;
410 nassertv(pipeline_stage == 0);
412 cdata->_target_tex_page = page;
421 output(ostream &out)
const {
423 out <<
"DisplayRegion(" << cdata->_regions[0]._dimensions
424 <<
")=pixels(" << cdata->_regions[0]._pixels <<
")";
445 time_t now = time(NULL);
446 struct tm *ttm = localtime(&now);
449 static const int buffer_size = 1024;
450 char buffer[buffer_size];
455 while (i < screenshot_filename.length()) {
456 char ch1 = screenshot_filename[i++];
457 if (ch1 ==
'%' && i < screenshot_filename.length()) {
458 char ch2 = screenshot_filename[i++];
459 if (ch2 ==
'~' && i < screenshot_filename.length()) {
460 char ch3 = screenshot_filename[i++];
463 filename_strm << prefix;
467 filename_strm << frame_count;
471 filename_strm << screenshot_extension;
477 char format[3] = {
'%', ch2,
'\0'};
478 if (strftime(buffer, buffer_size, format, ttm)) {
479 for (
char *b = buffer; *b !=
'\0'; b++) {
484 filename_strm <<
'-';
497 filename_strm << ch1;
501 return Filename(filename_strm.str());
515 Filename filename = make_screenshot_filename(prefix);
516 if (save_screenshot(filename)) {
531 if (!get_screenshot(image)) {
536 if (!image.
write(filename)) {
551 PT(
Texture) tex = get_screenshot();
557 if (!tex->store(image)) {
581 if (!window->
begin_frame(GraphicsOutput::FM_refresh, current_thread)) {
594 _window->get_fb_properties());
599 window->
end_frame(GraphicsOutput::FM_refresh, current_thread);
626 make_cull_result_graph() {
631 return cull_result->make_result_graph();
645 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
646 do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
662 nassertv(pipeline_stage == 0);
665 OPEN_ITERATE_ALL_STAGES(_cycler) {
667 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
668 do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
672 CLOSE_ITERATE_ALL_STAGES(_cycler);
686 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
687 do_compute_pixels(i, x_size, y_size, cdata);
702 OPEN_ITERATE_ALL_STAGES(_cycler) {
704 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
705 do_compute_pixels(i, x_size, y_size, cdata);
708 CLOSE_ITERATE_ALL_STAGES(_cycler);
728 if (_window->supports_pixel_zoom()) {
729 return get_clear_color_active() && get_clear_depth_active();
745 win_display_regions_changed() {
747 _window->win_display_regions_changed();
758 do_compute_pixels(
int i,
int x_size,
int y_size, CData *cdata) {
759 if (display_cat.is_debug()) {
761 <<
"DisplayRegion::do_compute_pixels(" << x_size <<
", " << y_size <<
")\n";
764 Region ®ion = cdata->_regions[i];
766 int old_w = region._pixels[1] - region._pixels[0];
767 int old_h = region._pixels[3] - region._pixels[2];
769 region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
770 region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
771 region._pixels_i[0] = region._pixels[0];
772 region._pixels_i[1] = region._pixels[1];
775 if (_window->get_inverted()) {
777 region._pixels[2] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
778 region._pixels[3] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
779 region._pixels_i[2] = int((region._dimensions[3] * y_size) + 0.5);
780 region._pixels_i[3] = int((region._dimensions[2] * y_size) + 0.5);
784 region._pixels[2] = int((region._dimensions[2] * y_size) + 0.5);
785 region._pixels[3] = int((region._dimensions[3] * y_size) + 0.5);
786 region._pixels_i[2] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
787 region._pixels_i[3] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
804 set_active_index(
int index) {
807 strm <<
"dr_" << index;
808 string name = strm.str();
810 _cull_region_pcollector =
PStatCollector(_window->get_cull_window_pcollector(), name);
811 _draw_region_pcollector =
PStatCollector(_window->get_draw_window_pcollector(), name);
833 DisplayRegion::CData::
836 _camera_node((
Camera *)NULL),
839 _stereo_channel(Lens::SC_mono),
841 _target_tex_page(-1),
842 _scissor_enabled(
true)
844 _regions.push_back(
Region());
852 DisplayRegion::CData::
853 CData(
const DisplayRegion::CData ©) :
854 _regions(copy._regions),
855 _lens_index(copy._lens_index),
856 _camera(copy._camera),
857 _camera_node(copy._camera_node),
858 _active(copy._active),
860 _stereo_channel(copy._stereo_channel),
861 _tex_view_offset(copy._tex_view_offset),
862 _target_tex_page(copy._target_tex_page),
863 _scissor_enabled(copy._scissor_enabled)
874 return new CData(*
this);
884 return new CDataCull(*
this);
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
static Filename make_screenshot_filename(const string &prefix="screenshot")
Synthesizes a suitable default filename for passing to save_screenshot().
RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop)
Returns a RenderBuffer object suitable for operating on the requested set of buffers.
A basic node of the scene graph or data graph.
void cleanup()
Cleans up some pointers associated with the DisplayRegion to help reduce the chance of memory leaks d...
GraphicsPipe * get_pipe() const
Returns the GraphicsPipe that this DisplayRegion is ultimately associated with, or NULL if no pipe is...
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...
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
Filename save_screenshot_default(const string &prefix="screenshot")
Saves a screenshot of the region to a default filename, and returns the filename, or empty string if ...
GraphicsPipe * get_pipe() const
Returns the GraphicsPipe that this window is associated with.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
virtual void set_sort(int sort)
Sets the sort value associated with the DisplayRegion.
bool is_empty() const
Returns true if the NodePath contains no nodes.
GraphicsOutput * get_window() const
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
static void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, GraphicsStateGuardian *gsg, Thread *current_thread)
Fires off a cull traversal using the indicated camera.
bool get_screenshot(PNMImage &image)
Captures the most-recently rendered image from the framebuffer into the indicated PNMImage...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
void set_dimensions(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t)
Changes the portion of the framebuffer this DisplayRegion corresponds to.
virtual void set_texture_reload_priority(int texture_reload_priority)
Specifies an integer priority which is assigned to any asynchronous texture reload requests spawned w...
A single page of data maintained by a PipelineCycler.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
void compute_pixels_all_stages()
Computes the pixel locations of the DisplayRegion within its window.
virtual void set_target_tex_page(int page)
This is a special parameter that is only used when rendering the faces of a cube map or multipage and...
bool save_screenshot(const Filename &filename, const string &image_comment="")
Saves a screenshot of the region to the indicated filename.
virtual void set_cull_traverser(CullTraverser *trav)
Specifies 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.
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...
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
A lightweight class that represents a single element that may be timed and/or counted via stats...
virtual void set_tex_view_offset(int tex_view_offset)
Sets the current texture view offset for this DisplayRegion.
virtual bool supports_pixel_zoom() const
Returns true if a call to set_pixel_zoom() will be respected, false if it will be ignored...
virtual void set_active(bool active)
Sets the active flag associated with the DisplayRegion.
virtual void set_incomplete_render(bool incomplete_render)
Sets the incomplete_render flag.
This defines the abstract interface for an object that receives Geoms identified by the CullTraverser...
The name of a file, such as a texture file or an Egg file.
int get_frame_count(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of times tick() has been called since the ClockObject was created, or since it was last reset.
An object to create GraphicsOutputs that share a particular 3-D API.
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
virtual void set_stereo_channel(Lens::StereoChannel stereo_channel)
Specifies whether the DisplayRegion represents the left or right channel of a stereo pair...
bool write(const Filename &filename, PNMFileType *type=NULL) const
Writes the image to the indicated filename.
virtual bool is_stereo() const
Returns true if this is a StereoDisplayRegion, false otherwise.
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
This is a base class for the various different classes that represent the result of a frame of render...
int get_draw_buffer_type() const
Returns the RenderBuffer into which the GSG should issue draw commands.
This is the base class for all three-component vectors and points.
This stores the result of a BinCullHandler traversal: an ordered collection of CullBins, each of which holds a number of Geoms and RenderStates to be rendered in some defined order.
virtual void set_camera(const NodePath &camera)
Sets the camera that is associated with this DisplayRegion.
GraphicsStateGuardian * get_gsg() const
Returns the GSG that is associated with this window.
PandaNode * node() const
Returns the referenced node of the path.
void set_lens_index(int index)
Sets the lens index, allows for multiple lenses to be attached to a camera.
A thread; that is, a lightweight process.
Encapsulates all the communication with a particular instance of a given rendering backend...
CullTraverser * get_cull_traverser()
Returns the CullTraverser that will be used to draw the contents of this DisplayRegion.
A rectangular subregion within a window for rendering into.
TypeHandle is the identifier used to differentiate C++ class types.
This object holds the camera position, etc., and other general setup information for rendering a part...
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
static int get_current_pipeline_stage()
Returns the integer pipeline stage associated with the current thread.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer, etc.) of a drawing region.
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...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
GraphicsPipe * get_pipe() const
Returns the GraphicsPipe that this DisplayRegion is ultimately associated with, or NULL if no pipe is...