mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
stereo rendering
This commit is contained in:
parent
5daca17ee6
commit
ffb92db022
@ -746,7 +746,8 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
return aspectRatio
|
return aspectRatio
|
||||||
|
|
||||||
def makeCamera(self, win, sort = 0, scene = None,
|
def makeCamera(self, win, sort = 0, scene = None,
|
||||||
displayRegion = (0, 1, 0, 1), aspectRatio = None,
|
displayRegion = (0, 1, 0, 1), stereoChannel = None,
|
||||||
|
aspectRatio = None,
|
||||||
lens = None, camName = 'cam'):
|
lens = None, camName = 'cam'):
|
||||||
"""
|
"""
|
||||||
Makes a new 3-d camera associated with the indicated window,
|
Makes a new 3-d camera associated with the indicated window,
|
||||||
@ -755,6 +756,9 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
dr = win.makeDisplayRegion(*displayRegion)
|
dr = win.makeDisplayRegion(*displayRegion)
|
||||||
dr.setSort(sort)
|
dr.setSort(sort)
|
||||||
|
|
||||||
|
if stereoChannel != None:
|
||||||
|
dr.setStereoChannel(stereoChannel)
|
||||||
|
|
||||||
if scene == None:
|
if scene == None:
|
||||||
scene = self.render
|
scene = self.render
|
||||||
|
|
||||||
|
@ -52,6 +52,20 @@ get_sort() const {
|
|||||||
return cdata->_sort;
|
return cdata->_sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DisplayRegion::get_stereo_channel
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns whether the DisplayRegion is specified as the
|
||||||
|
// left or right channel of a stereo pair, or whether it
|
||||||
|
// is a normal, monocular image. See
|
||||||
|
// set_stereo_channel().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE Lens::StereoChannel DisplayRegion::
|
||||||
|
get_stereo_channel() {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
return cdata->_stereo_channel;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DisplayRegion::set_cube_map_index
|
// Function: DisplayRegion::set_cube_map_index
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -75,7 +75,7 @@ operator = (const DisplayRegion&) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DisplayRegion::Destructor
|
// Function: DisplayRegion::Destructor
|
||||||
// Access: Public
|
// Access: Public, Virtual
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
DisplayRegion::
|
DisplayRegion::
|
||||||
@ -305,8 +305,7 @@ set_active(bool active) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void DisplayRegion::
|
void DisplayRegion::
|
||||||
set_sort(int sort) {
|
set_sort(int sort) {
|
||||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
nassertv(Thread::get_current_pipeline_stage() == 0);
|
||||||
nassertv(pipeline_stage == 0);
|
|
||||||
CDReader cdata(_cycler);
|
CDReader cdata(_cycler);
|
||||||
|
|
||||||
if (sort != cdata->_sort) {
|
if (sort != cdata->_sort) {
|
||||||
@ -316,6 +315,53 @@ set_sort(int sort) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DisplayRegion::set_stereo_channel
|
||||||
|
// Access: Published
|
||||||
|
// 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().
|
||||||
|
//
|
||||||
|
// 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().
|
||||||
|
//
|
||||||
|
// Normally you would create at least two DisplayRegions
|
||||||
|
// for a stereo window, one for each of the left and
|
||||||
|
// right channels. The two DisplayRegions may share the
|
||||||
|
// same camera (and thus the same lens); this parameter
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void DisplayRegion::
|
||||||
|
set_stereo_channel(Lens::StereoChannel stereo_channel) {
|
||||||
|
nassertv(Thread::get_current_pipeline_stage() == 0);
|
||||||
|
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
cdata->_stereo_channel = stereo_channel;
|
||||||
|
switch (stereo_channel) {
|
||||||
|
case Lens::SC_left:
|
||||||
|
cdata->_draw_buffer_mask = ~(RenderBuffer::T_front_right | RenderBuffer::T_back_right);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Lens::SC_right:
|
||||||
|
cdata->_draw_buffer_mask = ~(RenderBuffer::T_front_left | RenderBuffer::T_back_left);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Lens::SC_both:
|
||||||
|
cdata->_draw_buffer_mask = ~0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DisplayRegion::compute_pixels
|
// Function: DisplayRegion::compute_pixels
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -624,6 +670,33 @@ get_screenshot(PNMImage &image) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DisplayRegion::get_screenshot_buffer_type
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the RenderBuffer that should be used for
|
||||||
|
// capturing screenshots from this particular
|
||||||
|
// DrawableRegion.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int DisplayRegion::
|
||||||
|
get_screenshot_buffer_type() const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
return _screenshot_buffer_type & cdata->_draw_buffer_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DisplayRegion::get_draw_buffer_type
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the RenderBuffer into which the GSG should
|
||||||
|
// issue draw commands. Normally, this is the back
|
||||||
|
// buffer for double-buffered windows, and the front
|
||||||
|
// buffer for single-buffered windows.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int DisplayRegion::
|
||||||
|
get_draw_buffer_type() const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
return _draw_buffer_type & cdata->_draw_buffer_mask;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DisplayRegion::win_display_regions_changed
|
// Function: DisplayRegion::win_display_regions_changed
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -686,6 +759,8 @@ CData() :
|
|||||||
_camera_node((Camera *)NULL),
|
_camera_node((Camera *)NULL),
|
||||||
_active(true),
|
_active(true),
|
||||||
_sort(0),
|
_sort(0),
|
||||||
|
_stereo_channel(Lens::SC_both),
|
||||||
|
_draw_buffer_mask(~0),
|
||||||
_cube_map_index(-1)
|
_cube_map_index(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -711,6 +786,8 @@ CData(const DisplayRegion::CData ©) :
|
|||||||
_camera_node(copy._camera_node),
|
_camera_node(copy._camera_node),
|
||||||
_active(copy._active),
|
_active(copy._active),
|
||||||
_sort(copy._sort),
|
_sort(copy._sort),
|
||||||
|
_stereo_channel(copy._stereo_channel),
|
||||||
|
_draw_buffer_mask(copy._draw_buffer_mask),
|
||||||
_cube_map_index(copy._cube_map_index)
|
_cube_map_index(copy._cube_map_index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "cycleDataStageWriter.h"
|
#include "cycleDataStageWriter.h"
|
||||||
#include "pipelineCycler.h"
|
#include "pipelineCycler.h"
|
||||||
#include "config_display.h"
|
#include "config_display.h"
|
||||||
|
#include "lens.h"
|
||||||
|
|
||||||
#include "plist.h"
|
#include "plist.h"
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ private:
|
|||||||
void operator = (const DisplayRegion ©);
|
void operator = (const DisplayRegion ©);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~DisplayRegion();
|
virtual ~DisplayRegion();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
INLINE bool operator < (const DisplayRegion &other) const;
|
INLINE bool operator < (const DisplayRegion &other) const;
|
||||||
@ -88,6 +89,9 @@ PUBLISHED:
|
|||||||
void set_sort(int sort);
|
void set_sort(int sort);
|
||||||
INLINE int get_sort() const;
|
INLINE int get_sort() const;
|
||||||
|
|
||||||
|
void set_stereo_channel(Lens::StereoChannel stereo_channel);
|
||||||
|
INLINE Lens::StereoChannel get_stereo_channel();
|
||||||
|
|
||||||
INLINE void set_cube_map_index(int cube_map_index);
|
INLINE void set_cube_map_index(int cube_map_index);
|
||||||
INLINE int get_cube_map_index() const;
|
INLINE int get_cube_map_index() const;
|
||||||
|
|
||||||
@ -114,6 +118,9 @@ public:
|
|||||||
INLINE CullResult *get_cull_result() const;
|
INLINE CullResult *get_cull_result() const;
|
||||||
INLINE SceneSetup *get_scene_setup() const;
|
INLINE SceneSetup *get_scene_setup() const;
|
||||||
|
|
||||||
|
virtual int get_screenshot_buffer_type() const;
|
||||||
|
virtual int get_draw_buffer_type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CData;
|
class CData;
|
||||||
|
|
||||||
@ -155,6 +162,8 @@ private:
|
|||||||
|
|
||||||
bool _active;
|
bool _active;
|
||||||
int _sort;
|
int _sort;
|
||||||
|
Lens::StereoChannel _stereo_channel;
|
||||||
|
int _draw_buffer_mask;
|
||||||
int _cube_map_index;
|
int _cube_map_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,28 +202,3 @@ INLINE bool DrawableRegion::
|
|||||||
is_any_clear_active() const {
|
is_any_clear_active() const {
|
||||||
return (_flags & F_clear_all) != 0;
|
return (_flags & F_clear_all) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: DrawableRegion::get_draw_buffer_type
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the RenderBuffer into which the GSG should
|
|
||||||
// issue draw commands. Normally, this is the back
|
|
||||||
// buffer for double-buffered windows, and the front
|
|
||||||
// buffer for single-buffered windows.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE int DrawableRegion::
|
|
||||||
get_draw_buffer_type() const {
|
|
||||||
return _draw_buffer_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: DrawableRegion::get_screenshot_buffer_type
|
|
||||||
// Access: Public, Virtual
|
|
||||||
// Description: Returns the RenderBuffer that should be used for
|
|
||||||
// capturing screenshots from this particular
|
|
||||||
// DrawableRegion.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE int DrawableRegion::
|
|
||||||
get_screenshot_buffer_type() const {
|
|
||||||
return _screenshot_buffer_type;
|
|
||||||
}
|
|
||||||
|
@ -17,3 +17,38 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "drawableRegion.h"
|
#include "drawableRegion.h"
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DrawableRegion::Destructor
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
DrawableRegion::
|
||||||
|
~DrawableRegion() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DrawableRegion::get_screenshot_buffer_type
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the RenderBuffer that should be used for
|
||||||
|
// capturing screenshots from this particular
|
||||||
|
// DrawableRegion.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int DrawableRegion::
|
||||||
|
get_screenshot_buffer_type() const {
|
||||||
|
return _screenshot_buffer_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DrawableRegion::get_draw_buffer_type
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the RenderBuffer into which the GSG should
|
||||||
|
// issue draw commands. Normally, this is the back
|
||||||
|
// buffer for double-buffered windows, and the front
|
||||||
|
// buffer for single-buffered windows.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int DrawableRegion::
|
||||||
|
get_draw_buffer_type() const {
|
||||||
|
return _draw_buffer_type;
|
||||||
|
}
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
INLINE DrawableRegion();
|
INLINE DrawableRegion();
|
||||||
INLINE DrawableRegion(const DrawableRegion ©);
|
INLINE DrawableRegion(const DrawableRegion ©);
|
||||||
INLINE void operator = (const DrawableRegion ©);
|
INLINE void operator = (const DrawableRegion ©);
|
||||||
|
virtual ~DrawableRegion();
|
||||||
|
|
||||||
INLINE void copy_clear_settings(const DrawableRegion ©);
|
INLINE void copy_clear_settings(const DrawableRegion ©);
|
||||||
|
|
||||||
@ -57,8 +58,8 @@ PUBLISHED:
|
|||||||
INLINE bool is_any_clear_active() const;
|
INLINE bool is_any_clear_active() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
INLINE int get_screenshot_buffer_type() const;
|
virtual int get_screenshot_buffer_type() const;
|
||||||
INLINE int get_draw_buffer_type() const;
|
virtual int get_draw_buffer_type() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _screenshot_buffer_type;
|
int _screenshot_buffer_type;
|
||||||
|
@ -574,7 +574,7 @@ set_scene(SceneSetup *scene_setup) {
|
|||||||
if (_current_lens == (Lens *)NULL) {
|
if (_current_lens == (Lens *)NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return prepare_lens();
|
return prepare_lens(scene_setup->get_display_region()->get_stereo_channel());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -625,7 +625,7 @@ clear(DrawableRegion *clearable) {
|
|||||||
// false if it is not.
|
// false if it is not.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool GraphicsStateGuardian::
|
bool GraphicsStateGuardian::
|
||||||
prepare_lens() {
|
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "displayRegionStack.h"
|
#include "displayRegionStack.h"
|
||||||
#include "lensStack.h"
|
#include "lensStack.h"
|
||||||
#include "preparedGraphicsObjects.h"
|
#include "preparedGraphicsObjects.h"
|
||||||
|
#include "lens.h"
|
||||||
#include "graphicsStateGuardianBase.h"
|
#include "graphicsStateGuardianBase.h"
|
||||||
#include "graphicsThreadingModel.h"
|
#include "graphicsThreadingModel.h"
|
||||||
#include "graphicsPipe.h"
|
#include "graphicsPipe.h"
|
||||||
@ -161,7 +161,7 @@ public:
|
|||||||
INLINE void clear(DisplayRegion *dr);
|
INLINE void clear(DisplayRegion *dr);
|
||||||
|
|
||||||
virtual void prepare_display_region()=0;
|
virtual void prepare_display_region()=0;
|
||||||
virtual bool prepare_lens();
|
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||||
|
|
||||||
INLINE int force_normals();
|
INLINE int force_normals();
|
||||||
INLINE int undo_force_normals();
|
INLINE int undo_force_normals();
|
||||||
|
@ -609,7 +609,7 @@ prepare_display_region() {
|
|||||||
// false if it is not.
|
// false if it is not.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool DXGraphicsStateGuardian8::
|
bool DXGraphicsStateGuardian8::
|
||||||
prepare_lens() {
|
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||||
if (_current_lens == (Lens *)NULL) {
|
if (_current_lens == (Lens *)NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -619,7 +619,7 @@ prepare_lens() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start with the projection matrix from the lens.
|
// Start with the projection matrix from the lens.
|
||||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
|
const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel);
|
||||||
|
|
||||||
// The projection matrix must always be left-handed Y-up internally,
|
// The projection matrix must always be left-handed Y-up internally,
|
||||||
// to match DirectX's convention, even if our coordinate system of
|
// to match DirectX's convention, even if our coordinate system of
|
||||||
@ -1301,7 +1301,8 @@ end_draw_primitives() {
|
|||||||
|
|
||||||
if (_vertex_data->is_vertex_transformed()) {
|
if (_vertex_data->is_vertex_transformed()) {
|
||||||
// Restore the projection matrix that we wiped out above.
|
// Restore the projection matrix that we wiped out above.
|
||||||
prepare_lens();
|
_d3d_device->SetTransform(D3DTS_PROJECTION,
|
||||||
|
(D3DMATRIX*)_projection_mat.get_data());
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsStateGuardian::end_draw_primitives();
|
GraphicsStateGuardian::end_draw_primitives();
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
virtual void do_clear(const RenderBuffer &buffer);
|
virtual void do_clear(const RenderBuffer &buffer);
|
||||||
|
|
||||||
virtual void prepare_display_region();
|
virtual void prepare_display_region();
|
||||||
virtual bool prepare_lens();
|
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||||
|
|
||||||
virtual bool begin_frame();
|
virtual bool begin_frame();
|
||||||
virtual bool begin_scene();
|
virtual bool begin_scene();
|
||||||
|
@ -826,7 +826,7 @@ prepare_display_region() {
|
|||||||
// false if it is not.
|
// false if it is not.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool DXGraphicsStateGuardian9::
|
bool DXGraphicsStateGuardian9::
|
||||||
prepare_lens() {
|
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||||
if (_current_lens == (Lens *)NULL) {
|
if (_current_lens == (Lens *)NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -836,7 +836,7 @@ prepare_lens() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start with the projection matrix from the lens.
|
// Start with the projection matrix from the lens.
|
||||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
|
const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel);
|
||||||
|
|
||||||
// The projection matrix must always be left-handed Y-up internally,
|
// The projection matrix must always be left-handed Y-up internally,
|
||||||
// to match DirectX's convention, even if our coordinate system of
|
// to match DirectX's convention, even if our coordinate system of
|
||||||
@ -1716,7 +1716,8 @@ end_draw_primitives() {
|
|||||||
|
|
||||||
if (_vertex_data->is_vertex_transformed()) {
|
if (_vertex_data->is_vertex_transformed()) {
|
||||||
// Restore the projection matrix that we wiped out above.
|
// Restore the projection matrix that we wiped out above.
|
||||||
prepare_lens();
|
_d3d_device->SetTransform(D3DTS_PROJECTION,
|
||||||
|
(D3DMATRIX*)_projection_mat.get_data());
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsStateGuardian::end_draw_primitives();
|
GraphicsStateGuardian::end_draw_primitives();
|
||||||
|
@ -103,7 +103,7 @@ public:
|
|||||||
virtual void do_clear(const RenderBuffer &buffer);
|
virtual void do_clear(const RenderBuffer &buffer);
|
||||||
|
|
||||||
virtual void prepare_display_region();
|
virtual void prepare_display_region();
|
||||||
virtual bool prepare_lens();
|
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||||
|
|
||||||
virtual bool begin_frame();
|
virtual bool begin_frame();
|
||||||
virtual bool begin_scene();
|
virtual bool begin_scene();
|
||||||
|
@ -794,6 +794,7 @@ reset() {
|
|||||||
GLP(Disable)(GL_MULTISAMPLE);
|
GLP(Disable)(GL_MULTISAMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_stereo = ((get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_stereo) != 0);
|
||||||
|
|
||||||
// Set up all the enabled/disabled flags to GL's known initial
|
// Set up all the enabled/disabled flags to GL's known initial
|
||||||
// values: everything off.
|
// values: everything off.
|
||||||
@ -984,6 +985,7 @@ prepare_display_region() {
|
|||||||
GLsizei width = GLsizei(w);
|
GLsizei width = GLsizei(w);
|
||||||
GLsizei height = GLsizei(h);
|
GLsizei height = GLsizei(h);
|
||||||
|
|
||||||
|
set_draw_buffer(get_render_buffer(_actual_display_region->get_draw_buffer_type()));
|
||||||
enable_scissor(true);
|
enable_scissor(true);
|
||||||
GLP(Scissor)(x, y, width, height);
|
GLP(Scissor)(x, y, width, height);
|
||||||
GLP(Viewport)(x, y, width, height);
|
GLP(Viewport)(x, y, width, height);
|
||||||
@ -1006,7 +1008,7 @@ prepare_display_region() {
|
|||||||
// false if it is not.
|
// false if it is not.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool CLP(GraphicsStateGuardian)::
|
bool CLP(GraphicsStateGuardian)::
|
||||||
prepare_lens() {
|
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||||
if (_current_lens == (Lens *)NULL) {
|
if (_current_lens == (Lens *)NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1015,7 +1017,7 @@ prepare_lens() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
|
const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel);
|
||||||
|
|
||||||
// The projection matrix must always be right-handed Y-up, even if
|
// The projection matrix must always be right-handed Y-up, even if
|
||||||
// our coordinate system of choice is otherwise, because certain GL
|
// our coordinate system of choice is otherwise, because certain GL
|
||||||
@ -3732,19 +3734,35 @@ set_draw_buffer(const RenderBuffer &rb) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RenderBuffer::T_front_right:
|
case RenderBuffer::T_front_right:
|
||||||
|
if (_stereo) {
|
||||||
GLP(DrawBuffer)(GL_FRONT_RIGHT);
|
GLP(DrawBuffer)(GL_FRONT_RIGHT);
|
||||||
|
} else {
|
||||||
|
GLP(DrawBuffer)(GL_FRONT);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RenderBuffer::T_front_left:
|
case RenderBuffer::T_front_left:
|
||||||
|
if (_stereo) {
|
||||||
GLP(DrawBuffer)(GL_FRONT_LEFT);
|
GLP(DrawBuffer)(GL_FRONT_LEFT);
|
||||||
|
} else {
|
||||||
|
GLP(DrawBuffer)(GL_FRONT);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RenderBuffer::T_back_right:
|
case RenderBuffer::T_back_right:
|
||||||
|
if (_stereo) {
|
||||||
GLP(DrawBuffer)(GL_BACK_RIGHT);
|
GLP(DrawBuffer)(GL_BACK_RIGHT);
|
||||||
|
} else {
|
||||||
|
GLP(DrawBuffer)(GL_BACK);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RenderBuffer::T_back_left:
|
case RenderBuffer::T_back_left:
|
||||||
|
if (_stereo) {
|
||||||
GLP(DrawBuffer)(GL_BACK_LEFT);
|
GLP(DrawBuffer)(GL_BACK_LEFT);
|
||||||
|
} else {
|
||||||
|
GLP(DrawBuffer)(GL_BACK);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -78,7 +78,7 @@ public:
|
|||||||
virtual void do_clear(const RenderBuffer &buffer);
|
virtual void do_clear(const RenderBuffer &buffer);
|
||||||
|
|
||||||
virtual void prepare_display_region();
|
virtual void prepare_display_region();
|
||||||
virtual bool prepare_lens();
|
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||||
|
|
||||||
virtual bool begin_frame();
|
virtual bool begin_frame();
|
||||||
virtual void end_frame();
|
virtual void end_frame();
|
||||||
@ -282,6 +282,8 @@ protected:
|
|||||||
MM_alpha_mask = 0x0004,
|
MM_alpha_mask = 0x0004,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool _stereo;
|
||||||
|
|
||||||
int _multisample_mode;
|
int _multisample_mode;
|
||||||
bool _line_smooth_enabled;
|
bool _line_smooth_enabled;
|
||||||
bool _point_smooth_enabled;
|
bool _point_smooth_enabled;
|
||||||
|
@ -66,6 +66,13 @@ operator = (const Lens ©) {
|
|||||||
_aspect_ratio = copy._aspect_ratio;
|
_aspect_ratio = copy._aspect_ratio;
|
||||||
_near_distance = copy._near_distance;
|
_near_distance = copy._near_distance;
|
||||||
_far_distance = copy._far_distance;
|
_far_distance = copy._far_distance;
|
||||||
|
|
||||||
|
_view_hpr = copy._view_hpr;
|
||||||
|
_view_vector = copy._view_vector;
|
||||||
|
_interocular_distance = copy._interocular_distance;
|
||||||
|
_convergence_distance = copy._convergence_distance;
|
||||||
|
_keystone = copy._keystone;
|
||||||
|
|
||||||
_user_flags = copy._user_flags;
|
_user_flags = copy._user_flags;
|
||||||
_comp_flags = 0;
|
_comp_flags = 0;
|
||||||
|
|
||||||
@ -105,7 +112,8 @@ clear() {
|
|||||||
_view_hpr.set(0.0f, 0.0f, 0.0f);
|
_view_hpr.set(0.0f, 0.0f, 0.0f);
|
||||||
_view_vector.set(0.0f, 1.0f, 0.0f);
|
_view_vector.set(0.0f, 1.0f, 0.0f);
|
||||||
_up_vector.set(0.0f, 0.0f, 1.0f);
|
_up_vector.set(0.0f, 0.0f, 1.0f);
|
||||||
_iod_offset = 0.0f;
|
_interocular_distance = 0.0f;
|
||||||
|
_convergence_distance = 0.0f;
|
||||||
_keystone.set(0.0f, 0.0f);
|
_keystone.set(0.0f, 0.0f);
|
||||||
|
|
||||||
_user_flags = 0;
|
_user_flags = 0;
|
||||||
@ -432,7 +440,7 @@ set_view_hpr(const LVecBase3f &view_hpr) {
|
|||||||
_view_hpr = view_hpr;
|
_view_hpr = view_hpr;
|
||||||
adjust_user_flags(UF_view_vector | UF_view_mat,
|
adjust_user_flags(UF_view_vector | UF_view_mat,
|
||||||
UF_view_hpr);
|
UF_view_hpr);
|
||||||
adjust_comp_flags(CF_mat | CF_view_vector | CF_iod_offset,
|
adjust_comp_flags(CF_mat | CF_view_vector,
|
||||||
CF_view_hpr);
|
CF_view_hpr);
|
||||||
throw_change_event();
|
throw_change_event();
|
||||||
}
|
}
|
||||||
@ -465,7 +473,7 @@ set_view_vector(const LVector3f &view_vector, const LVector3f &up_vector) {
|
|||||||
_up_vector = up_vector;
|
_up_vector = up_vector;
|
||||||
adjust_user_flags(UF_view_hpr | UF_view_mat,
|
adjust_user_flags(UF_view_hpr | UF_view_mat,
|
||||||
UF_view_vector);
|
UF_view_vector);
|
||||||
adjust_comp_flags(CF_mat | CF_view_hpr | CF_iod_offset,
|
adjust_comp_flags(CF_mat | CF_view_hpr,
|
||||||
CF_view_vector);
|
CF_view_vector);
|
||||||
throw_change_event();
|
throw_change_event();
|
||||||
}
|
}
|
||||||
@ -509,39 +517,71 @@ get_nodal_point() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Lens::set_iod_offset
|
// Function: Lens::set_interocular_distance
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Sets the amount by which the lens is shifted to the
|
// Description: Sets the distance between the left and right eyes of
|
||||||
// right, perpendicular to its view vector and up
|
// a stereo camera. This distance is used to apply a
|
||||||
// vector. This is normally used to shift one or both
|
// stereo effect when the lens is rendered on a stereo
|
||||||
// lens of a stereo camera to generate parallax. You
|
// display region. It only has an effect on a
|
||||||
// can also simply set a complete transformation matrix
|
// PerspectiveLens.
|
||||||
// (via set_view_mat()) that includes an arbitrary
|
//
|
||||||
// translation.
|
// Also see set_interocular_distance(), which relates.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void Lens::
|
void Lens::
|
||||||
set_iod_offset(float iod_offset) {
|
set_interocular_distance(float interocular_distance) {
|
||||||
_iod_offset = iod_offset;
|
_interocular_distance = interocular_distance;
|
||||||
adjust_user_flags(UF_view_mat,
|
if (_interocular_distance == 0.0f) {
|
||||||
UF_iod_offset);
|
adjust_user_flags(UF_interocular_distance, 0);
|
||||||
adjust_comp_flags(CF_mat | CF_view_hpr | CF_view_vector,
|
} else {
|
||||||
CF_iod_offset);
|
adjust_user_flags(0, UF_interocular_distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
adjust_comp_flags(CF_mat, 0);
|
||||||
throw_change_event();
|
throw_change_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Lens::get_iod_offset
|
// Function: Lens::get_interocular_distance
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the aspect ratio of the Lens. This is
|
// Description: See set_interocular_distance().
|
||||||
// determined based on the indicated film size; see
|
|
||||||
// set_film_size().
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
float Lens::
|
float Lens::
|
||||||
get_iod_offset() const {
|
get_interocular_distance() const {
|
||||||
if ((_comp_flags & CF_iod_offset) == 0) {
|
return _interocular_distance;
|
||||||
((Lens *)this)->compute_iod_offset();
|
|
||||||
}
|
}
|
||||||
return _iod_offset;
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Lens::set_convergence_distance
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the distance between the left and right eyes of
|
||||||
|
// a stereo camera. This distance is used to apply a
|
||||||
|
// stereo effect when the lens is rendered on a stereo
|
||||||
|
// display region. It only has an effect on a
|
||||||
|
// PerspectiveLens.
|
||||||
|
//
|
||||||
|
// Also see set_interocular_distance(), which relates.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Lens::
|
||||||
|
set_convergence_distance(float convergence_distance) {
|
||||||
|
_convergence_distance = convergence_distance;
|
||||||
|
if (_convergence_distance == 0.0f) {
|
||||||
|
adjust_user_flags(UF_convergence_distance, 0);
|
||||||
|
} else {
|
||||||
|
adjust_user_flags(0, UF_convergence_distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
adjust_comp_flags(CF_mat, 0);
|
||||||
|
throw_change_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Lens::get_convergence_distance
|
||||||
|
// Access: Published
|
||||||
|
// Description: See set_convergence_distance().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
float Lens::
|
||||||
|
get_convergence_distance() const {
|
||||||
|
return _convergence_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -549,7 +589,7 @@ get_iod_offset() const {
|
|||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Sets an arbitrary transformation on the lens. This
|
// Description: Sets an arbitrary transformation on the lens. This
|
||||||
// replaces the individual transformation components
|
// replaces the individual transformation components
|
||||||
// like set_view_hpr() or set_iod_offset().
|
// like set_view_hpr().
|
||||||
//
|
//
|
||||||
// Setting a transformation here will have a slightly
|
// Setting a transformation here will have a slightly
|
||||||
// different effect than putting one on the LensNode
|
// different effect than putting one on the LensNode
|
||||||
@ -562,9 +602,11 @@ get_iod_offset() const {
|
|||||||
void Lens::
|
void Lens::
|
||||||
set_view_mat(const LMatrix4f &view_mat) {
|
set_view_mat(const LMatrix4f &view_mat) {
|
||||||
_lens_mat = view_mat;
|
_lens_mat = view_mat;
|
||||||
adjust_user_flags(UF_view_vector | UF_view_hpr | UF_iod_offset,
|
adjust_user_flags(UF_view_vector | UF_view_hpr,
|
||||||
UF_view_mat);
|
UF_view_mat);
|
||||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_lens_mat_inv | CF_view_hpr | CF_view_vector | CF_iod_offset,
|
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||||
|
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||||
|
CF_lens_mat_inv | CF_view_hpr | CF_view_vector,
|
||||||
CF_lens_mat);
|
CF_lens_mat);
|
||||||
throw_change_event();
|
throw_change_event();
|
||||||
}
|
}
|
||||||
@ -590,8 +632,10 @@ get_view_mat() const {
|
|||||||
void Lens::
|
void Lens::
|
||||||
clear_view_mat() {
|
clear_view_mat() {
|
||||||
_lens_mat = LMatrix4f::ident_mat();
|
_lens_mat = LMatrix4f::ident_mat();
|
||||||
adjust_user_flags(0, UF_view_vector | UF_view_hpr | UF_iod_offset | UF_view_mat);
|
adjust_user_flags(0, UF_view_vector | UF_view_hpr | UF_view_mat);
|
||||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_lens_mat_inv | CF_view_hpr | CF_view_vector | CF_iod_offset,
|
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||||
|
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||||
|
CF_lens_mat_inv | CF_view_hpr | CF_view_vector,
|
||||||
CF_lens_mat);
|
CF_lens_mat);
|
||||||
throw_change_event();
|
throw_change_event();
|
||||||
}
|
}
|
||||||
@ -617,7 +661,9 @@ void Lens::
|
|||||||
set_keystone(const LVecBase2f &keystone) {
|
set_keystone(const LVecBase2f &keystone) {
|
||||||
_keystone = keystone;
|
_keystone = keystone;
|
||||||
adjust_user_flags(0, UF_keystone);
|
adjust_user_flags(0, UF_keystone);
|
||||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0);
|
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||||
|
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||||
|
CF_film_mat | CF_film_mat_inv, 0);
|
||||||
throw_change_event();
|
throw_change_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,7 +676,9 @@ void Lens::
|
|||||||
clear_keystone() {
|
clear_keystone() {
|
||||||
_keystone.set(0.0f, 0.0f);
|
_keystone.set(0.0f, 0.0f);
|
||||||
adjust_user_flags(UF_keystone, 0);
|
adjust_user_flags(UF_keystone, 0);
|
||||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0);
|
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||||
|
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||||
|
CF_film_mat | CF_film_mat_inv, 0);
|
||||||
throw_change_event();
|
throw_change_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,9 +690,9 @@ clear_keystone() {
|
|||||||
// PerspectiveLens, but it may be called for other kinds
|
// PerspectiveLens, but it may be called for other kinds
|
||||||
// of lenses as well.
|
// of lenses as well.
|
||||||
//
|
//
|
||||||
// The frustum will be rooted at the origin (or offset
|
// The frustum will be rooted at the origin (or by
|
||||||
// by iod_offset, or by whatever translation might have
|
// whatever translation might have been specified in a
|
||||||
// been specified in a previous call to set_view_mat).
|
// previous call to set_view_mat).
|
||||||
//
|
//
|
||||||
// It is legal for the four points not to be arranged in
|
// It is legal for the four points not to be arranged in
|
||||||
// a rectangle; if this is the case, the frustum will be
|
// a rectangle; if this is the case, the frustum will be
|
||||||
@ -699,8 +747,7 @@ set_frustum_from_corners(const LVecBase3f &ul, const LVecBase3f &ur,
|
|||||||
int flags) {
|
int flags) {
|
||||||
// We'll need to know the pre-existing eyepoint translation from the
|
// We'll need to know the pre-existing eyepoint translation from the
|
||||||
// center, so we can preserve it in the new frustum. This is
|
// center, so we can preserve it in the new frustum. This is
|
||||||
// usually just a shift along the x axis, if anything at all, for
|
// usually (0, 0, 0), but it could be an arbitrary vector.
|
||||||
// the iod offset, but it could be an arbitrary vector.
|
|
||||||
const LMatrix4f &lens_mat_inv = get_lens_mat_inv();
|
const LMatrix4f &lens_mat_inv = get_lens_mat_inv();
|
||||||
LVector3f eye_offset;
|
LVector3f eye_offset;
|
||||||
lens_mat_inv.get_row3(eye_offset, 3);
|
lens_mat_inv.get_row3(eye_offset, 3);
|
||||||
@ -1018,22 +1065,59 @@ make_bounds() const {
|
|||||||
// nonlinear.
|
// nonlinear.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
const LMatrix4f &Lens::
|
const LMatrix4f &Lens::
|
||||||
get_projection_mat() const {
|
get_projection_mat(StereoChannel channel) const {
|
||||||
if ((_comp_flags & CF_projection_mat) == 0) {
|
if ((_comp_flags & CF_projection_mat) == 0) {
|
||||||
((Lens *)this)->compute_projection_mat();
|
((Lens *)this)->compute_projection_mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (channel) {
|
||||||
|
case SC_left:
|
||||||
|
return _projection_mat_left;
|
||||||
|
case SC_right:
|
||||||
|
return _projection_mat_right;
|
||||||
|
case SC_both:
|
||||||
|
return _projection_mat;
|
||||||
|
}
|
||||||
|
|
||||||
return _projection_mat;
|
return _projection_mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Lens::get_projection_mat_inv
|
// Function: Lens::get_projection_mat_inv
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns the matrix that transforms from a 2-d point
|
// Description: Returns the matrix that transforms from a 2-d point
|
||||||
// on the film to a 3-d vector in space, if such a
|
// on the film to a 3-d vector in space, if such a
|
||||||
// matrix exists.
|
// matrix exists.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
const LMatrix4f &Lens::
|
const LMatrix4f &Lens::
|
||||||
get_projection_mat_inv() const {
|
get_projection_mat_inv(StereoChannel stereo_channel) const {
|
||||||
|
switch (stereo_channel) {
|
||||||
|
case SC_left:
|
||||||
|
{
|
||||||
|
if ((_comp_flags & CF_projection_mat_left_inv) == 0) {
|
||||||
|
Lens *non_const = (Lens *)this;
|
||||||
|
const LMatrix4f &projection_mat_left = get_projection_mat(SC_left);
|
||||||
|
non_const->_projection_mat_left_inv.invert_from(projection_mat_left);
|
||||||
|
non_const->adjust_comp_flags(0, CF_projection_mat_left_inv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _projection_mat_left_inv;
|
||||||
|
|
||||||
|
case SC_right:
|
||||||
|
{
|
||||||
|
if ((_comp_flags & CF_projection_mat_right_inv) == 0) {
|
||||||
|
Lens *non_const = (Lens *)this;
|
||||||
|
const LMatrix4f &projection_mat_right = get_projection_mat(SC_right);
|
||||||
|
non_const->_projection_mat_right_inv.invert_from(projection_mat_right);
|
||||||
|
non_const->adjust_comp_flags(0, CF_projection_mat_right_inv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _projection_mat_right_inv;
|
||||||
|
|
||||||
|
case SC_both:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((_comp_flags & CF_projection_mat_inv) == 0) {
|
if ((_comp_flags & CF_projection_mat_inv) == 0) {
|
||||||
Lens *non_const = (Lens *)this;
|
Lens *non_const = (Lens *)this;
|
||||||
const LMatrix4f &projection_mat = get_projection_mat();
|
const LMatrix4f &projection_mat = get_projection_mat();
|
||||||
@ -1043,6 +1127,68 @@ get_projection_mat_inv() const {
|
|||||||
return _projection_mat_inv;
|
return _projection_mat_inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Lens::get_film_mat
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the matrix that transforms from a point
|
||||||
|
// behind the lens to a point on the film.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const LMatrix4f &Lens::
|
||||||
|
get_film_mat() const {
|
||||||
|
if ((_comp_flags & CF_film_mat) == 0) {
|
||||||
|
((Lens *)this)->compute_film_mat();
|
||||||
|
}
|
||||||
|
return _film_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Lens::get_film_mat_inv
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the matrix that transforms from a point on
|
||||||
|
// the film to a point behind the lens.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const LMatrix4f &Lens::
|
||||||
|
get_film_mat_inv() const {
|
||||||
|
if ((_comp_flags & CF_film_mat_inv) == 0) {
|
||||||
|
Lens *non_const = (Lens *)this;
|
||||||
|
const LMatrix4f &film_mat = get_film_mat();
|
||||||
|
non_const->_film_mat_inv.invert_from(film_mat);
|
||||||
|
non_const->adjust_comp_flags(0, CF_film_mat_inv);
|
||||||
|
}
|
||||||
|
return _film_mat_inv;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Lens::get_lens_mat
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the matrix that transforms from a point
|
||||||
|
// in front of the lens to a point in space.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const LMatrix4f &Lens::
|
||||||
|
get_lens_mat() const {
|
||||||
|
if ((_comp_flags & CF_lens_mat) == 0) {
|
||||||
|
((Lens *)this)->compute_lens_mat();
|
||||||
|
}
|
||||||
|
return _lens_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Lens::get_lens_mat_inv
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the matrix that transforms from a point in
|
||||||
|
// space to a point in front of the lens.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const LMatrix4f &Lens::
|
||||||
|
get_lens_mat_inv() const {
|
||||||
|
if ((_comp_flags & CF_lens_mat_inv) == 0) {
|
||||||
|
Lens *non_const = (Lens *)this;
|
||||||
|
const LMatrix4f &lens_mat = get_lens_mat();
|
||||||
|
non_const->_lens_mat_inv.invert_from(lens_mat);
|
||||||
|
non_const->adjust_comp_flags(0, CF_lens_mat_inv);
|
||||||
|
}
|
||||||
|
return _lens_mat_inv;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Lens::output
|
// Function: Lens::output
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
@ -1091,68 +1237,6 @@ throw_change_event() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Lens::get_film_mat
|
|
||||||
// Access: Protected
|
|
||||||
// Description: Returns the matrix that transforms from a point
|
|
||||||
// behind the lens to a point on the film.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
const LMatrix4f &Lens::
|
|
||||||
get_film_mat() const {
|
|
||||||
if ((_comp_flags & CF_film_mat) == 0) {
|
|
||||||
((Lens *)this)->compute_film_mat();
|
|
||||||
}
|
|
||||||
return _film_mat;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Lens::get_film_mat_inv
|
|
||||||
// Access: Protected
|
|
||||||
// Description: Returns the matrix that transforms from a point on
|
|
||||||
// the film to a point behind the lens.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
const LMatrix4f &Lens::
|
|
||||||
get_film_mat_inv() const {
|
|
||||||
if ((_comp_flags & CF_film_mat_inv) == 0) {
|
|
||||||
Lens *non_const = (Lens *)this;
|
|
||||||
const LMatrix4f &film_mat = get_film_mat();
|
|
||||||
non_const->_film_mat_inv.invert_from(film_mat);
|
|
||||||
non_const->adjust_comp_flags(0, CF_film_mat_inv);
|
|
||||||
}
|
|
||||||
return _film_mat_inv;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Lens::get_lens_mat
|
|
||||||
// Access: Protected
|
|
||||||
// Description: Returns the matrix that transforms from a point
|
|
||||||
// in front of the lens to a point in space.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
const LMatrix4f &Lens::
|
|
||||||
get_lens_mat() const {
|
|
||||||
if ((_comp_flags & CF_lens_mat) == 0) {
|
|
||||||
((Lens *)this)->compute_lens_mat();
|
|
||||||
}
|
|
||||||
return _lens_mat;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Lens::get_lens_mat_inv
|
|
||||||
// Access: Protected
|
|
||||||
// Description: Returns the matrix that transforms from a point in
|
|
||||||
// space to a point in front of the lens.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
const LMatrix4f &Lens::
|
|
||||||
get_lens_mat_inv() const {
|
|
||||||
if ((_comp_flags & CF_lens_mat_inv) == 0) {
|
|
||||||
Lens *non_const = (Lens *)this;
|
|
||||||
const LMatrix4f &lens_mat = get_lens_mat();
|
|
||||||
non_const->_lens_mat_inv.invert_from(lens_mat);
|
|
||||||
non_const->adjust_comp_flags(0, CF_lens_mat_inv);
|
|
||||||
}
|
|
||||||
return _lens_mat_inv;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Lens::extrude_impl
|
// Function: Lens::extrude_impl
|
||||||
// Access: Protected, Virtual
|
// Access: Protected, Virtual
|
||||||
@ -1411,23 +1495,6 @@ compute_view_vector() {
|
|||||||
adjust_comp_flags(0, CF_view_vector);
|
adjust_comp_flags(0, CF_view_vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Lens::compute_iod_offset
|
|
||||||
// Access: Protected, Virtual
|
|
||||||
// Description: Computes the IOD offset: the translation along the
|
|
||||||
// "right" axis.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void Lens::
|
|
||||||
compute_iod_offset() {
|
|
||||||
if ((_user_flags & UF_iod_offset) == 0) {
|
|
||||||
const LMatrix4f &lens_mat_inv = get_lens_mat_inv();
|
|
||||||
LVector3f translate;
|
|
||||||
lens_mat_inv.get_row3(translate, 3);
|
|
||||||
_iod_offset = -translate.dot(LVector3f::right(_cs));
|
|
||||||
}
|
|
||||||
adjust_comp_flags(0, CF_iod_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Lens::compute_projection_mat
|
// Function: Lens::compute_projection_mat
|
||||||
// Access: Protected, Virtual
|
// Access: Protected, Virtual
|
||||||
@ -1436,9 +1503,15 @@ compute_iod_offset() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void Lens::
|
void Lens::
|
||||||
compute_projection_mat() {
|
compute_projection_mat() {
|
||||||
_projection_mat = LMatrix4f::ident_mat();
|
_projection_mat =
|
||||||
_projection_mat_inv = _projection_mat;
|
_projection_mat_left =
|
||||||
adjust_comp_flags(0, CF_projection_mat | CF_projection_mat_inv);
|
_projection_mat_right =
|
||||||
|
_projection_mat_inv =
|
||||||
|
_projection_mat_left_inv =
|
||||||
|
_projection_mat_right_inv =
|
||||||
|
LMatrix4f::ident_mat();
|
||||||
|
adjust_comp_flags(0, CF_projection_mat | CF_projection_mat_inv |
|
||||||
|
CF_projection_mat_left_inv |CF_projection_mat_right_inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1498,11 +1571,6 @@ compute_lens_mat() {
|
|||||||
} else {
|
} else {
|
||||||
_lens_mat = LMatrix4f::ident_mat();
|
_lens_mat = LMatrix4f::ident_mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_user_flags & UF_iod_offset) != 0) {
|
|
||||||
LVector3f iod_vector = _iod_offset * LVector3f::right(_cs);
|
|
||||||
_lens_mat = LMatrix4f::translate_mat(iod_vector) * _lens_mat;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
adjust_comp_flags(CF_lens_mat_inv,
|
adjust_comp_flags(CF_lens_mat_inv,
|
||||||
CF_lens_mat);
|
CF_lens_mat);
|
||||||
|
@ -49,6 +49,12 @@ public:
|
|||||||
void operator = (const Lens ©);
|
void operator = (const Lens ©);
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
|
enum StereoChannel {
|
||||||
|
SC_left = 0x01,
|
||||||
|
SC_right = 0x02,
|
||||||
|
SC_both = 0x03, // == SC_left | SC_right
|
||||||
|
};
|
||||||
|
|
||||||
virtual PT(Lens) make_copy() const=0;
|
virtual PT(Lens) make_copy() const=0;
|
||||||
|
|
||||||
INLINE bool extrude(const LPoint2f &point2d,
|
INLINE bool extrude(const LPoint2f &point2d,
|
||||||
@ -107,8 +113,11 @@ PUBLISHED:
|
|||||||
const LVector3f &get_view_vector() const;
|
const LVector3f &get_view_vector() const;
|
||||||
const LVector3f &get_up_vector() const;
|
const LVector3f &get_up_vector() const;
|
||||||
LPoint3f get_nodal_point() const;
|
LPoint3f get_nodal_point() const;
|
||||||
void set_iod_offset(float offset);
|
|
||||||
float get_iod_offset() const;
|
void set_interocular_distance(float interocular_distance);
|
||||||
|
float get_interocular_distance() const;
|
||||||
|
void set_convergence_distance(float convergence_distance);
|
||||||
|
float get_convergence_distance() const;
|
||||||
|
|
||||||
void set_view_mat(const LMatrix4f &view_mat);
|
void set_view_mat(const LMatrix4f &view_mat);
|
||||||
const LMatrix4f &get_view_mat() const;
|
const LMatrix4f &get_view_mat() const;
|
||||||
@ -142,8 +151,14 @@ PUBLISHED:
|
|||||||
|
|
||||||
virtual PT(BoundingVolume) make_bounds() const;
|
virtual PT(BoundingVolume) make_bounds() const;
|
||||||
|
|
||||||
const LMatrix4f &get_projection_mat() const;
|
const LMatrix4f &get_projection_mat(StereoChannel channel = SC_both) const;
|
||||||
const LMatrix4f &get_projection_mat_inv() const;
|
const LMatrix4f &get_projection_mat_inv(StereoChannel channel = SC_both) const;
|
||||||
|
|
||||||
|
const LMatrix4f &get_film_mat() const;
|
||||||
|
const LMatrix4f &get_film_mat_inv() const;
|
||||||
|
|
||||||
|
const LMatrix4f &get_lens_mat() const;
|
||||||
|
const LMatrix4f &get_lens_mat_inv() const;
|
||||||
|
|
||||||
virtual void output(ostream &out) const;
|
virtual void output(ostream &out) const;
|
||||||
virtual void write(ostream &out, int indent_level = 0) const;
|
virtual void write(ostream &out, int indent_level = 0) const;
|
||||||
@ -157,12 +172,6 @@ protected:
|
|||||||
|
|
||||||
void throw_change_event();
|
void throw_change_event();
|
||||||
|
|
||||||
const LMatrix4f &get_film_mat() const;
|
|
||||||
const LMatrix4f &get_film_mat_inv() const;
|
|
||||||
|
|
||||||
const LMatrix4f &get_lens_mat() const;
|
|
||||||
const LMatrix4f &get_lens_mat_inv() const;
|
|
||||||
|
|
||||||
virtual bool extrude_impl(const LPoint3f &point2d,
|
virtual bool extrude_impl(const LPoint3f &point2d,
|
||||||
LPoint3f &near_point, LPoint3f &far_point) const;
|
LPoint3f &near_point, LPoint3f &far_point) const;
|
||||||
virtual bool extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const;
|
virtual bool extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const;
|
||||||
@ -174,7 +183,6 @@ protected:
|
|||||||
virtual void compute_aspect_ratio();
|
virtual void compute_aspect_ratio();
|
||||||
virtual void compute_view_hpr();
|
virtual void compute_view_hpr();
|
||||||
virtual void compute_view_vector();
|
virtual void compute_view_vector();
|
||||||
virtual void compute_iod_offset();
|
|
||||||
virtual void compute_projection_mat();
|
virtual void compute_projection_mat();
|
||||||
virtual void compute_film_mat();
|
virtual void compute_film_mat();
|
||||||
virtual void compute_lens_mat();
|
virtual void compute_lens_mat();
|
||||||
@ -206,12 +214,15 @@ protected:
|
|||||||
|
|
||||||
LVecBase3f _view_hpr;
|
LVecBase3f _view_hpr;
|
||||||
LVector3f _view_vector, _up_vector;
|
LVector3f _view_vector, _up_vector;
|
||||||
float _iod_offset;
|
float _interocular_distance;
|
||||||
|
float _convergence_distance;
|
||||||
LVecBase2f _keystone;
|
LVecBase2f _keystone;
|
||||||
|
|
||||||
LMatrix4f _film_mat, _film_mat_inv;
|
LMatrix4f _film_mat, _film_mat_inv;
|
||||||
LMatrix4f _lens_mat, _lens_mat_inv;
|
LMatrix4f _lens_mat, _lens_mat_inv;
|
||||||
LMatrix4f _projection_mat, _projection_mat_inv;
|
LMatrix4f _projection_mat, _projection_mat_inv;
|
||||||
|
LMatrix4f _projection_mat_left, _projection_mat_left_inv;
|
||||||
|
LMatrix4f _projection_mat_right, _projection_mat_right_inv;
|
||||||
|
|
||||||
enum UserFlags {
|
enum UserFlags {
|
||||||
// Parameters the user may have explicitly specified.
|
// Parameters the user may have explicitly specified.
|
||||||
@ -223,9 +234,10 @@ protected:
|
|||||||
UF_aspect_ratio = 0x0020,
|
UF_aspect_ratio = 0x0020,
|
||||||
UF_view_hpr = 0x0040,
|
UF_view_hpr = 0x0040,
|
||||||
UF_view_vector = 0x0080,
|
UF_view_vector = 0x0080,
|
||||||
UF_iod_offset = 0x0100,
|
UF_interocular_distance = 0x0100,
|
||||||
UF_view_mat = 0x0200,
|
UF_convergence_distance = 0x0200,
|
||||||
UF_keystone = 0x0400,
|
UF_view_mat = 0x0400,
|
||||||
|
UF_keystone = 0x0800,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CompFlags {
|
enum CompFlags {
|
||||||
@ -236,15 +248,16 @@ protected:
|
|||||||
CF_lens_mat_inv = 0x0008,
|
CF_lens_mat_inv = 0x0008,
|
||||||
CF_projection_mat = 0x0010,
|
CF_projection_mat = 0x0010,
|
||||||
CF_projection_mat_inv = 0x0020,
|
CF_projection_mat_inv = 0x0020,
|
||||||
CF_mat = 0x003f, // all of the above.
|
CF_projection_mat_left_inv = 0x0040,
|
||||||
|
CF_projection_mat_right_inv = 0x0080,
|
||||||
|
CF_mat = 0x00ff, // all of the above.
|
||||||
|
|
||||||
CF_focal_length = 0x0040,
|
|
||||||
CF_fov = 0x0080,
|
|
||||||
CF_film_size = 0x0100,
|
CF_film_size = 0x0100,
|
||||||
CF_aspect_ratio = 0x0200,
|
CF_aspect_ratio = 0x0200,
|
||||||
CF_view_hpr = 0x0400,
|
CF_view_hpr = 0x0400,
|
||||||
CF_view_vector = 0x0800,
|
CF_view_vector = 0x0800,
|
||||||
CF_iod_offset = 0x1000,
|
CF_focal_length = 0x1000,
|
||||||
|
CF_fov = 0x2000,
|
||||||
};
|
};
|
||||||
short _user_flags;
|
short _user_flags;
|
||||||
short _comp_flags;
|
short _comp_flags;
|
||||||
|
@ -119,9 +119,11 @@ compute_projection_mat() {
|
|||||||
canonical = LMatrix4f::ident_mat();
|
canonical = LMatrix4f::ident_mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_projection_mat = get_lens_mat_inv() * canonical * get_film_mat();
|
_projection_mat = get_lens_mat_inv() * canonical * get_film_mat();
|
||||||
adjust_comp_flags(CF_projection_mat_inv,
|
_projection_mat_left = _projection_mat_right = _projection_mat;
|
||||||
|
|
||||||
|
adjust_comp_flags(CF_projection_mat_inv | CF_projection_mat_left_inv |
|
||||||
|
CF_projection_mat_right_inv,
|
||||||
CF_projection_mat);
|
CF_projection_mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,9 +115,29 @@ compute_projection_mat() {
|
|||||||
canonical = LMatrix4f::ident_mat();
|
canonical = LMatrix4f::ident_mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_projection_mat = get_lens_mat_inv() * canonical * get_film_mat();
|
_projection_mat = get_lens_mat_inv() * canonical * get_film_mat();
|
||||||
adjust_comp_flags(CF_projection_mat_inv,
|
|
||||||
|
if ((_user_flags & UF_interocular_distance) == 0) {
|
||||||
|
_projection_mat_left = _projection_mat_right = _projection_mat;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Compute the left and right projection matrices in case this
|
||||||
|
// lens is assigned to a stereo DisplayRegion.
|
||||||
|
|
||||||
|
LVector3f iod = _interocular_distance * 0.5f * LVector3f::left(_cs);
|
||||||
|
_projection_mat_left = get_lens_mat_inv() * LMatrix4f::translate_mat(-iod) * canonical * get_film_mat();
|
||||||
|
_projection_mat_right = get_lens_mat_inv() * LMatrix4f::translate_mat(iod) * canonical * get_film_mat();
|
||||||
|
|
||||||
|
if (_user_flags & UF_convergence_distance) {
|
||||||
|
nassertv(_convergence_distance != 0.0f);
|
||||||
|
LVector3f cd = (0.25f / _convergence_distance) * LVector3f::left(_cs);
|
||||||
|
_projection_mat_left *= LMatrix4f::translate_mat(cd);
|
||||||
|
_projection_mat_right *= LMatrix4f::translate_mat(-cd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adjust_comp_flags(CF_projection_mat_inv | CF_projection_mat_left_inv |
|
||||||
|
CF_projection_mat_right_inv,
|
||||||
CF_projection_mat);
|
CF_projection_mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user