support stereo DisplayRegions

This commit is contained in:
David Rose 2006-02-17 19:17:06 +00:00
parent 486680b144
commit 47c2e41c75
23 changed files with 221 additions and 499 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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 &copy) :
_display_region(copy._display_region),
_stack_level(copy._stack_level)
{
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionStack::Copy Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionStack::
operator =(const DisplayRegionStack &copy) {
_display_region = copy._display_region;
_stack_level = copy._stack_level;
}

View File

@ -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 &copy);
INLINE void operator =(const DisplayRegionStack &copy);
private:
CPT(DisplayRegion) _display_region;
int _stack_level;
friend class GraphicsStateGuardian;
};
#include "displayRegionStack.I"
#endif

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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 &copy) :
_lens(copy._lens),
_stack_level(copy._stack_level)
{
}
////////////////////////////////////////////////////////////////////
// Function: LensStack::Copy Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void LensStack::
operator =(const LensStack &copy) {
_lens = copy._lens;
_stack_level = copy._stack_level;
}

View File

@ -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 &copy);
INLINE void operator =(const LensStack &copy);
private:
CPT(Lens) _lens;
int _stack_level;
friend class GraphicsStateGuardian;
};
#include "lensStack.I"
#endif

View File

@ -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

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;