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;
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 {
422 CDReader cdata(_cycler);
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());
536 if (!image.
write(filename)) {
557 if (!tex->store(image)) {
581 if (!window->
begin_frame(GraphicsOutput::FM_refresh, current_thread)) {
587 RenderBuffer buffer = gsg->get_render_buffer(get_screenshot_buffer_type(),
588 _window->get_fb_properties());
589 if (!gsg->framebuffer_copy_to_ram(tex, 0, -1, this, buffer)) {
593 window->
end_frame(GraphicsOutput::FM_refresh, current_thread);
620 make_cull_result_graph() {
625 return cull_result->make_result_graph();
639 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
656 nassertv(pipeline_stage == 0);
659 OPEN_ITERATE_ALL_STAGES(_cycler) {
661 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
666 CLOSE_ITERATE_ALL_STAGES(_cycler);
680 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
681 do_compute_pixels(i, x_size, y_size, cdata);
696 OPEN_ITERATE_ALL_STAGES(_cycler) {
698 for (
size_t i = 0; i < cdata->_regions.size(); ++i) {
699 do_compute_pixels(i, x_size, y_size, cdata);
702 CLOSE_ITERATE_ALL_STAGES(_cycler);
739 win_display_regions_changed() {
741 _window->win_display_regions_changed();
752 do_compute_pixels(
int i,
int x_size,
int y_size, CData *cdata) {
753 if (display_cat.is_debug()) {
755 <<
"DisplayRegion::do_compute_pixels(" << x_size <<
", " << y_size <<
")\n";
758 Region ®ion = cdata->_regions[i];
760 int old_w = region._pixels[1] - region._pixels[0];
761 int old_h = region._pixels[3] - region._pixels[2];
763 region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
764 region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
765 region._pixels_i[0] = region._pixels[0];
766 region._pixels_i[1] = region._pixels[1];
771 region._pixels[2] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
772 region._pixels[3] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
773 region._pixels_i[2] = int((region._dimensions[3] * y_size) + 0.5);
774 region._pixels_i[3] = int((region._dimensions[2] * y_size) + 0.5);
778 region._pixels[2] = int((region._dimensions[2] * y_size) + 0.5);
779 region._pixels[3] = int((region._dimensions[3] * y_size) + 0.5);
780 region._pixels_i[2] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
781 region._pixels_i[3] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
798 set_active_index(
int index) {
801 strm <<
"dr_" << index;
802 string name = strm.str();
827 DisplayRegion::CData::
830 _camera_node((
Camera *)NULL),
833 _stereo_channel(
Lens::SC_mono),
835 _target_tex_page(-1),
836 _scissor_enabled(true)
838 _regions.push_back(Region());
846 DisplayRegion::CData::
847 CData(
const DisplayRegion::CData ©) :
848 _regions(copy._regions),
849 _lens_index(copy._lens_index),
850 _camera(copy._camera),
851 _camera_node(copy._camera_node),
852 _active(copy._active),
854 _stereo_channel(copy._stereo_channel),
855 _tex_view_offset(copy._tex_view_offset),
856 _target_tex_page(copy._target_tex_page),
857 _scissor_enabled(copy._scissor_enabled)
868 return new CData(*
this);
878 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().
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...
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 ...
bool has_size() const
Returns true if the size of the window/frame buffer is known, false otherwise.
bool write(const Filename &filename, PNMFileType *type=NULL) const
Writes the image to the indicated filename.
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 get_clear_color_active() const
Returns the current setting of the flag that indicates whether the color buffer should be cleared eve...
A base class for any number of different kinds of lenses, linear and otherwise.
virtual bool is_stereo() const
Returns true if this is a StereoDisplayRegion, false otherwise.
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.
PandaNode * node() const
Returns the referenced node of the path.
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 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 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.
GraphicsPipe * get_pipe() const
Returns the GraphicsPipe that this window is associated with.
PStatCollector & get_draw_window_pcollector()
Returns a PStatCollector for timing the draw operation for just this GraphicsOutput.
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 void set_active(bool active)
Sets the active flag associated with the DisplayRegion.
int get_draw_buffer_type() const
Returns the RenderBuffer into which the GSG should issue draw commands.
virtual void set_incomplete_render(bool incomplete_render)
Sets the incomplete_render flag.
bool get_inverted() const
Returns the current setting of the inverted 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.
virtual bool supports_pixel_zoom() const
Returns true if a call to set_pixel_zoom() will be respected, false if it will be ignored...
GraphicsPipe * get_pipe() const
Returns the GraphicsPipe that this DisplayRegion is ultimately associated with, or NULL if no pipe is...
An object to create GraphicsOutputs that share a particular 3-D API.
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.
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...
GraphicsStateGuardian * get_gsg() const
Returns the GSG that is associated with this window.
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...
GraphicsPipe * get_pipe() const
Returns the GraphicsPipe that this DisplayRegion is ultimately associated with, or NULL if no pipe is...
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.
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.
int get_fb_x_size() const
Returns the internal width of the window or buffer.
bool get_clear_depth_active() const
Returns the current setting of the flag that indicates whether the depth buffer should be cleared eve...
Encapsulates all the communication with a particular instance of a given rendering backend...
bool is_empty() const
Returns true if the NodePath contains no nodes.
CullTraverser * get_cull_traverser()
Returns the CullTraverser that will be used to draw the contents of this DisplayRegion.
int get_fb_y_size() const
Returns the internal height of the window or buffer.
A rectangular subregion within a window for rendering into.
PStatCollector & get_cull_window_pcollector()
Returns a PStatCollector for timing the cull operation for just this GraphicsOutput.
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...