From 47c2e41c75692e8af378e9fd6eecf97c8d19078d Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 17 Feb 2006 19:17:06 +0000 Subject: [PATCH] support stereo DisplayRegions --- direct/src/showbase/ShowBase.py | 15 +-- panda/src/display/Sources.pp | 7 +- panda/src/display/displayRegion.I | 31 +++++++ panda/src/display/displayRegion.cxx | 11 ++- panda/src/display/displayRegion.h | 4 + panda/src/display/displayRegionStack.I | 61 ------------- panda/src/display/displayRegionStack.h | 51 ----------- panda/src/display/graphicsEngine.cxx | 91 +++++++++++-------- panda/src/display/graphicsEngine.h | 2 - panda/src/display/graphicsOutput.cxx | 3 +- panda/src/display/graphicsStateGuardian.I | 77 +++------------- panda/src/display/graphicsStateGuardian.cxx | 60 +++++++----- panda/src/display/graphicsStateGuardian.h | 17 +--- panda/src/display/lensStack.I | 61 ------------- panda/src/display/lensStack.h | 50 ---------- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 66 ++++++-------- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 4 +- panda/src/framework/windowFramework.cxx | 39 +------- panda/src/framework/windowFramework.h | 1 - .../glstuff/glGraphicsStateGuardian_src.cxx | 46 ++++------ .../src/glstuff/glGraphicsStateGuardian_src.h | 6 +- panda/src/gobj/lens.cxx | 6 +- panda/src/gobj/lens.h | 11 ++- 23 files changed, 221 insertions(+), 499 deletions(-) delete mode 100644 panda/src/display/displayRegionStack.I delete mode 100644 panda/src/display/displayRegionStack.h delete mode 100644 panda/src/display/lensStack.I delete mode 100644 panda/src/display/lensStack.h diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index a0528802df..23e711e6c2 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -807,19 +807,8 @@ class ShowBase(DirectObject.DirectObject): if stereo == None: stereo = (win.isStereo() and self.config.GetBool('default-stereo-camera', 1)) if stereo: - # A stereo camera! The first DisplayRegion becomes the - # left channel. - dr.setStereoChannel(Lens.SCLeft) - - # So we'll need another DisplayRegion for the right channel. - dr = win.makeDisplayRegion(*displayRegion) - dr.setSort(sort) - dr.setClearDepthActive(1) - if clearColor: - dr.setClearColorActive(1) - dr.setClearColor(clearColor) - dr.setCamera(cam) - dr.setStereoChannel(Lens.SCRight) + # A stereo camera! + dr.setStereoChannel(Lens.SCStereo) return cam diff --git a/panda/src/display/Sources.pp b/panda/src/display/Sources.pp index 3e95d6a23e..79bf6c0eb8 100644 --- a/panda/src/display/Sources.pp +++ b/panda/src/display/Sources.pp @@ -15,8 +15,6 @@ config_display.h \ drawableRegion.I drawableRegion.h \ displayRegion.I displayRegion.h \ - displayRegionStack.I \ - displayRegionStack.h \ frameBufferProperties.I frameBufferProperties.h \ graphicsEngine.I graphicsEngine.h \ graphicsOutput.I graphicsOutput.h \ @@ -32,7 +30,6 @@ graphicsDevice.h graphicsDevice.I \ parasiteBuffer.I parasiteBuffer.h \ windowProperties.I windowProperties.h \ - lensStack.I lensStack.h \ lru.h #define INCLUDED_SOURCES \ @@ -58,8 +55,7 @@ standardMunger.I standardMunger.h \ config_display.h \ drawableRegion.I drawableRegion.h \ - displayRegion.I displayRegion.h displayRegionStack.I \ - displayRegionStack.h \ + displayRegion.I displayRegion.h \ frameBufferProperties.I frameBufferProperties.h \ graphicsEngine.I graphicsEngine.h \ graphicsOutput.I graphicsOutput.h \ @@ -74,7 +70,6 @@ graphicsDevice.I graphicsDevice.h \ parasiteBuffer.I parasiteBuffer.h \ windowProperties.I windowProperties.h \ - lensStack.I lensStack.h \ renderBuffer.h #define IGATESCAN all diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index cd7931fcea..67cd071b70 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -66,6 +66,37 @@ 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_cube_map_index // Access: Published diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index ad6eec08df..05a3d82dcb 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -33,7 +33,8 @@ TypeHandle DisplayRegion::_type_handle; //////////////////////////////////////////////////////////////////// DisplayRegion:: DisplayRegion(GraphicsOutput *window) : - _window(window) + _window(window), + _clear_depth_between_eyes(true) { _draw_buffer_type = window->get_draw_buffer_type(); compute_pixels_all_stages(); @@ -46,7 +47,8 @@ DisplayRegion(GraphicsOutput *window) : //////////////////////////////////////////////////////////////////// DisplayRegion:: DisplayRegion(GraphicsOutput *window, float l, float r, float b, float t) : - _window(window) + _window(window), + _clear_depth_between_eyes(true) { _draw_buffer_type = window->get_draw_buffer_type(); set_dimensions(l, r, b, t); @@ -356,7 +358,8 @@ set_stereo_channel(Lens::StereoChannel stereo_channel) { cdata->_draw_buffer_mask = ~(RenderBuffer::T_front_left | RenderBuffer::T_back_left); break; - case Lens::SC_both: + case Lens::SC_mono: + case Lens::SC_stereo: cdata->_draw_buffer_mask = ~0; break; } @@ -759,7 +762,7 @@ CData() : _camera_node((Camera *)NULL), _active(true), _sort(0), - _stereo_channel(Lens::SC_both), + _stereo_channel(Lens::SC_mono), _draw_buffer_mask(~0), _cube_map_index(-1) { diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 84f4562242..5556906f3b 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -92,6 +92,9 @@ PUBLISHED: 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_cube_map_index(int cube_map_index); INLINE int get_cube_map_index() const; @@ -130,6 +133,7 @@ private: // The associated window is a permanent property of the // DisplayRegion. It doesn't need to be cycled. GraphicsOutput *_window; + bool _clear_depth_between_eyes; // This is the data that is associated with the DisplayRegion that // needs to be cycled every frame, but represents the parameters as diff --git a/panda/src/display/displayRegionStack.I b/panda/src/display/displayRegionStack.I deleted file mode 100644 index b6a163e227..0000000000 --- a/panda/src/display/displayRegionStack.I +++ /dev/null @@ -1,61 +0,0 @@ -// Filename: displayRegionStack.I -// Created by: drose (06Oct99) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - - - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegionStack::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE DisplayRegionStack:: -DisplayRegionStack() { - _stack_level = -1; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegionStack::Destructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE DisplayRegionStack:: -~DisplayRegionStack() { -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegionStack::Copy Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE DisplayRegionStack:: -DisplayRegionStack(const DisplayRegionStack ©) : - _display_region(copy._display_region), - _stack_level(copy._stack_level) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegionStack::Copy Operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegionStack:: -operator =(const DisplayRegionStack ©) { - _display_region = copy._display_region; - _stack_level = copy._stack_level; -} diff --git a/panda/src/display/displayRegionStack.h b/panda/src/display/displayRegionStack.h deleted file mode 100644 index 2db736bc0e..0000000000 --- a/panda/src/display/displayRegionStack.h +++ /dev/null @@ -1,51 +0,0 @@ -// Filename: displayRegionStack.h -// Created by: drose (06Oct99) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -#ifndef DISPLAYREGIONSTACK_H -#define DISPLAYREGIONSTACK_H - -#include "pandabase.h" - -#include "displayRegion.h" - -class GraphicsStateGuardian; - -//////////////////////////////////////////////////////////////////// -// Class : DisplayRegionStack -// Description : An instance of this kind of object is returned by -// GraphicsStateGuardian::push_display_region(). It -// holds the information needed to restore the previous -// display region in the subsequent matching call to -// pop_display_region(). -//////////////////////////////////////////////////////////////////// -class DisplayRegionStack { -public: - INLINE DisplayRegionStack(); - INLINE ~DisplayRegionStack(); - INLINE DisplayRegionStack(const DisplayRegionStack ©); - INLINE void operator =(const DisplayRegionStack ©); - -private: - CPT(DisplayRegion) _display_region; - int _stack_level; - friend class GraphicsStateGuardian; -}; - -#include "displayRegionStack.I" - -#endif diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 72f285b67a..ef7cf9b822 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -809,11 +809,16 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr) { GraphicsStateGuardian *gsg = win->get_gsg(); nassertv(gsg != (GraphicsStateGuardian *)NULL); + win->change_scenes(dr); + gsg->prepare_display_region(dr, dr->get_stereo_channel()); + PT(SceneSetup) scene_setup = setup_scene(gsg, dr); - if (setup_gsg(gsg, scene_setup)) { - win->change_scenes(dr); - DisplayRegionStack old_dr = gsg->push_display_region(dr); - gsg->prepare_display_region(); + 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->is_any_clear_active()) { gsg->clear(dr); } @@ -823,8 +828,6 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr) { do_cull(&cull_handler, scene_setup, gsg); gsg->end_scene(); } - - gsg->pop_display_region(old_dr); } } @@ -1243,43 +1246,59 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup, PStatTimer timer(_draw_pcollector); GraphicsStateGuardian *gsg = win->get_gsg(); - if (setup_gsg(gsg, scene_setup)) { - win->change_scenes(dr); - DisplayRegionStack old_dr = gsg->push_display_region(dr); - gsg->prepare_display_region(); + win->change_scenes(dr); + + if (dr->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->is_any_clear_active()) { + gsg->prepare_display_region(dr, Lens::SC_stereo); gsg->clear(dr); } - if (gsg->begin_scene()) { - cull_result->draw(); - gsg->end_scene(); + gsg->prepare_display_region(dr, Lens::SC_left); + + 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()) { + cull_result->draw(); + gsg->end_scene(); + } + if (dr->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, Lens::SC_right); + gsg->set_scene(scene_setup); + if (gsg->begin_scene()) { + cull_result->draw(); + gsg->end_scene(); + } } - gsg->pop_display_region(old_dr); - } -} -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::setup_gsg -// Access: Private -// Description: Sets up the GSG to draw the indicated scene. Returns -// true if the scene (and its lens) is acceptable, false -// otherwise. -//////////////////////////////////////////////////////////////////// -bool GraphicsEngine:: -setup_gsg(GraphicsStateGuardian *gsg, SceneSetup *scene_setup) { - if (scene_setup == (SceneSetup *)NULL) { - // No scene, no draw. - return false; - } + } else { + // For a mono DisplayRegion, or a left/right eye only + // DisplayRegion, we just render that. + gsg->prepare_display_region(dr, dr->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"; - return false; + 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->is_any_clear_active()) { + gsg->clear(dr); + } + if (gsg->begin_scene()) { + cull_result->draw(); + gsg->end_scene(); + } + } } - - return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index d04d072ac3..c687fe8a59 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -160,8 +160,6 @@ private: void do_draw(CullResult *cull_result, SceneSetup *scene_setup, GraphicsOutput *win, DisplayRegion *dr); - bool setup_gsg(GraphicsStateGuardian *gsg, SceneSetup *scene_setup); - void do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg, const GraphicsThreadingModel &threading_model); void do_remove_window(GraphicsOutput *window); diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 14da1c5d9a..e1325121cf 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -1033,9 +1033,8 @@ clear() { nassertv(_gsg != (GraphicsStateGuardian *)NULL); - DisplayRegionStack old_dr = _gsg->push_display_region(_default_display_region); + _gsg->prepare_display_region(_default_display_region, Lens::SC_mono); _gsg->clear(this); - _gsg->pop_display_region(old_dr); } } diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index dd426194b7..fbbf760cc1 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -569,24 +569,6 @@ get_scene() const { return _scene_setup; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::clear -// Access: Public -// Description: Clears the framebuffer within the indicated -// DisplayRegion, according to the flags indicated by -// the DisplayRegion object (inheriting from -// DrawableRegion). Note that by default, a -// DisplayRegion does not have any clear flags set, in -// which case this function will do nothing. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsStateGuardian:: -clear(DisplayRegion *dr) { - DisplayRegionStack old_dr = push_display_region(dr); - prepare_display_region(); - clear((DrawableRegion *)dr); - pop_display_region(old_dr); -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::reset_if_new // Access: Public @@ -632,16 +614,24 @@ get_transform() { // Function: GraphicsStateGuardian::get_current_display_region // Access: Public // Description: Returns the current display region being rendered to, -// as set by the last call to push_display_region() (or -// restored by pop_display_region()). This display -// region will be made active (if it is not already) by -// a call to prepare_display_region(). +// as set by the last call to prepare_display_region(). //////////////////////////////////////////////////////////////////// INLINE const DisplayRegion *GraphicsStateGuardian:: get_current_display_region() const { return _current_display_region; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_current_stereo_channel +// Access: Public +// Description: Returns the current stereo channel being rendered to, +// as set by the last call to prepare_display_region(). +//////////////////////////////////////////////////////////////////// +INLINE Lens::StereoChannel GraphicsStateGuardian:: +get_current_stereo_channel() const { + return _current_stereo_channel; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_current_lens // Access: Public @@ -654,49 +644,6 @@ get_current_lens() const { return _current_lens; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::push_display_region -// Access: Public -// Description: Saves the current display region information and sets -// up a new display region for rendering. The return -// value from this function must eventually be passed to -// a matching pop_display_region() call. -// -// The new display region will not actually be made -// active for rendering until the next call to -// prepare_display_region(). This is a state-changing -// optimization. -//////////////////////////////////////////////////////////////////// -INLINE DisplayRegionStack GraphicsStateGuardian:: -push_display_region(const DisplayRegion *dr) { - DisplayRegionStack old; - old._display_region = _current_display_region; - old._stack_level = _display_region_stack_level; - _display_region_stack_level++; - _current_display_region = dr; - return old; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::pop_display_region -// Access: Public -// Description: Restores the display region previously in effect, -// before the matching call to push_display_region(). -// -// The newly-restored display region will not actually -// be made active for rendering until the next call to -// prepare_display_region(). This is a state-changing -// optimization. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsStateGuardian:: -pop_display_region(DisplayRegionStack &node) { - nassertv(_display_region_stack_level > 0); - _display_region_stack_level--; - nassertv(node._stack_level == _display_region_stack_level); - _current_display_region = node._display_region; - node._stack_level = -1; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_cs_transform // Access: Public diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 98f25022cb..0f7f9d56bb 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -101,6 +101,7 @@ GraphicsStateGuardian(const FrameBufferProperties &properties, set_coordinate_system(get_default_coordinate_system()); _current_display_region = (DisplayRegion*)0L; + _current_stereo_channel = Lens::SC_mono; _current_lens = (Lens *)NULL; _needs_reset = true; _is_valid = false; @@ -270,10 +271,6 @@ reset() { _needs_reset = false; _is_valid = false; - _display_region_stack_level = 0; - _frame_buffer_stack_level = 0; - _lens_stack_level = 0; - _state_rs = NULL; _target_rs = NULL; _state.clear_to_zero(); @@ -363,22 +360,8 @@ set_scene(SceneSetup *scene_setup) { if (_current_lens == (Lens *)NULL) { return false; } - DisplayRegion *dr = scene_setup->get_display_region(); - Lens::StereoChannel stereo_channel = dr->get_stereo_channel(); - switch (stereo_channel) { - case Lens::SC_left: - _color_write_mask = dr->get_window()->get_left_eye_color_mask(); - break; - case Lens::SC_right: - _color_write_mask = dr->get_window()->get_right_eye_color_mask(); - break; - - case Lens::SC_both: - _color_write_mask = ColorWriteAttrib::C_all; - } - - return prepare_lens(stereo_channel); + return prepare_lens(); } //////////////////////////////////////////////////////////////////// @@ -627,6 +610,10 @@ set_depth_clear_value(const float value) { // Description: Clears the framebuffer within the current // DisplayRegion, according to the flags indicated by // the given DrawableRegion object. +// +// This does not set the DisplayRegion first. You +// should call prepare_display_region() to specify the +// region you wish the clear operation to apply to. //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: clear(DrawableRegion *clearable) { @@ -643,11 +630,42 @@ clear(DrawableRegion *clearable) { } if (clear_buffer_type != 0) { - prepare_display_region(); do_clear(get_render_buffer(clear_buffer_type)); } } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::prepare_display_region +// Access: Public, Virtual +// Description: Makes the specified DisplayRegion current. All +// future drawing and clear operations will be +// constrained within the given DisplayRegion. +// +// The stereo_channel parameter further qualifies the +// channel that is to be rendered into, in the case of a +// stereo display region. Normally, in the monocular +// case, it is Lens::SC_mono. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { + _current_display_region = dr; + _current_stereo_channel = stereo_channel; + + switch (stereo_channel) { + case Lens::SC_left: + _color_write_mask = dr->get_window()->get_left_eye_color_mask(); + break; + + case Lens::SC_right: + _color_write_mask = dr->get_window()->get_right_eye_color_mask(); + break; + + case Lens::SC_mono: + case Lens::SC_stereo: + _color_write_mask = ColorWriteAttrib::C_all; + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::prepare_lens // Access: Public, Virtual @@ -661,7 +679,7 @@ clear(DrawableRegion *clearable) { // false if it is not. //////////////////////////////////////////////////////////////////// bool GraphicsStateGuardian:: -prepare_lens(Lens::StereoChannel stereo_channel) { +prepare_lens() { return false; } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index d76a74cb02..86431439cf 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -22,8 +22,6 @@ #include "pandabase.h" #include "frameBufferProperties.h" -#include "displayRegionStack.h" -#include "lensStack.h" #include "preparedGraphicsObjects.h" #include "lens.h" #include "graphicsStateGuardianBase.h" @@ -158,10 +156,10 @@ public: virtual void do_clear(const RenderBuffer &buffer)=0; void clear(DrawableRegion *clearable); - INLINE void clear(DisplayRegion *dr); - virtual void prepare_display_region()=0; - virtual bool prepare_lens(Lens::StereoChannel stereo_channel); + virtual void prepare_display_region(DisplayRegion *dr, + Lens::StereoChannel stereo_channel); + virtual bool prepare_lens(); virtual bool begin_frame(); virtual bool begin_scene(); @@ -194,11 +192,9 @@ public: RenderBuffer get_render_buffer(int buffer_type); INLINE const DisplayRegion *get_current_display_region() const; + INLINE Lens::StereoChannel get_current_stereo_channel() const; INLINE const Lens *get_current_lens() const; - INLINE DisplayRegionStack push_display_region(const DisplayRegion *dr); - INLINE void pop_display_region(DisplayRegionStack &node); - INLINE const TransformState *get_cs_transform() const; INLINE const TransformState *get_inv_cs_transform() const; @@ -287,11 +283,8 @@ protected: bool _stencil_clear_value; Colorf _accum_clear_value; - int _display_region_stack_level; - int _frame_buffer_stack_level; - int _lens_stack_level; - CPT(DisplayRegion) _current_display_region; + Lens::StereoChannel _current_stereo_channel; CPT(Lens) _current_lens; CoordinateSystem _coordinate_system; diff --git a/panda/src/display/lensStack.I b/panda/src/display/lensStack.I deleted file mode 100644 index 9e6e9fec25..0000000000 --- a/panda/src/display/lensStack.I +++ /dev/null @@ -1,61 +0,0 @@ -// Filename: lensStack.I -// Created by: drose (25Feb02) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - - - -//////////////////////////////////////////////////////////////////// -// Function: LensStack::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE LensStack:: -LensStack() { - _stack_level = -1; -} - -//////////////////////////////////////////////////////////////////// -// Function: LensStack::Destructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE LensStack:: -~LensStack() { -} - -//////////////////////////////////////////////////////////////////// -// Function: LensStack::Copy Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE LensStack:: -LensStack(const LensStack ©) : - _lens(copy._lens), - _stack_level(copy._stack_level) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: LensStack::Copy Operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void LensStack:: -operator =(const LensStack ©) { - _lens = copy._lens; - _stack_level = copy._stack_level; -} diff --git a/panda/src/display/lensStack.h b/panda/src/display/lensStack.h deleted file mode 100644 index 08dee42139..0000000000 --- a/panda/src/display/lensStack.h +++ /dev/null @@ -1,50 +0,0 @@ -// Filename: lensStack.h -// Created by: drose (25Feb02) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved -// -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -#ifndef LENSSTACK_H -#define LENSSTACK_H - -#include "pandabase.h" - -#include "lens.h" - -class GraphicsStateGuardian; - -//////////////////////////////////////////////////////////////////// -// Class : LensStack -// Description : An instance of this kind of object is returned by -// GraphicsStateGuardian::push_lens(). It holds the -// information needed to restore the previous display -// region in the subsequent matching call to pop_lens(). -//////////////////////////////////////////////////////////////////// -class LensStack { -public: - INLINE LensStack(); - INLINE ~LensStack(); - INLINE LensStack(const LensStack ©); - INLINE void operator =(const LensStack ©); - -private: - CPT(Lens) _lens; - int _stack_level; - friend class GraphicsStateGuardian; -}; - -#include "lensStack.I" - -#endif diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 59ad17a019..70bb2fec39 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -768,49 +768,43 @@ do_clear(const RenderBuffer &buffer) { // scissor region and viewport) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: -prepare_display_region() { +prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { + nassertv(dr != (DisplayRegion *)NULL); + GraphicsStateGuardian::prepare_display_region(dr, stereo_channel); // DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::PRE prepare_display_region\n"; DBG_E - if (_current_display_region == (DisplayRegion*)0L) { - dxgsg9_cat.error() - << "Invalid NULL display region in prepare_display_region()\n"; - - } else if (_current_display_region != _actual_display_region) { - _actual_display_region = _current_display_region; - // DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::prepare_display_region\n"; DBG_E - int l, u, w, h; - _actual_display_region->get_region_pixels_i(l, u, w, h); + int l, u, w, h; + _current_display_region->get_region_pixels_i(l, u, w, h); + + DBG_S dxgsg9_cat.debug ( ) << "display_region " << l << " " << u << " " << w << " " << h << "\n"; DBG_E - DBG_S dxgsg9_cat.debug ( ) << "display_region " << l << " " << u << " " << w << " " << h << "\n"; DBG_E - - // Create the viewport - D3DVIEWPORT9 vp = { l, u, w, h, 0.0f, 1.0f }; - HRESULT hr = _d3d_device->SetViewport(&vp); + // Create the viewport + D3DVIEWPORT9 vp = { l, u, w, h, 0.0f, 1.0f }; + HRESULT hr = _d3d_device->SetViewport(&vp); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "_screen->_swap_chain = " << _screen->_swap_chain << " _swap_chain = " << _swap_chain << "\n"; + dxgsg9_cat.error() + << "SetViewport(" << l << ", " << u << ", " << w << ", " << h + << ") failed" << D3DERRORSTRING(hr); + + D3DVIEWPORT9 vp_old; + _d3d_device->GetViewport(&vp_old); + dxgsg9_cat.error() + << "GetViewport(" << vp_old.X << ", " << vp_old.Y << ", " << vp_old.Width << ", " + << vp_old.Height << ") returned: Trying to set that vp---->\n"; + hr = _d3d_device->SetViewport(&vp_old); + if (FAILED(hr)) { - dxgsg9_cat.error() - << "_screen->_swap_chain = " << _screen->_swap_chain << " _swap_chain = " << _swap_chain << "\n"; - dxgsg9_cat.error() - << "SetViewport(" << l << ", " << u << ", " << w << ", " << h - << ") failed" << D3DERRORSTRING(hr); - - D3DVIEWPORT9 vp_old; - _d3d_device->GetViewport(&vp_old); - dxgsg9_cat.error() - << "GetViewport(" << vp_old.X << ", " << vp_old.Y << ", " << vp_old.Width << ", " - << vp_old.Height << ") returned: Trying to set that vp---->\n"; - hr = _d3d_device->SetViewport(&vp_old); - - if (FAILED(hr)) { - dxgsg9_cat.error() << "Failed again\n"; - throw_event("panda3d-render-error"); - nassertv(false); - } + dxgsg9_cat.error() << "Failed again\n"; + throw_event("panda3d-render-error"); + nassertv(false); } - // Note: for DX9, also change scissor clipping state here } + // Note: for DX9, also change scissor clipping state here } //////////////////////////////////////////////////////////////////// @@ -826,7 +820,7 @@ prepare_display_region() { // false if it is not. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: -prepare_lens(Lens::StereoChannel stereo_channel) { +prepare_lens() { if (_current_lens == (Lens *)NULL) { return false; } @@ -836,7 +830,7 @@ prepare_lens(Lens::StereoChannel stereo_channel) { } // Start with the projection matrix from the lens. - const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel); + const LMatrix4f &lens_mat = _current_lens->get_projection_mat(_current_stereo_channel); // The projection matrix must always be left-handed Y-up internally, // to match DirectX's convention, even if our coordinate system of diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 27a0de9cff..c5cc49b297 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -102,8 +102,8 @@ public: virtual void do_clear(const RenderBuffer &buffer); - virtual void prepare_display_region(); - virtual bool prepare_lens(Lens::StereoChannel stereo_channel); + virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel); + virtual bool prepare_lens(); virtual bool begin_frame(); virtual bool begin_scene(); diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index 1918407972..d506fefaaf 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -187,15 +187,8 @@ open_window(const WindowProperties &props, GraphicsEngine *engine, _display_region_3d->set_camera(camera_np); if (_window->is_stereo() && default_stereo_camera) { - // Actually, let's make a stereo camera. That means the - // _display_region_3d will be the left channel, and we need to - // make another one to be the right channel. - - _display_region_3d->set_stereo_channel(Lens::SC_left); - - _display_region_right = _window->make_display_region(); - _display_region_right->set_stereo_channel(Lens::SC_right); - _display_region_right->set_camera(camera_np); + // Actually, let's make a stereo DisplayRegion. + _display_region_3d->set_stereo_channel(Lens::SC_stereo); } set_background_type(_background_type); @@ -966,12 +959,6 @@ set_background_type(WindowFramework::BackgroundType type) { _display_region_3d->set_clear_depth_active(true); _display_region_3d->set_clear_color(_window->get_clear_color()); _display_region_3d->set_clear_depth(_window->get_clear_depth()); - if (_display_region_right) { - _display_region_right->set_clear_color_active(true); - _display_region_right->set_clear_depth_active(true); - _display_region_right->set_clear_color(_window->get_clear_color()); - _display_region_right->set_clear_depth(_window->get_clear_depth()); - } break; case BT_black: @@ -979,12 +966,6 @@ set_background_type(WindowFramework::BackgroundType type) { _display_region_3d->set_clear_depth_active(true); _display_region_3d->set_clear_color(Colorf(0.0f, 0.0f, 0.0f, 0.0f)); _display_region_3d->set_clear_depth(1.0f); - if (_display_region_right) { - _display_region_right->set_clear_color_active(true); - _display_region_right->set_clear_depth_active(true); - _display_region_right->set_clear_color(Colorf(0.0f, 0.0f, 0.0f, 0.0f)); - _display_region_right->set_clear_depth(1.0f); - } break; case BT_gray: @@ -992,12 +973,6 @@ set_background_type(WindowFramework::BackgroundType type) { _display_region_3d->set_clear_depth_active(true); _display_region_3d->set_clear_color(Colorf(0.3f, 0.3f, 0.3f, 0.0f)); _display_region_3d->set_clear_depth(1.0f); - if (_display_region_right) { - _display_region_right->set_clear_color_active(true); - _display_region_right->set_clear_depth_active(true); - _display_region_right->set_clear_color(Colorf(0.3f, 0.3f, 0.3f, 0.0f)); - _display_region_right->set_clear_depth(1.0f); - } break; case BT_white: @@ -1005,21 +980,11 @@ set_background_type(WindowFramework::BackgroundType type) { _display_region_3d->set_clear_depth_active(true); _display_region_3d->set_clear_color(Colorf(1.0f, 1.0f, 1.0f, 0.0f)); _display_region_3d->set_clear_depth(1.0f); - if (_display_region_right) { - _display_region_right->set_clear_color_active(true); - _display_region_right->set_clear_depth_active(true); - _display_region_right->set_clear_color(Colorf(1.0f, 1.0f, 1.0f, 0.0f)); - _display_region_right->set_clear_depth(1.0f); - } break; case BT_none: _display_region_3d->set_clear_color_active(false); _display_region_3d->set_clear_depth_active(false); - if (_display_region_right) { - _display_region_right->set_clear_color_active(false); - _display_region_right->set_clear_depth_active(false); - } break; } } diff --git a/panda/src/framework/windowFramework.h b/panda/src/framework/windowFramework.h index 07ca8ad638..fe60f2f4a8 100644 --- a/panda/src/framework/windowFramework.h +++ b/panda/src/framework/windowFramework.h @@ -160,7 +160,6 @@ private: PT(GraphicsWindow) _window; PT(DisplayRegion) _display_region_2d; PT(DisplayRegion) _display_region_3d; - PT(DisplayRegion) _display_region_right; NodePath _camera_group; typedef pvector< PT(Camera) > Cameras; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index ea4d3c3a42..b84a6fa54f 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -961,33 +961,25 @@ do_clear(const RenderBuffer &buffer) { // scissor region and viewport) //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -prepare_display_region() { - if (_current_display_region == (DisplayRegion*)0L) { - GLCAT.error() - << "Invalid NULL display region in prepare_display_region()\n"; - enable_scissor(false); - _viewport_width = 1; - _viewport_height = 1; +prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) { + nassertv(dr != (DisplayRegion *)NULL); + GraphicsStateGuardian::prepare_display_region(dr, stereo_channel); - } else if (_current_display_region != _actual_display_region) { - _actual_display_region = _current_display_region; + int l, b, w, h; + _current_display_region->get_region_pixels(l, b, w, h); + _viewport_width = w; + _viewport_height = h; + GLint x = GLint(l); + GLint y = GLint(b); + GLsizei width = GLsizei(w); + GLsizei height = GLsizei(h); + + set_draw_buffer(get_render_buffer(_current_display_region->get_draw_buffer_type())); + enable_scissor(true); + GLP(Scissor)(x, y, width, height); + GLP(Viewport)(x, y, width, height); - int l, b, w, h; - _actual_display_region->get_region_pixels(l, b, w, h); - _viewport_width = w; - _viewport_height = h; - GLint x = GLint(l); - GLint y = GLint(b); - GLsizei width = GLsizei(w); - GLsizei height = GLsizei(h); - - set_draw_buffer(get_render_buffer(_actual_display_region->get_draw_buffer_type())); - enable_scissor(true); - GLP(Scissor)(x, y, width, height); - GLP(Viewport)(x, y, width, height); - } report_my_gl_errors(); - do_point_size(); } @@ -1004,7 +996,7 @@ prepare_display_region() { // false if it is not. //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: -prepare_lens(Lens::StereoChannel stereo_channel) { +prepare_lens() { if (_current_lens == (Lens *)NULL) { return false; } @@ -1013,7 +1005,7 @@ prepare_lens(Lens::StereoChannel stereo_channel) { return false; } - const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel); + const LMatrix4f &lens_mat = _current_lens->get_projection_mat(_current_stereo_channel); // The projection matrix must always be right-handed Y-up, even if // our coordinate system of choice is otherwise, because certain GL @@ -1071,8 +1063,6 @@ begin_frame() { _primitive_batches_display_list_pcollector.clear_level(); #endif - _actual_display_region = NULL; - report_my_gl_errors(); return true; } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 5a5dc27bde..6c7976c2ef 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -84,8 +84,8 @@ public: virtual void do_clear(const RenderBuffer &buffer); - virtual void prepare_display_region(); - virtual bool prepare_lens(Lens::StereoChannel stereo_channel); + virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel); + virtual bool prepare_lens(); virtual bool begin_frame(); virtual void end_frame(); @@ -321,8 +321,6 @@ protected: PT(ShaderExpansion) _texture_binding_shader_expansion; CLP(ShaderContext) *_texture_binding_shader_context; - CPT(DisplayRegion) _actual_display_region; - #ifdef SUPPORT_IMMEDIATE_MODE CLP(ImmediateModeSender) _sender; bool _use_sender; diff --git a/panda/src/gobj/lens.cxx b/panda/src/gobj/lens.cxx index f362db27de..7d0d471c12 100644 --- a/panda/src/gobj/lens.cxx +++ b/panda/src/gobj/lens.cxx @@ -1076,7 +1076,8 @@ get_projection_mat(StereoChannel channel) const { return _projection_mat_left; case SC_right: return _projection_mat_right; - case SC_both: + case SC_mono: + case SC_stereo: return _projection_mat; } @@ -1115,7 +1116,8 @@ get_projection_mat_inv(StereoChannel stereo_channel) const { } return _projection_mat_right_inv; - case SC_both: + case SC_mono: + case SC_stereo: break; } diff --git a/panda/src/gobj/lens.h b/panda/src/gobj/lens.h index 09f5bfaf3e..91a739e935 100644 --- a/panda/src/gobj/lens.h +++ b/panda/src/gobj/lens.h @@ -50,9 +50,10 @@ public: PUBLISHED: enum StereoChannel { - SC_left = 0x01, - SC_right = 0x02, - SC_both = 0x03, // == SC_left | SC_right + SC_mono = 0x00, + SC_left = 0x01, + SC_right = 0x02, + SC_stereo = 0x03, // == SC_left | SC_right }; virtual PT(Lens) make_copy() const=0; @@ -151,8 +152,8 @@ PUBLISHED: virtual PT(BoundingVolume) make_bounds() const; - const LMatrix4f &get_projection_mat(StereoChannel channel = SC_both) const; - const LMatrix4f &get_projection_mat_inv(StereoChannel channel = SC_both) const; + const LMatrix4f &get_projection_mat(StereoChannel channel = SC_mono) const; + const LMatrix4f &get_projection_mat_inv(StereoChannel channel = SC_mono) const; const LMatrix4f &get_film_mat() const; const LMatrix4f &get_film_mat_inv() const;