diff --git a/panda/src/display/Sources.pp b/panda/src/display/Sources.pp index c1488fac69..592c5a01a8 100644 --- a/panda/src/display/Sources.pp +++ b/panda/src/display/Sources.pp @@ -33,6 +33,7 @@ windowProperties.I windowProperties.h \ renderBuffer.h \ stencilRenderStates.h \ + stereoDisplayRegion.I stereoDisplayRegion.h \ displaySearchParameters.h \ displayInformation.h @@ -55,6 +56,7 @@ windowProperties.cxx \ lru.cxx \ stencilRenderStates.cxx \ + stereoDisplayRegion.cxx \ displaySearchParameters.cxx \ displayInformation.cxx @@ -80,6 +82,7 @@ windowProperties.I windowProperties.h \ renderBuffer.h \ stencilRenderStates.h \ + stereoDisplayRegion.I stereoDisplayRegion.h \ displaySearchParameters.h \ displayInformation.h diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index 21b3a8547f..f84f6ec6d1 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -24,6 +24,7 @@ #include "graphicsDevice.h" #include "parasiteBuffer.h" #include "pandaSystem.h" +#include "stereoDisplayRegion.h" ConfigureDef(config_display); NotifyCategoryDef(display, ""); @@ -197,6 +198,14 @@ ConfigVariableString red_blue_stereo_colors "'green', 'cyan', 'magenta', 'yellow', or 'alpha', or a union " "of two or more words separated by a vertical pipe (|).")); +ConfigVariableBool default_stereo_camera +("default-stereo-camera", true, + PRC_DESC("When this is true, the default DisplayRegion created for " + "a window or buffer with the stereo property will be a " + "StereoDisplayRegion, which activates the stereo properties of " + "the camera lens, and enables stereo. Set this false to " + "require StereoDisplayRegions to be created explicitly.")); + ConfigVariableBool color_scale_via_lighting ("color-scale-via-lighting", true, PRC_DESC("When this is true, Panda will try to implement ColorAttribs and " @@ -369,6 +378,7 @@ init_libdisplay() { GraphicsWindow::init_type(); ParasiteBuffer::init_type(); StandardMunger::init_type(); + StereoDisplayRegion::init_type(); #if defined(HAVE_THREADS) && defined(DO_PIPELINING) PandaSystem *ps = PandaSystem::get_global_ptr(); diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index 81e8cc6756..487dec0e71 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -57,6 +57,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool copy_texture_inverted; extern EXPCL_PANDA_DISPLAY ConfigVariableBool window_inverted; extern EXPCL_PANDA_DISPLAY ConfigVariableBool red_blue_stereo; extern EXPCL_PANDA_DISPLAY ConfigVariableString red_blue_stereo_colors; +extern EXPCL_PANDA_DISPLAY ConfigVariableBool default_stereo_camera; extern EXPCL_PANDA_DISPLAY ConfigVariableBool color_scale_via_lighting; extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture; extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_incomplete_render; diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 9946522021..3b232e4296 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -155,63 +155,9 @@ get_stereo_channel() { return cdata->_stereo_channel; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_clear_depth_between_eyes -// Access: Published -// Description: Specifies whether the depth buffer is cleared again -// between the left and right eyes of a stereo -// DisplayRegion. This has an effect only when -// get_stereo_channel() returns Lens::SC_stereo; other -// kinds of DisplayRegions are monocular and do not -// render two different eyes. -// -// Normally, you want this to be true, since if you're -// using a depth buffer you normally need to clear it -// between the left and right eyes. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -set_clear_depth_between_eyes(bool clear_depth_between_eyes) { - _clear_depth_between_eyes = clear_depth_between_eyes; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_clear_depth_between_eyes -// Access: Published -// Description: Returns whether the depth buffer is cleared again -// between the left and right eyes of a stereo -// DisplayRegion. See set_clear_depth_between_eyes(). -//////////////////////////////////////////////////////////////////// -INLINE bool DisplayRegion:: -get_clear_depth_between_eyes() const { - return _clear_depth_between_eyes; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_incomplete_render -// Access: Public -// Description: Sets the incomplete_render flag. When this is -// true, the frame will be rendered even if some of the -// geometry or textures in the scene are not available -// (e.g. they have been temporarily paged out). When -// this is false, the frame will be held up while this -// data is reloaded. -// -// This flag may also be set on the -// GraphicsStateGuardian. It will be considered true -// for a given DisplayRegion only if it is true on both -// the GSG and on the DisplayRegion. -// -// See GraphicsStateGuardian::set_incomplete_render() -// for more detail. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -set_incomplete_render(bool incomplete_render) { - _incomplete_render = incomplete_render; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_incomplete_render -// Access: Public, Virtual +// Access: Published // Description: Returns the incomplete_render flag. See // set_incomplete_render(). //////////////////////////////////////////////////////////////////// @@ -220,28 +166,6 @@ get_incomplete_render() const { return _incomplete_render; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_texture_reload_priority -// Access: Published -// Description: Specifies an integer priority which is assigned to -// any asynchronous texture reload requests spawned -// while processing this DisplayRegion. This controls -// which textures are loaded first when multiple -// textures need to be reloaded at once; it also -// controls the relative priority between asynchronous -// texture loads and asynchronous model or animation -// loads. -// -// Specifying a larger number here makes the textures -// rendered by this DisplayRegion load up first. This -// may be particularly useful to do, for instance, for -// the DisplayRegion that renders the gui. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -set_texture_reload_priority(int texture_reload_priority) { - _texture_reload_priority = texture_reload_priority; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_texture_reload_priority // Access: Published @@ -254,38 +178,6 @@ get_texture_reload_priority() const { return _texture_reload_priority; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_cull_traverser -// Access: Published -// Description: Specifies the CullTraverser that will be used to draw -// the contents of this DisplayRegion. Normally the -// default CullTraverser is sufficient, but this may be -// changed to change the default cull behavior. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -set_cull_traverser(CullTraverser *trav) { - _trav = trav; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_cube_map_index -// Access: Published -// Description: This is a special parameter that is only used when -// rendering the faces of a cube map. Normally you -// should not need to set it directly. This sets up the -// DisplayRegion to render to the nth cube map face; the -// value must be between 0 and 5, inclusive. A normal -// DisplayRegion that is not associated with any -// particular cube map should be set to -1. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -set_cube_map_index(int cube_map_index) { - int pipeline_stage = Thread::get_current_pipeline_stage(); - nassertv(pipeline_stage == 0); - CDWriter cdata(_cycler); - cdata->_cube_map_index = cube_map_index; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_cube_map_index // Access: Published @@ -300,54 +192,6 @@ get_cube_map_index() const { return cdata->_cube_map_index; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_pixels -// Access: Published -// Description: Retrieves the coordinates of the DisplayRegion within -// its window, in pixels. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -get_pixels(int &pl, int &pr, int &pb, int &pt) const { - CDReader cdata(_cycler); - pl = cdata->_pl; - pr = cdata->_pr; - pb = cdata->_pb; - pt = cdata->_pt; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_region_pixels -// Access: Published -// Description: Retrieves the coordinates of the DisplayRegion within -// its window, as the pixel location of its bottom-left -// corner, along with a pixel width and height. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -get_region_pixels(int &xo, int &yo, int &w, int &h) const { - CDReader cdata(_cycler); - xo = cdata->_pl; - yo = cdata->_pb; - w = cdata->_pr - cdata->_pl; - h = cdata->_pt - cdata->_pb; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_region_pixels_i -// Access: Published -// Description: Similar to get_region_pixels(), but returns the upper -// left corner, and the pixel numbers are numbered from -// the top-left corner down, in the DirectX way of -// things. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -get_region_pixels_i(int &xo, int &yo, int &w, int &h) const { - CDReader cdata(_cycler); - xo = cdata->_pl; - yo = cdata->_pti; - w = cdata->_pr - cdata->_pl; - h = cdata->_pbi - cdata->_pti; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_pixel_width // Access: Published @@ -370,6 +214,54 @@ get_pixel_height() const { return cdata->_pt - cdata->_pb; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_pixels +// Access: Public +// Description: Retrieves the coordinates of the DisplayRegion within +// its window, in pixels. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +get_pixels(int &pl, int &pr, int &pb, int &pt) const { + CDReader cdata(_cycler); + pl = cdata->_pl; + pr = cdata->_pr; + pb = cdata->_pb; + pt = cdata->_pt; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_region_pixels +// Access: Public +// Description: Retrieves the coordinates of the DisplayRegion within +// its window, as the pixel location of its bottom-left +// corner, along with a pixel width and height. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +get_region_pixels(int &xo, int &yo, int &w, int &h) const { + CDReader cdata(_cycler); + xo = cdata->_pl; + yo = cdata->_pb; + w = cdata->_pr - cdata->_pl; + h = cdata->_pt - cdata->_pb; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_region_pixels_i +// Access: Public +// Description: Similar to get_region_pixels(), but returns the upper +// left corner, and the pixel numbers are numbered from +// the top-left corner down, in the DirectX way of +// things. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +get_region_pixels_i(int &xo, int &yo, int &w, int &h) const { + CDReader cdata(_cycler); + xo = cdata->_pl; + yo = cdata->_pti; + w = cdata->_pr - cdata->_pl; + h = cdata->_pbi - cdata->_pti; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_cull_result // Access: Public @@ -674,18 +566,6 @@ get_stereo_channel() { return _cdata->_stereo_channel; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegionPipelineReader::get_clear_depth_between_eyes -// Access: Public -// Description: Returns whether the depth buffer is cleared again -// between the left and right eyes of a stereo -// DisplayRegion. See set_clear_depth_between_eyes(). -//////////////////////////////////////////////////////////////////// -INLINE bool DisplayRegionPipelineReader:: -get_clear_depth_between_eyes() const { - return _object->_clear_depth_between_eyes; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegionPipelineReader::get_cube_map_index // Access: Public @@ -763,8 +643,3 @@ INLINE int DisplayRegionPipelineReader:: get_pixel_height() const { return _cdata->_pt - _cdata->_pb; } - -INLINE ostream &operator << (ostream &out, const DisplayRegion &dr) { - dr.output(out); - return out; -} diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index ac136497fd..68745b4aa1 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -13,6 +13,7 @@ //////////////////////////////////////////////////////////////////// #include "displayRegion.h" +#include "stereoDisplayRegion.h" #include "graphicsOutput.h" #include "config_display.h" #include "texture.h" @@ -25,32 +26,12 @@ TypeHandle DisplayRegionPipelineReader::_type_handle; //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -DisplayRegion:: -DisplayRegion(GraphicsOutput *window) : - _window(window), - _clear_depth_between_eyes(true), - _incomplete_render(true), - _texture_reload_priority(0), - _cull_region_pcollector("Cull:Invalid"), - _draw_region_pcollector("Draw:Invalid") -{ - _screenshot_buffer_type = window->get_draw_buffer_type(); - _draw_buffer_type = window->get_draw_buffer_type(); - compute_pixels_all_stages(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::Constructor -// Access: Public +// Access: Protected // Description: //////////////////////////////////////////////////////////////////// DisplayRegion:: DisplayRegion(GraphicsOutput *window, float l, float r, float b, float t) : _window(window), - _clear_depth_between_eyes(true), _incomplete_render(true), _texture_reload_priority(0), _cull_region_pcollector("Cull:Invalid"), @@ -68,11 +49,11 @@ DisplayRegion(GraphicsOutput *window, float l, float r, float b, float t) : // Description: //////////////////////////////////////////////////////////////////// DisplayRegion:: -DisplayRegion(const DisplayRegion &) : +DisplayRegion(const DisplayRegion ©) : + _window(NULL), _cull_region_pcollector("Cull:Invalid"), _draw_region_pcollector("Draw:Invalid") { - nassertv(false); } //////////////////////////////////////////////////////////////////// @@ -117,7 +98,7 @@ cleanup() { //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_dimensions -// Access: Published +// Access: Published, Virtual // Description: Changes the portion of the framebuffer this // DisplayRegion corresponds to. The parameters range // from 0 to 1, where 0,0 is the lower left corner and @@ -152,9 +133,20 @@ get_pipe() const { return (_window != (GraphicsOutput *)NULL) ? _window->get_pipe() : NULL; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::is_stereo +// Access: Published, Virtual +// Description: Returns true if this is a StereoDisplayRegion, false +// otherwise. +//////////////////////////////////////////////////////////////////// +bool DisplayRegion:: +is_stereo() const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_camera -// Access: Published +// Access: Published, Virtual // Description: Sets the camera that is associated with this // DisplayRegion. There is a one-to-many association // between cameras and DisplayRegions; one camera may be @@ -196,7 +188,7 @@ set_camera(const NodePath &camera) { //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_active -// Access: Published +// Access: Published, Virtual // Description: Sets the active flag associated with the // DisplayRegion. If the DisplayRegion is marked // inactive, nothing is rendered. @@ -216,7 +208,7 @@ set_active(bool active) { //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_sort -// Access: Published +// Access: Published, Virtual // Description: Sets the sort value associated with the // DisplayRegion. Within a window, DisplayRegions will // be rendered in order from the lowest sort value to @@ -236,17 +228,18 @@ set_sort(int sort) { //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_stereo_channel -// Access: Published +// Access: Published, Virtual // Description: Specifies whether the DisplayRegion represents the // left or right channel of a stereo pair, or whether it -// is a normal, monocular image. See -// set_stereo_channel(). +// is a normal, monocular image. This automatically +// adjusts the lens that is used to render to this +// DisplayRegion to its left or right eye, according to +// the lens's stereo properties. // -// This controls which direction--to the left or the -// right--the view from a PerspectiveLens is shifted -// when it is used to render into this DisplayRegion. -// Also see Lens::set_interocular_distance() and -// Lens::set_convergence_distance(). +// When the DisplayRegion is attached to a stereo window +// (one for which is_stereo() returns true), this also +// specifies which physical channel the DisplayRegion +// renders to. // // Normally you would create at least two DisplayRegions // for a stereo window, one for each of the left and @@ -255,19 +248,81 @@ set_sort(int sort) { // is used to control the exact properties of the lens // when it is used to render into this DisplayRegion. // -// When the DisplayRegion is attached to a stereo window -// (one in which FrameBufferProperties::FM_stereo is -// set), this also specifies which physical channel the -// DisplayRegion renders to. +// Also see the StereoDisplayRegion, which automates +// managing a pair of left/right DisplayRegions. +// +// An ordinary DisplayRegion may be set to SC_mono, +// SC_left, or SC_right. You may set SC_stereo only on +// a StereoDisplayRegion. //////////////////////////////////////////////////////////////////// void DisplayRegion:: set_stereo_channel(Lens::StereoChannel stereo_channel) { + nassertv(is_stereo() || stereo_channel != Lens::SC_stereo); + nassertv(Thread::get_current_pipeline_stage() == 0); CDWriter cdata(_cycler); cdata->_stereo_channel = stereo_channel; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::set_incomplete_render +// Access: Published, Virtual +// Description: Sets the incomplete_render flag. When this is +// true, the frame will be rendered even if some of the +// geometry or textures in the scene are not available +// (e.g. they have been temporarily paged out). When +// this is false, the frame will be held up while this +// data is reloaded. +// +// This flag may also be set on the +// GraphicsStateGuardian. It will be considered true +// for a given DisplayRegion only if it is true on both +// the GSG and on the DisplayRegion. +// +// See GraphicsStateGuardian::set_incomplete_render() +// for more detail. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +set_incomplete_render(bool incomplete_render) { + _incomplete_render = incomplete_render; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::set_texture_reload_priority +// Access: Published, Virtual +// Description: Specifies an integer priority which is assigned to +// any asynchronous texture reload requests spawned +// while processing this DisplayRegion. This controls +// which textures are loaded first when multiple +// textures need to be reloaded at once; it also +// controls the relative priority between asynchronous +// texture loads and asynchronous model or animation +// loads. +// +// Specifying a larger number here makes the textures +// rendered by this DisplayRegion load up first. This +// may be particularly useful to do, for instance, for +// the DisplayRegion that renders the gui. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +set_texture_reload_priority(int texture_reload_priority) { + _texture_reload_priority = texture_reload_priority; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::set_cull_traverser +// Access: Published, Virtual +// Description: Specifies the CullTraverser that will be used to draw +// the contents of this DisplayRegion. Normally the +// default CullTraverser is sufficient, but this may be +// changed to change the default cull behavior. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +set_cull_traverser(CullTraverser *trav) { + _trav = trav; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_cull_traverser // Access: Published @@ -283,82 +338,27 @@ get_cull_traverser() { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::compute_pixels -// Access: Published -// Description: Computes the pixel locations of the DisplayRegion -// within its window. The DisplayRegion will request -// the size from the window. +// Function: DisplayRegion::set_cube_map_index +// Access: Published, Virtual +// Description: This is a special parameter that is only used when +// rendering the faces of a cube map. Normally you +// should not need to set it directly. This sets up the +// DisplayRegion to render to the nth cube map face; the +// value must be between 0 and 5, inclusive. A normal +// DisplayRegion that is not associated with any +// particular cube map should be set to -1. //////////////////////////////////////////////////////////////////// void DisplayRegion:: -compute_pixels() { - int pipeline_stage = Thread::get_current_pipeline_stage(); - nassertv(pipeline_stage == 0); - - if (_window != (GraphicsOutput *)NULL) { - CDWriter cdata(_cycler); - do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(), - cdata); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::compute_pixels_all_stages -// Access: Published -// Description: Computes the pixel locations of the DisplayRegion -// within its window. The DisplayRegion will request -// the size from the window. -//////////////////////////////////////////////////////////////////// -void DisplayRegion:: -compute_pixels_all_stages() { - int pipeline_stage = Thread::get_current_pipeline_stage(); - nassertv(pipeline_stage == 0); - - if (_window != (GraphicsOutput *)NULL) { - OPEN_ITERATE_ALL_STAGES(_cycler) { - CDStageWriter cdata(_cycler, pipeline_stage); - do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(), - cdata); - } - CLOSE_ITERATE_ALL_STAGES(_cycler); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::compute_pixels -// Access: Published -// Description: Computes the pixel locations of the DisplayRegion -// within its window, given the size of the window in -// pixels. -//////////////////////////////////////////////////////////////////// -void DisplayRegion:: -compute_pixels(int x_size, int y_size) { +set_cube_map_index(int cube_map_index) { int pipeline_stage = Thread::get_current_pipeline_stage(); nassertv(pipeline_stage == 0); CDWriter cdata(_cycler); - do_compute_pixels(x_size, y_size, cdata); -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::compute_pixels_all_stages -// Access: Published -// Description: Performs a compute_pixels() operation for all stages -// of the pipeline. This is appropriate, for instance, -// when a window changes sizes, since this is a global -// operation; and you want the new window size to be -// immediately available even to the downstream stages. -//////////////////////////////////////////////////////////////////// -void DisplayRegion:: -compute_pixels_all_stages(int x_size, int y_size) { - OPEN_ITERATE_ALL_STAGES(_cycler) { - CDStageWriter cdata(_cycler, pipeline_stage); - do_compute_pixels(x_size, y_size, cdata); - } - CLOSE_ITERATE_ALL_STAGES(_cycler); + cdata->_cube_map_index = cube_map_index; } //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::output -// Access: Published +// Access: Published, Virtual // Description: //////////////////////////////////////////////////////////////////// void DisplayRegion:: @@ -526,7 +526,7 @@ get_screenshot(PNMImage &image) { //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::make_cull_result_graph -// Access: Public +// Access: Published // Description: Returns a special scene graph constructed to // represent the results of the last frame's cull // operation. @@ -554,9 +554,83 @@ make_cull_result_graph() { return cull_result->make_result_graph(); } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::compute_pixels +// Access: Public +// Description: Computes the pixel locations of the DisplayRegion +// within its window. The DisplayRegion will request +// the size from the window. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +compute_pixels() { + int pipeline_stage = Thread::get_current_pipeline_stage(); + nassertv(pipeline_stage == 0); + + if (_window != (GraphicsOutput *)NULL) { + CDWriter cdata(_cycler); + do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(), + cdata); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::compute_pixels_all_stages +// Access: Public +// Description: Computes the pixel locations of the DisplayRegion +// within its window. The DisplayRegion will request +// the size from the window. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +compute_pixels_all_stages() { + int pipeline_stage = Thread::get_current_pipeline_stage(); + nassertv(pipeline_stage == 0); + + if (_window != (GraphicsOutput *)NULL) { + OPEN_ITERATE_ALL_STAGES(_cycler) { + CDStageWriter cdata(_cycler, pipeline_stage); + do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(), + cdata); + } + CLOSE_ITERATE_ALL_STAGES(_cycler); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::compute_pixels +// Access: Public +// Description: Computes the pixel locations of the DisplayRegion +// within its window, given the size of the window in +// pixels. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +compute_pixels(int x_size, int y_size) { + int pipeline_stage = Thread::get_current_pipeline_stage(); + nassertv(pipeline_stage == 0); + CDWriter cdata(_cycler); + do_compute_pixels(x_size, y_size, cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::compute_pixels_all_stages +// Access: Public +// Description: Performs a compute_pixels() operation for all stages +// of the pipeline. This is appropriate, for instance, +// when a window changes sizes, since this is a global +// operation; and you want the new window size to be +// immediately available even to the downstream stages. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +compute_pixels_all_stages(int x_size, int y_size) { + OPEN_ITERATE_ALL_STAGES(_cycler) { + CDStageWriter cdata(_cycler, pipeline_stage); + do_compute_pixels(x_size, y_size, cdata); + } + CLOSE_ITERATE_ALL_STAGES(_cycler); +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::supports_pixel_zoom -// Access: Published, Virtual +// Access: Public, Virtual // Description: Returns true if a call to set_pixel_zoom() will be // respected, false if it will be ignored. If this // returns false, then get_pixel_factor() will always diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 13f8f2e259..45c29e681b 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -17,6 +17,7 @@ #include "pandabase.h" +#include "displayRegionBase.h" #include "drawableRegion.h" #include "referenceCount.h" #include "nodePath.h" @@ -54,11 +55,11 @@ class CullTraverser; // glass, usually for layering 2-d interfaces on top of // a 3-d scene. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA_DISPLAY DisplayRegion : public ReferenceCount, public DrawableRegion { +class EXPCL_PANDA_DISPLAY DisplayRegion : public DisplayRegionBase, public DrawableRegion { protected: - DisplayRegion(GraphicsOutput *window); DisplayRegion(GraphicsOutput *window, float l, float r, float b, float t); + private: DisplayRegion(const DisplayRegion ©); void operator = (const DisplayRegion ©); @@ -75,50 +76,40 @@ PUBLISHED: INLINE float get_right() const; INLINE float get_bottom() const; INLINE float get_top() const; - void set_dimensions(float l, float r, float b, float t); + virtual void set_dimensions(float l, float r, float b, float t); INLINE GraphicsOutput *get_window() const; GraphicsPipe *get_pipe() const; + virtual bool is_stereo() const; - void set_camera(const NodePath &camera); + virtual void set_camera(const NodePath &camera); INLINE NodePath get_camera(Thread *current_thread = Thread::get_current_thread()) const; - void set_active(bool active); + virtual void set_active(bool active); INLINE bool is_active() const; - void set_sort(int sort); + virtual void set_sort(int sort); INLINE int get_sort() const; - void set_stereo_channel(Lens::StereoChannel stereo_channel); + virtual void set_stereo_channel(Lens::StereoChannel stereo_channel); INLINE Lens::StereoChannel get_stereo_channel(); - INLINE void set_clear_depth_between_eyes(bool clear_depth_between_eyes); - INLINE bool get_clear_depth_between_eyes() const; - - INLINE void set_incomplete_render(bool incomplete_render); + virtual void set_incomplete_render(bool incomplete_render); INLINE bool get_incomplete_render() const; - INLINE void set_texture_reload_priority(int texture_reload_priority); + virtual void set_texture_reload_priority(int texture_reload_priority); INLINE int get_texture_reload_priority() const; - INLINE void set_cull_traverser(CullTraverser *trav); + virtual void set_cull_traverser(CullTraverser *trav); CullTraverser *get_cull_traverser(); - INLINE void set_cube_map_index(int cube_map_index); + virtual void set_cube_map_index(int cube_map_index); INLINE int get_cube_map_index() const; - void compute_pixels(); - void compute_pixels_all_stages(); - void compute_pixels(int x_size, int y_size); - void compute_pixels_all_stages(int x_size, int y_size); - INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; - INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const; - INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const; - INLINE int get_pixel_width() const; INLINE int get_pixel_height() const; - void output(ostream &out) const; + virtual void output(ostream &out) const; static Filename make_screenshot_filename( const string &prefix = "screenshot"); @@ -127,9 +118,17 @@ PUBLISHED: const Filename &filename, const string &image_comment = ""); bool get_screenshot(PNMImage &image); - PT(PandaNode) make_cull_result_graph(); + virtual PT(PandaNode) make_cull_result_graph(); public: + void compute_pixels(); + void compute_pixels_all_stages(); + void compute_pixels(int x_size, int y_size); + void compute_pixels_all_stages(int x_size, int y_size); + INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; + INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const; + INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const; + virtual bool supports_pixel_zoom() const; INLINE void set_cull_result(CullResult *cull_result, SceneSetup *scene_setup, @@ -147,10 +146,10 @@ private: void do_compute_pixels(int x_size, int y_size, CData *cdata); void set_active_index(int index); +protected: // The associated window is a permanent property of the // DisplayRegion. It doesn't need to be cycled. GraphicsOutput *_window; - bool _clear_depth_between_eyes; bool _incomplete_render; int _texture_reload_priority; @@ -158,6 +157,7 @@ private: // Ditto for the cull traverser. PT(CullTraverser) _trav; +private: // This is the data that is associated with the DisplayRegion that // needs to be cycled every frame, but represents the parameters as // specified by the user, and which probably will not change that @@ -230,10 +230,14 @@ public: return _type_handle; } static void init_type() { - ReferenceCount::init_type(); + DisplayRegionBase::init_type(); register_type(_type_handle, "DisplayRegion", - ReferenceCount::get_class_type()); + DisplayRegionBase::get_class_type()); } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} private: static TypeHandle _type_handle; @@ -303,8 +307,6 @@ private: static TypeHandle _type_handle; }; -INLINE ostream &operator << (ostream &out, const DisplayRegion &dr); - #include "displayRegion.I" #endif /* DISPLAYREGION_H */ diff --git a/panda/src/display/display_composite2.cxx b/panda/src/display/display_composite2.cxx index 70934678fe..1d9152995a 100644 --- a/panda/src/display/display_composite2.cxx +++ b/panda/src/display/display_composite2.cxx @@ -12,3 +12,4 @@ #include "stencilRenderStates.cxx" #include "displaySearchParameters.cxx" #include "displayInformation.cxx" +#include "stereoDisplayRegion.cxx" diff --git a/panda/src/display/drawableRegion.I b/panda/src/display/drawableRegion.I index 3e6a89337d..cab362fa1f 100644 --- a/panda/src/display/drawableRegion.I +++ b/panda/src/display/drawableRegion.I @@ -93,8 +93,7 @@ copy_clear_settings(const DrawableRegion ©) { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_color_active(bool clear_color_active) { - _clear_active[RTP_color] = clear_color_active; - update_pixel_factor(); + set_clear_active(RTP_color, clear_color_active); } //////////////////////////////////////////////////////////////////// @@ -106,7 +105,7 @@ set_clear_color_active(bool clear_color_active) { //////////////////////////////////////////////////////////////////// INLINE bool DrawableRegion:: get_clear_color_active() const { - return _clear_active[RTP_color]; + return get_clear_active(RTP_color); } //////////////////////////////////////////////////////////////////// @@ -120,8 +119,7 @@ get_clear_color_active() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_depth_active(bool clear_depth_active) { - _clear_active[RTP_depth] = clear_depth_active; - update_pixel_factor(); + set_clear_active(RTP_depth, clear_depth_active); } //////////////////////////////////////////////////////////////////// @@ -133,7 +131,7 @@ set_clear_depth_active(bool clear_depth_active) { //////////////////////////////////////////////////////////////////// INLINE bool DrawableRegion:: get_clear_depth_active() const { - return _clear_active[RTP_depth]; + return get_clear_active(RTP_depth); } //////////////////////////////////////////////////////////////////// @@ -147,7 +145,7 @@ get_clear_depth_active() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_stencil_active(bool clear_stencil_active) { - _clear_active[RTP_stencil] = clear_stencil_active; + set_clear_active(RTP_stencil, clear_stencil_active); } //////////////////////////////////////////////////////////////////// @@ -159,30 +157,7 @@ set_clear_stencil_active(bool clear_stencil_active) { //////////////////////////////////////////////////////////////////// INLINE bool DrawableRegion:: get_clear_stencil_active() const { - return _clear_active[RTP_stencil]; -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawableRegion::set_clear_active -// Access: Published -// Description: Sets the clear-active flag for any bitplane. -//////////////////////////////////////////////////////////////////// -INLINE void DrawableRegion:: -set_clear_active(int n, bool clear_active) { - nassertv((n >= 0)&&(n < RTP_COUNT)); - _clear_active[n] = clear_active; - update_pixel_factor(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawableRegion::get_clear_active -// Access: Published -// Description: Gets the clear-active flag for any bitplane. -//////////////////////////////////////////////////////////////////// -INLINE bool DrawableRegion:: -get_clear_active(int n) const { - nassertr((n >= 0)&&(n < RTP_COUNT), false); - return _clear_active[n]; + return get_clear_active(RTP_stencil); } //////////////////////////////////////////////////////////////////// @@ -196,7 +171,7 @@ get_clear_active(int n) const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_color(const Colorf &color) { - _clear_value[RTP_color] = color; + set_clear_value(RTP_color, color); } //////////////////////////////////////////////////////////////////// @@ -210,7 +185,7 @@ set_clear_color(const Colorf &color) { //////////////////////////////////////////////////////////////////// INLINE const Colorf &DrawableRegion:: get_clear_color() const { - return _clear_value[RTP_color]; + return get_clear_value(RTP_color); } //////////////////////////////////////////////////////////////////// @@ -224,7 +199,7 @@ get_clear_color() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_depth(float depth) { - _clear_value[RTP_depth] = Colorf(depth,depth,depth,depth); + set_clear_value(RTP_depth, Colorf(depth,depth,depth,depth)); } //////////////////////////////////////////////////////////////////// @@ -238,7 +213,7 @@ set_clear_depth(float depth) { //////////////////////////////////////////////////////////////////// INLINE float DrawableRegion:: get_clear_depth() const { - return _clear_value[RTP_depth][0]; + return get_clear_value(RTP_depth)[0]; } //////////////////////////////////////////////////////////////////// // Function: DrawableRegion::set_clear_stencil @@ -251,7 +226,7 @@ get_clear_depth() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_stencil(const unsigned int stencil) { - _clear_value[RTP_stencil] = Colorf(stencil,stencil,stencil,stencil); + set_clear_value(RTP_stencil, Colorf(stencil,stencil,stencil,stencil)); } //////////////////////////////////////////////////////////////////// @@ -265,92 +240,7 @@ set_clear_stencil(const unsigned int stencil) { //////////////////////////////////////////////////////////////////// INLINE unsigned int DrawableRegion:: get_clear_stencil() const { - return (int)(_clear_value[RTP_stencil][0]); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawableRegion::set_clear_value -// Access: Published -// Description: Sets the clear value for any bitplane. -//////////////////////////////////////////////////////////////////// -INLINE void DrawableRegion:: -set_clear_value(int n, const Colorf &color) { - nassertv((n >= 0) && (n < RTP_COUNT)); - _clear_value[n] = color; -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawableRegion::get_clear_value -// Access: Published -// Description: Returns the clear value for any bitplane. -//////////////////////////////////////////////////////////////////// -INLINE const Colorf &DrawableRegion:: -get_clear_value(int n) const { - static Colorf blank(0.5,0.5,0.5,0.0); - nassertr((n >= 0) && (n < RTP_COUNT), blank); - return _clear_value[n]; -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawableRegion::disable_clears -// Access: Published -// Description: Disables both the color and depth clear. See -// set_clear_color_active and set_clear_depth_active. -//////////////////////////////////////////////////////////////////// -INLINE void DrawableRegion:: -disable_clears() { - for (int i=0; i= 0)&&(n < RTP_COUNT)); + _clear_active[n] = clear_active; + update_pixel_factor(); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::get_clear_active +// Access: Published, Virtual +// Description: Gets the clear-active flag for any bitplane. +//////////////////////////////////////////////////////////////////// +bool DrawableRegion:: +get_clear_active(int n) const { + nassertr((n >= 0)&&(n < RTP_COUNT), false); + return _clear_active[n]; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::set_clear_value +// Access: Published, Virtual +// Description: Sets the clear value for any bitplane. +//////////////////////////////////////////////////////////////////// +void DrawableRegion:: +set_clear_value(int n, const Colorf &clear_value) { + nassertv((n >= 0) && (n < RTP_COUNT)); + _clear_value[n] = clear_value; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::get_clear_value +// Access: Published, Virtual +// Description: Returns the clear value for any bitplane. +//////////////////////////////////////////////////////////////////// +const Colorf &DrawableRegion:: +get_clear_value(int n) const { + static Colorf blank(0.5,0.5,0.5,0.0); + nassertr((n >= 0) && (n < RTP_COUNT), blank); + return _clear_value[n]; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::disable_clears +// Access: Published, Virtual +// Description: Disables both the color and depth clear. See +// set_clear_color_active and set_clear_depth_active. +//////////////////////////////////////////////////////////////////// +void DrawableRegion:: +disable_clears() { + for (int i = 0; i < RTP_COUNT; ++i) { + _clear_active[i] = false; + } + update_pixel_factor(); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::is_any_clear_active +// Access: Published, Virtual +// Description: Returns true if any of the clear types (so far there +// are just color or depth) have been set active, or +// false if none of them are active and there is no need +// to clear. +//////////////////////////////////////////////////////////////////// +bool DrawableRegion:: +is_any_clear_active() const { + for (int i = 0; i < RTP_COUNT; ++i) { + if (get_clear_active(i)) { + return true; + } + } + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::set_pixel_zoom +// Access: Published, Virtual +// Description: Sets the amount by which the pixels of the region are +// scaled internally when filling the image interally. +// Setting this number larger makes the pixels blockier, +// but may make the rendering faster, particularly for +// software renderers. Setting this number to 2.0 +// reduces the number of pixels that have to be filled +// by the renderer by a factor of 2.0. It doesn't make +// sense to set this lower than 1.0. +// +// It is possible to set this on either individual +// DisplayRegions or on overall GraphicsWindows, but you +// will get better performance for setting it on the +// window rather than its individual DisplayRegions. +// Also, you may not set it on a DisplayRegion that +// doesn't have both clear_color() and clear_depth() +// enabled. +// +// This property is only supported on renderers for +// which it is particularly useful--currently, this is +// the tinydisplay software renderer. Other kinds of +// renderers allow you to set this property, but ignore +// it. +//////////////////////////////////////////////////////////////////// +void DrawableRegion:: +set_pixel_zoom(float pixel_zoom) { + _pixel_zoom = pixel_zoom; + update_pixel_factor(); +} + //////////////////////////////////////////////////////////////////// // Function: DrawableRegion::supports_pixel_zoom // Access: Published, Virtual diff --git a/panda/src/display/drawableRegion.h b/panda/src/display/drawableRegion.h index d889a0d4ed..29bc2ae508 100644 --- a/panda/src/display/drawableRegion.h +++ b/panda/src/display/drawableRegion.h @@ -65,10 +65,10 @@ PUBLISHED: INLINE void set_clear_color_active(bool clear_color_active); INLINE bool get_clear_color_active() const; - + INLINE void set_clear_depth_active(bool clear_depth_active); INLINE bool get_clear_depth_active() const; - + INLINE void set_clear_stencil_active(bool clear_stencil_active); INLINE bool get_clear_stencil_active() const; @@ -81,17 +81,16 @@ PUBLISHED: INLINE void set_clear_stencil(unsigned int stencil); INLINE unsigned int get_clear_stencil() const; - INLINE void set_clear_active(int n, bool clear_aux_active); - INLINE bool get_clear_active(int n) const; + virtual void set_clear_active(int n, bool clear_aux_active); + virtual bool get_clear_active(int n) const; - INLINE void set_clear_value(int n, const Colorf &color); - INLINE const Colorf &get_clear_value(int n) const; + virtual void set_clear_value(int n, const Colorf &clear_value); + virtual const Colorf &get_clear_value(int n) const; - INLINE void disable_clears(); + virtual void disable_clears(); + virtual bool is_any_clear_active() const; - INLINE bool is_any_clear_active() const; - - INLINE void set_pixel_zoom(float pixel_zoom); + virtual void set_pixel_zoom(float pixel_zoom); INLINE float get_pixel_zoom() const; INLINE float get_pixel_factor() const; virtual bool supports_pixel_zoom() const; diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 70a6d43bfb..a261c7dc54 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -1244,20 +1244,23 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr, win->change_scenes(dr_reader); gsg->prepare_display_region(dr_reader, dr_reader->get_stereo_channel()); + if (dr_reader->is_any_clear_active()) { + gsg->clear(dr); + } + PT(SceneSetup) scene_setup = setup_scene(gsg, dr_reader); if (scene_setup == (SceneSetup *)NULL) { // Never mind. + } else if (dr_reader->get_object()->is_stereo()) { + // Don't draw stereo DisplayRegions directly. + } else if (!gsg->set_scene(scene_setup)) { // The scene or lens is inappropriate somehow. display_cat.error() << gsg->get_type() << " cannot render scene with specified lens.\n"; } else { - if (dr_reader->is_any_clear_active()) { - gsg->clear(dr); - } - DrawCullHandler cull_handler(gsg); if (gsg->begin_scene()) { delete dr_reader; @@ -1312,7 +1315,7 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { dr_reader = NULL; (*aci).second = dr; cull_to_bins(win, dr, current_thread); - + } else { // We have already culled a scene using this camera in // this thread, and now we're being asked to cull another @@ -1326,7 +1329,7 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { setup_scene(win->get_gsg(), dr_reader), current_thread); } - + if (dr_reader != (DisplayRegionPipelineReader *)NULL) { delete dr_reader; } @@ -1462,9 +1465,7 @@ draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { PT(CullResult) cull_result = dr->get_cull_result(current_thread); PT(SceneSetup) scene_setup = dr->get_scene_setup(current_thread); - if (cull_result != (CullResult *)NULL && scene_setup != (SceneSetup *)NULL) { - do_draw(cull_result, scene_setup, win, dr, current_thread); - } + do_draw(cull_result, scene_setup, win, dr, current_thread); } //////////////////////////////////////////////////////////////////// @@ -1771,62 +1772,33 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup, GraphicsStateGuardian *gsg = win->get_gsg(); win->change_scenes(dr_reader); - if (dr_reader->get_stereo_channel() == Lens::SC_stereo) { - // A special case. For a stereo DisplayRegion, we render the left - // eye, followed by the right eye. - if (dr_reader->is_any_clear_active()) { - gsg->prepare_display_region(dr_reader, Lens::SC_stereo); - gsg->clear(dr_reader->get_object()); - } - gsg->prepare_display_region(dr_reader, Lens::SC_left); + gsg->prepare_display_region(dr_reader, dr_reader->get_stereo_channel()); + if (dr_reader->is_any_clear_active()) { + gsg->clear(dr_reader->get_object()); + } - if (!gsg->set_scene(scene_setup)) { - // The scene or lens is inappropriate somehow. - display_cat.error() - << gsg->get_type() << " cannot render scene with specified lens.\n"; - } else { - if (gsg->begin_scene()) { - delete dr_reader; - dr_reader = NULL; - cull_result->draw(current_thread); - gsg->end_scene(); - dr_reader = new DisplayRegionPipelineReader(dr, current_thread); - } - if (dr_reader->get_clear_depth_between_eyes()) { - DrawableRegion clear_region; - clear_region.set_clear_depth_active(true); - clear_region.set_clear_depth(dr->get_clear_depth()); - gsg->clear(&clear_region); - } - gsg->prepare_display_region(dr_reader, Lens::SC_right); - gsg->set_scene(scene_setup); - if (gsg->begin_scene()) { - delete dr_reader; - dr_reader = NULL; - cull_result->draw(current_thread); - gsg->end_scene(); - } - } + if (cull_result == NULL || scene_setup == NULL) { + // Nothing to see here. + + } else if (dr_reader->get_object()->is_stereo()) { + // We don't actually draw the stereo DisplayRegions. These are + // just placeholders; we draw the individual left and right eyes + // instead. (We might still clear the stereo DisplayRegions, + // though, since it's probably faster to clear right and left + // channels in one pass, than to clear them in two separate + // passes.) + + } else if (!gsg->set_scene(scene_setup)) { + // The scene or lens is inappropriate somehow. + display_cat.error() + << gsg->get_type() << " cannot render scene with specified lens.\n"; } else { - // For a mono DisplayRegion, or a left/right eye only - // DisplayRegion, we just render that. - gsg->prepare_display_region(dr_reader, dr_reader->get_stereo_channel()); - - if (!gsg->set_scene(scene_setup)) { - // The scene or lens is inappropriate somehow. - display_cat.error() - << gsg->get_type() << " cannot render scene with specified lens.\n"; - } else { - if (dr_reader->is_any_clear_active()) { - gsg->clear(dr_reader->get_object()); - } - if (gsg->begin_scene()) { - delete dr_reader; - dr_reader = NULL; - cull_result->draw(current_thread); - gsg->end_scene(); - } + if (gsg->begin_scene()) { + delete dr_reader; + dr_reader = NULL; + cull_result->draw(current_thread); + gsg->end_scene(); } } diff --git a/panda/src/display/graphicsOutput.I b/panda/src/display/graphicsOutput.I index 187829a3e4..92ae7d97ac 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -467,22 +467,45 @@ trigger_copy() { // Access: Published // Description: Creates a new DisplayRegion that covers the entire // window. +// +// If is_stereo() is true for this window, and +// default-stereo-camera is configured true, this +// actually makes a StereoDisplayRegion. Call +// make_mono_display_region() or +// make_stereo_display_region() if you want to insist on +// one or the other. //////////////////////////////////////////////////////////////////// INLINE DisplayRegion *GraphicsOutput:: make_display_region() { - return add_display_region(new DisplayRegion(this)); + return make_display_region(0.0f, 1.0f, 0.0f, 1.0f); } //////////////////////////////////////////////////////////////////// -// Function: GraphicsOutput::make_display_region +// Function: GraphicsOutput::make_mono_display_region // Access: Published -// Description: Creates a new DisplayRegion that covers the indicated -// sub-rectangle within the window. The range on all -// parameters is 0..1. +// Description: Creates a new DisplayRegion that covers the entire +// window. +// +// This always returns a mono DisplayRegion, even if +// is_stereo() is true. //////////////////////////////////////////////////////////////////// INLINE DisplayRegion *GraphicsOutput:: -make_display_region(float l, float r, float b, float t) { - return add_display_region(new DisplayRegion(this, l, r, b, t)); +make_mono_display_region() { + return make_mono_display_region(0.0f, 1.0f, 0.0f, 1.0f); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::make_stereo_display_region +// Access: Published +// Description: Creates a new DisplayRegion that covers the entire +// window. +// +// This always returns a stereo DisplayRegion, even if +// is_stereo() is false. +//////////////////////////////////////////////////////////////////// +INLINE StereoDisplayRegion *GraphicsOutput:: +make_stereo_display_region() { + return make_stereo_display_region(0.0f, 1.0f, 0.0f, 1.0f); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 74e87f1143..e08e37120b 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -121,7 +121,7 @@ GraphicsOutput(GraphicsPipe *pipe, // We start out with one DisplayRegion that covers the whole window, // which we may use internally for full-window operations like // clear() and get_screenshot(). - _default_display_region = make_display_region(0.0f, 1.0f, 0.0f, 1.0f); + _default_display_region = make_mono_display_region(0.0f, 1.0f, 0.0f, 1.0f); _default_display_region->set_active(false); _display_regions_stale = false; @@ -444,6 +444,68 @@ set_sort(int sort) { } } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::make_display_region +// Access: Published +// Description: Creates a new DisplayRegion that covers the indicated +// sub-rectangle within the window. The range on all +// parameters is 0..1. +// +// If is_stereo() is true for this window, and +// default-stereo-camera is configured true, this +// actually makes a StereoDisplayRegion. Call +// make_mono_display_region() or +// make_stereo_display_region() if you want to insist on +// one or the other. +//////////////////////////////////////////////////////////////////// +DisplayRegion *GraphicsOutput:: +make_display_region(float l, float r, float b, float t) { + if (is_stereo() && default_stereo_camera) { + return make_stereo_display_region(l, r, b, t); + } else { + return make_mono_display_region(l, r, b, t); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::make_mono_display_region +// Access: Published +// Description: Creates a new DisplayRegion that covers the indicated +// sub-rectangle within the window. The range on all +// parameters is 0..1. +// +// This always returns a mono DisplayRegion, even if +// is_stereo() is true. +//////////////////////////////////////////////////////////////////// +DisplayRegion *GraphicsOutput:: +make_mono_display_region(float l, float r, float b, float t) { + return add_display_region(new DisplayRegion(this, l, r, b, t)); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::make_stereo_display_region +// Access: Published +// Description: Creates a new DisplayRegion that covers the indicated +// sub-rectangle within the window. The range on all +// parameters is 0..1. +// +// This always returns a stereo DisplayRegion, even if +// is_stereo() is false. +//////////////////////////////////////////////////////////////////// +StereoDisplayRegion *GraphicsOutput:: +make_stereo_display_region(float l, float r, float b, float t) { + PT(DisplayRegion) left = new DisplayRegion(this, l, r, b, t); + PT(DisplayRegion) right = new DisplayRegion(this, l, r, b, t); + + PT(StereoDisplayRegion) stereo = new StereoDisplayRegion(this, l, r, b, t, + left, right); + add_display_region(stereo); + add_display_region(left); + add_display_region(right); + + return stereo; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::remove_display_region // Access: Published @@ -459,22 +521,14 @@ remove_display_region(DisplayRegion *display_region) { nassertr(display_region != _default_display_region, false); - PT(DisplayRegion) drp = display_region; - TotalDisplayRegions::iterator dri = - find(_total_display_regions.begin(), _total_display_regions.end(), drp); - if (dri != _total_display_regions.end()) { - // Let's aggressively clean up the display region too. - display_region->cleanup(); - display_region->_window = NULL; - _total_display_regions.erase(dri); - if (display_region->is_active()) { - _display_regions_stale = true; - } - - return true; + if (display_region->is_stereo()) { + StereoDisplayRegion *sdr; + DCAST_INTO_R(sdr, display_region, false); + do_remove_display_region(sdr->get_left_eye()); + do_remove_display_region(sdr->get_right_eye()); } - return false; + return do_remove_display_region(display_region); } //////////////////////////////////////////////////////////////////// @@ -1031,9 +1085,9 @@ clear(Thread *current_thread) { bool GraphicsOutput:: copy_to_textures() { bool okflag = true; - for (int i=0; icleanup(); + display_region->_window = NULL; + _total_display_regions.erase(dri); + if (display_region->is_active()) { + _display_regions_stale = true; + } + + return true; + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::do_determine_display_regions // Access: Private diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 4559cf7be2..bf7f3e066b 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -19,6 +19,7 @@ #include "graphicsPipe.h" #include "displayRegion.h" +#include "stereoDisplayRegion.h" #include "graphicsStateGuardian.h" #include "drawableRegion.h" #include "renderBuffer.h" @@ -141,8 +142,11 @@ PUBLISHED: INLINE void trigger_copy(); INLINE DisplayRegion *make_display_region(); - INLINE DisplayRegion *make_display_region(float l, float r, - float b, float t); + DisplayRegion *make_display_region(float l, float r, float b, float t); + INLINE DisplayRegion *make_mono_display_region(); + DisplayRegion *make_mono_display_region(float l, float r, float b, float t); + INLINE StereoDisplayRegion *make_stereo_display_region(); + StereoDisplayRegion *make_stereo_display_region(float l, float r, float b, float t); bool remove_display_region(DisplayRegion *display_region); void remove_all_display_regions(); @@ -248,6 +252,7 @@ private: PT(GeomVertexData) create_texture_card_vdata(int x, int y); DisplayRegion *add_display_region(DisplayRegion *display_region); + bool do_remove_display_region(DisplayRegion *display_region); INLINE void win_display_regions_changed(); diff --git a/panda/src/display/stereoDisplayRegion.I b/panda/src/display/stereoDisplayRegion.I new file mode 100644 index 0000000000..323765d9a2 --- /dev/null +++ b/panda/src/display/stereoDisplayRegion.I @@ -0,0 +1,36 @@ +// Filename: stereoDisplayRegion.I +// Created by: drose (19Feb09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::get_left_eye +// Access: Published +// Description: Returns a pointer to the left DisplayRegion managed +// by this stereo object. +//////////////////////////////////////////////////////////////////// +INLINE DisplayRegion *StereoDisplayRegion:: +get_left_eye() { + return _left_eye; +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::get_right_eye +// Access: Published +// Description: Returns a pointer to the right DisplayRegion managed +// by this stereo object. +//////////////////////////////////////////////////////////////////// +INLINE DisplayRegion *StereoDisplayRegion:: +get_right_eye() { + return _right_eye; +} diff --git a/panda/src/display/stereoDisplayRegion.cxx b/panda/src/display/stereoDisplayRegion.cxx new file mode 100644 index 0000000000..aacd367aa2 --- /dev/null +++ b/panda/src/display/stereoDisplayRegion.cxx @@ -0,0 +1,318 @@ +// Filename: stereoDisplayRegion.cxx +// Created by: drose (19Feb09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "stereoDisplayRegion.h" +#include "pandaNode.h" + +TypeHandle StereoDisplayRegion::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +StereoDisplayRegion:: +StereoDisplayRegion(GraphicsOutput *window, + float l, float r, float b, float t, + DisplayRegion *left, DisplayRegion *right) : + DisplayRegion(window, l, r, b, t), + _left_eye(left), + _right_eye(right) +{ + nassertv(window == left->get_window() && + window == right->get_window()); + set_stereo_channel(Lens::SC_stereo); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +StereoDisplayRegion:: +~StereoDisplayRegion() { +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_clear_active +// Access: Published, Virtual +// Description: Sets the clear-active flag for any bitplane. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_clear_active(int n, bool clear_active) { + // The clear_active flag gets set only on the parent, stereo display + // region. + DisplayRegion::set_clear_active(n, clear_active); + + // Except for depth and stencil buffers. These also get set on the + // right display region by default, on the assumption that we want + // to clear these buffers between drawing the eyes, and that the + // right eye is the second of the pair. + switch (n) { + case RTP_stencil: + case RTP_depth_stencil: + case RTP_depth: + _right_eye->set_clear_active(n, clear_active); + break; + + default: + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_clear_value +// Access: Published, Virtual +// Description: Sets the clear value for any bitplane. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_clear_value(int n, const Colorf &clear_value) { + DisplayRegion::set_clear_value(n, clear_value); + _left_eye->set_clear_value(n, clear_value); + _right_eye->set_clear_value(n, clear_value); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::disable_clears +// Access: Published, Virtual +// Description: Disables both the color and depth clear. See +// set_clear_color_active and set_clear_depth_active. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +disable_clears() { + DisplayRegion::disable_clears(); + _left_eye->disable_clears(); + _right_eye->disable_clears(); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_pixel_zoom +// Access: Published, Virtual +// Description: Sets the pixel_zoom for left and right eyes. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_pixel_zoom(float pixel_zoom) { + DisplayRegion::set_pixel_zoom(pixel_zoom); + _left_eye->set_pixel_zoom(pixel_zoom); + _right_eye->set_pixel_zoom(pixel_zoom); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_dimensions +// Access: Published, Virtual +// Description: Sets both the left and right DisplayRegions to the +// indicated dimensions. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_dimensions(float l, float r, float b, float t) { + DisplayRegion::set_dimensions(l, r, b, t); + _left_eye->set_dimensions(l, r, b, t); + _right_eye->set_dimensions(l, r, b, t); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::is_stereo +// Access: Published, Virtual +// Description: Returns true if this is a StereoDisplayRegion, false +// otherwise. +//////////////////////////////////////////////////////////////////// +bool StereoDisplayRegion:: +is_stereo() const { + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_camera +// Access: Published, Virtual +// Description: Sets both the left and right DisplayRegions to the +// indicated camera. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_camera(const NodePath &camera) { + DisplayRegion::set_camera(camera); + _left_eye->set_camera(camera); + _right_eye->set_camera(camera); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_active +// Access: Published, Virtual +// Description: Sets the active flag on both the left and right +// DisplayRegions to the indicated value. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_active(bool active) { + DisplayRegion::set_active(active); + _left_eye->set_active(active); + _right_eye->set_active(active); + if (active) { + // Reenable the appropriate eyes according to our stereo_channel + // setting. + set_stereo_channel(get_stereo_channel()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_sort +// Access: Published, Virtual +// Description: Sets the indicated sort value on the overall +// DisplayRegion, the indicated sort value + 1 on the +// left eye, and the indicated sort value + 2 on the +// right eye. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_sort(int sort) { + DisplayRegion::set_sort(sort); + _left_eye->set_sort(sort + 1); + _right_eye->set_sort(sort + 2); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_stereo_channel +// Access: Published, Virtual +// Description: Sets the stereo channels on the left and right eyes, +// and also sets the active flags independently on both +// eyes. For a StereoDisplayRegion, a different action +// is performed for each different value: +// +// SC_stereo - the left eye is set to SC_left, the right +// eye to SC_right, and both eyes are activated. +// +// SC_left - the left eye is set to SC_left and +// activated; the right eye is deactivated. +// +// SC_right - the right eye is set to SC_right and +// activated; the left eye is deactivated. +// +// SC_mono - the left eye is set to SC_mono and +// activated; the right eye is deactivated. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_stereo_channel(Lens::StereoChannel stereo_channel) { + DisplayRegion::set_stereo_channel(stereo_channel); + if (!is_active()) { + return; + } + + switch (stereo_channel) { + case Lens::SC_stereo: + _left_eye->set_stereo_channel(Lens::SC_left); + _left_eye->set_active(true); + _right_eye->set_stereo_channel(Lens::SC_right); + _right_eye->set_active(true); + break; + + case Lens::SC_left: + _left_eye->set_stereo_channel(Lens::SC_left); + _left_eye->set_active(true); + _right_eye->set_active(false); + break; + + case Lens::SC_right: + _left_eye->set_active(false); + _right_eye->set_stereo_channel(Lens::SC_right); + _right_eye->set_active(true); + break; + + case Lens::SC_mono: + _left_eye->set_stereo_channel(Lens::SC_mono); + _left_eye->set_active(true); + _right_eye->set_active(false); + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_incomplete_render +// Access: Published, Virtual +// Description: Sets the incomplete_render flag on both the left and +// right DisplayRegions to the indicated value. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_incomplete_render(bool incomplete_render) { + DisplayRegion::set_incomplete_render(incomplete_render); + _left_eye->set_incomplete_render(incomplete_render); + _right_eye->set_incomplete_render(incomplete_render); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_texture_reload_priority +// Access: Published, Virtual +// Description: Sets the texture_reload_priority on both the left and +// right DisplayRegions to the indicated value. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_texture_reload_priority(int texture_reload_priority) { + DisplayRegion::set_texture_reload_priority(texture_reload_priority); + _left_eye->set_texture_reload_priority(texture_reload_priority); + _right_eye->set_texture_reload_priority(texture_reload_priority); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_cull_traverser +// Access: Published, Virtual +// Description: Sets the CullTraverser for both the left and right +// DisplayRegions. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_cull_traverser(CullTraverser *trav) { + DisplayRegion::set_cull_traverser(trav); + _left_eye->set_cull_traverser(trav); + _right_eye->set_cull_traverser(trav); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::set_cube_map_index +// Access: Published, Virtual +// Description: Sets the cube_map_index on both the left and +// right DisplayRegions to the indicated value. +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +set_cube_map_index(int cube_map_index) { + DisplayRegion::set_cube_map_index(cube_map_index); + _left_eye->set_cube_map_index(cube_map_index); + _right_eye->set_cube_map_index(cube_map_index); +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::output +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void StereoDisplayRegion:: +output(ostream &out) const { + out << "StereoDisplayRegion(" << *_left_eye << ")"; +} + +//////////////////////////////////////////////////////////////////// +// Function: StereoDisplayRegion::make_cull_result_graph +// Access: Published, Virtual +// Description: Returns a special scene graph constructed to +// represent the results of the last frame's cull +// operation. +//////////////////////////////////////////////////////////////////// +PT(PandaNode) StereoDisplayRegion:: +make_cull_result_graph() { + PT(PandaNode) root = new PandaNode("stereo"); + + PT(PandaNode) left = _left_eye->make_cull_result_graph(); + left->set_name("left"); + root->add_child(left, _left_eye->get_sort()); + + PT(PandaNode) right = _right_eye->make_cull_result_graph(); + right->set_name("right"); + root->add_child(right, _right_eye->get_sort()); + + return root; +} diff --git a/panda/src/display/stereoDisplayRegion.h b/panda/src/display/stereoDisplayRegion.h new file mode 100644 index 0000000000..4967ecf4e4 --- /dev/null +++ b/panda/src/display/stereoDisplayRegion.h @@ -0,0 +1,98 @@ +// Filename: stereoDisplayRegion.h +// Created by: drose (19Feb09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef STEREODISPLAYREGION_H +#define STEREODISPLAYREGION_H + +#include "pandabase.h" + +#include "displayRegion.h" + +//////////////////////////////////////////////////////////////////// +// Class : StereoDisplayRegion +// Description : This is a special DisplayRegion wrapper that actually +// includes a pair of DisplayRegions internally: the +// left and right eyes. The DisplayRegion represented +// here does not have a physical association with the +// window, but it pretends it does. Instead, it +// maintains a pointer to the left and right +// DisplayRegions separately. +// +// Operations on the StereoDisplayRegion object affect +// both left and right eyes together. To access the +// left or right eyes independently, use get_left_eye() +// and get_right_eye(). +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA_DISPLAY StereoDisplayRegion : public DisplayRegion { +protected: + StereoDisplayRegion(GraphicsOutput *window, + float l, float r, float b, float t, + DisplayRegion *left, DisplayRegion *right); + +public: + virtual ~StereoDisplayRegion(); + +PUBLISHED: + // Inherited from DrawableRegion + virtual void set_clear_active(int n, bool clear_aux_active); + virtual void set_clear_value(int n, const Colorf &clear_value); + virtual void disable_clears(); + virtual void set_pixel_zoom(float pixel_zoom); + + // Inherited from DisplayRegion + virtual void set_dimensions(float l, float r, float b, float t); + virtual bool is_stereo() const; + virtual void set_camera(const NodePath &camera); + virtual void set_active(bool active); + virtual void set_sort(int sort); + virtual void set_stereo_channel(Lens::StereoChannel stereo_channel); + virtual void set_incomplete_render(bool incomplete_render); + virtual void set_texture_reload_priority(int texture_reload_priority); + virtual void set_cull_traverser(CullTraverser *trav); + virtual void set_cube_map_index(int cube_map_index); + + virtual void output(ostream &out) const; + virtual PT(PandaNode) make_cull_result_graph(); + + INLINE DisplayRegion *get_left_eye(); + INLINE DisplayRegion *get_right_eye(); + +private: + PT(DisplayRegion) _left_eye; + PT(DisplayRegion) _right_eye; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + DisplayRegion::init_type(); + register_type(_type_handle, "StereoDisplayRegion", + DisplayRegion::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + + friend class GraphicsOutput; + friend class DisplayRegionPipelineReader; +}; + +#include "stereoDisplayRegion.I" + +#endif diff --git a/panda/src/framework/config_framework.cxx b/panda/src/framework/config_framework.cxx index b3c5b8d2d2..22a9ca888f 100644 --- a/panda/src/framework/config_framework.cxx +++ b/panda/src/framework/config_framework.cxx @@ -30,8 +30,6 @@ ConfigVariableDouble aspect_ratio ("aspect-ratio", 0.0); ConfigVariableBool show_frame_rate_meter ("show-frame-rate-meter", false); -ConfigVariableBool default_stereo_camera -("default-stereo-camera", true); ConfigVariableString record_session ("record-session", ""); diff --git a/panda/src/framework/config_framework.h b/panda/src/framework/config_framework.h index 2c29a31aa2..ebff70dd95 100644 --- a/panda/src/framework/config_framework.h +++ b/panda/src/framework/config_framework.h @@ -27,7 +27,6 @@ NotifyCategoryDecl(framework, EXPCL_FRAMEWORK, EXPTP_FRAMEWORK); // Configure variables for framework package. extern ConfigVariableDouble aspect_ratio; extern ConfigVariableBool show_frame_rate_meter; -extern ConfigVariableBool default_stereo_camera; extern ConfigVariableString record_session; extern ConfigVariableString playback_session; diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index 902b37a7ac..ae27abbafe 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -180,11 +180,6 @@ open_window(const WindowProperties &props, GraphicsEngine *engine, NodePath camera_np = make_camera(); _display_region_3d->set_camera(camera_np); - if (_window->is_stereo() && default_stereo_camera) { - // Actually, let's make a stereo DisplayRegion. - _display_region_3d->set_stereo_channel(Lens::SC_stereo); - } - set_background_type(_background_type); if (show_frame_rate_meter) { @@ -286,7 +281,7 @@ get_render_2d() { // display region. float l, r, b, t; _display_region_3d->get_dimensions(l, r, b, t); - _display_region_2d = _window->make_display_region(l, r, b, t); + _display_region_2d = _window->make_mono_display_region(l, r, b, t); _display_region_2d->set_sort(10); // Finally, we need a camera to associate with the display region. diff --git a/panda/src/grutil/frameRateMeter.cxx b/panda/src/grutil/frameRateMeter.cxx index ae9ec7790f..bc2409747a 100644 --- a/panda/src/grutil/frameRateMeter.cxx +++ b/panda/src/grutil/frameRateMeter.cxx @@ -88,7 +88,7 @@ setup_window(GraphicsOutput *window) { _root.set_two_sided(1, 1); // Create a display region that covers the entire window. - _display_region = _window->make_display_region(); + _display_region = _window->make_mono_display_region(); _display_region->set_sort(frame_rate_meter_layer_sort); // Finally, we need a camera to associate with the display region. diff --git a/panda/src/gsgbase/Sources.pp b/panda/src/gsgbase/Sources.pp index 505676a792..e9772a9336 100644 --- a/panda/src/gsgbase/Sources.pp +++ b/panda/src/gsgbase/Sources.pp @@ -9,12 +9,17 @@ #define COMBINED_SOURCES $[TARGET]_composite1.cxx #define SOURCES \ - config_gsgbase.h graphicsStateGuardianBase.h + config_gsgbase.h \ + displayRegionBase.I displayRegionBase.h \ + graphicsStateGuardianBase.h #define INCLUDED_SOURCES \ - config_gsgbase.cxx graphicsStateGuardianBase.cxx + config_gsgbase.cxx \ + displayRegionBase.cxx \ + graphicsStateGuardianBase.cxx #define INSTALL_HEADERS \ + displayRegionBase.I displayRegionBase.h \ graphicsStateGuardianBase.h #define IGATESCAN all diff --git a/panda/src/gsgbase/config_gsgbase.cxx b/panda/src/gsgbase/config_gsgbase.cxx index ae66daddc2..5ea6f4159f 100644 --- a/panda/src/gsgbase/config_gsgbase.cxx +++ b/panda/src/gsgbase/config_gsgbase.cxx @@ -13,6 +13,7 @@ //////////////////////////////////////////////////////////////////// #include "config_gsgbase.h" +#include "displayRegionBase.h" #include "graphicsStateGuardianBase.h" #include "dconfig.h" @@ -20,5 +21,6 @@ Configure(config_gsgbase); ConfigureFn(config_gsgbase) { + DisplayRegionBase::init_type(); GraphicsStateGuardianBase::init_type(); } diff --git a/panda/src/gsgbase/displayRegionBase.I b/panda/src/gsgbase/displayRegionBase.I new file mode 100644 index 0000000000..9b3746fb8e --- /dev/null +++ b/panda/src/gsgbase/displayRegionBase.I @@ -0,0 +1,29 @@ +// Filename: displayRegionBase.I +// Created by: drose (20Feb09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionBase::Constructor +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE DisplayRegionBase:: +DisplayRegionBase() { +} + +INLINE ostream & +operator << (ostream &out, const DisplayRegionBase &dr) { + dr.output(out); + return out; +} diff --git a/panda/src/gsgbase/displayRegionBase.cxx b/panda/src/gsgbase/displayRegionBase.cxx new file mode 100644 index 0000000000..287c8b3328 --- /dev/null +++ b/panda/src/gsgbase/displayRegionBase.cxx @@ -0,0 +1,27 @@ +// Filename: displayRegionBase.cxx +// Created by: drose (20Feb09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "displayRegionBase.h" + +TypeHandle DisplayRegionBase::_type_handle; + + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionBase::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +DisplayRegionBase:: +~DisplayRegionBase() { +} diff --git a/panda/src/gsgbase/displayRegionBase.h b/panda/src/gsgbase/displayRegionBase.h new file mode 100644 index 0000000000..1b7f1fab52 --- /dev/null +++ b/panda/src/gsgbase/displayRegionBase.h @@ -0,0 +1,59 @@ +// Filename: displayRegionBase.h +// Created by: drose (20Feb09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef DISPLAYREGIONBASE_H +#define DISPLAYREGIONBASE_H + +#include "pandabase.h" + +#include "typedReferenceCount.h" + +//////////////////////////////////////////////////////////////////// +// Class : DisplayRegionBase +// Description : An abstract base class for DisplayRegion, mainly so +// we can store DisplayRegion pointers in a Camera. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA_GSGBASE DisplayRegionBase : public TypedReferenceCount { +protected: + INLINE DisplayRegionBase(); + +public: + virtual ~DisplayRegionBase(); + +PUBLISHED: + virtual void output(ostream &out) const=0; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + TypedReferenceCount::init_type(); + register_type(_type_handle, "DisplayRegionBase", + TypedReferenceCount::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +INLINE ostream &operator << (ostream &out, const DisplayRegionBase &dr); + +#include "displayRegionBase.I" + +#endif diff --git a/panda/src/gsgbase/gsgbase_composite1.cxx b/panda/src/gsgbase/gsgbase_composite1.cxx index 1c65428490..3b47c01195 100644 --- a/panda/src/gsgbase/gsgbase_composite1.cxx +++ b/panda/src/gsgbase/gsgbase_composite1.cxx @@ -1,4 +1,5 @@ -#include"config_gsgbase.cxx" -#include"graphicsStateGuardianBase.cxx" +#include "config_gsgbase.cxx" +#include "displayRegionBase.cxx" +#include "graphicsStateGuardianBase.cxx" diff --git a/panda/src/pgraph/camera.I b/panda/src/pgraph/camera.I index d3102c6af9..5c33ea6fc7 100644 --- a/panda/src/pgraph/camera.I +++ b/panda/src/pgraph/camera.I @@ -82,9 +82,9 @@ get_num_display_regions() const { // Description: Returns the nth display region associated with the // camera. //////////////////////////////////////////////////////////////////// -INLINE DisplayRegion *Camera:: +INLINE DisplayRegionBase *Camera:: get_display_region(int n) const { - nassertr(n >= 0 && n < (int)_display_regions.size(), (DisplayRegion *)NULL); + nassertr(n >= 0 && n < (int)_display_regions.size(), (DisplayRegionBase *)NULL); return _display_regions[n]; } diff --git a/panda/src/pgraph/camera.cxx b/panda/src/pgraph/camera.cxx index df1bb2aa31..3819f7f821 100644 --- a/panda/src/pgraph/camera.cxx +++ b/panda/src/pgraph/camera.cxx @@ -273,7 +273,7 @@ cleanup_aux_scene_data(Thread *current_thread) { // intended to be called from the DisplayRegion. //////////////////////////////////////////////////////////////////// void Camera:: -add_display_region(DisplayRegion *display_region) { +add_display_region(DisplayRegionBase *display_region) { _display_regions.push_back(display_region); } @@ -285,7 +285,7 @@ add_display_region(DisplayRegion *display_region) { // intended to be called from the DisplayRegion. //////////////////////////////////////////////////////////////////// void Camera:: -remove_display_region(DisplayRegion *display_region) { +remove_display_region(DisplayRegionBase *display_region) { DisplayRegions::iterator dri = find(_display_regions.begin(), _display_regions.end(), display_region); if (dri != _display_regions.end()) { diff --git a/panda/src/pgraph/camera.h b/panda/src/pgraph/camera.h index 0b4499c756..36bb0fb853 100644 --- a/panda/src/pgraph/camera.h +++ b/panda/src/pgraph/camera.h @@ -25,8 +25,7 @@ #include "pointerTo.h" #include "pmap.h" #include "auxSceneData.h" - -class DisplayRegion; +#include "displayRegionBase.h" //////////////////////////////////////////////////////////////////// // Class : Camera @@ -54,7 +53,7 @@ PUBLISHED: INLINE const NodePath &get_scene() const; INLINE int get_num_display_regions() const; - INLINE DisplayRegion *get_display_region(int n) const; + INLINE DisplayRegionBase *get_display_region(int n) const; MAKE_SEQ(get_display_regions, get_num_display_regions, get_display_region); INLINE void set_camera_mask(DrawMask mask); @@ -84,8 +83,8 @@ PUBLISHED: int cleanup_aux_scene_data(Thread *current_thread = Thread::get_current_thread()); private: - void add_display_region(DisplayRegion *display_region); - void remove_display_region(DisplayRegion *display_region); + void add_display_region(DisplayRegionBase *display_region); + void remove_display_region(DisplayRegionBase *display_region); bool _active; NodePath _scene; @@ -94,7 +93,7 @@ private: DrawMask _camera_mask; - typedef pvector DisplayRegions; + typedef pvector DisplayRegions; DisplayRegions _display_regions; CPT(RenderState) _initial_state;