From b7a51b133ea86e20b34ce87601083efd4974b7f0 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 7 Feb 2012 19:16:27 +0000 Subject: [PATCH] GraphicsOutput::set_swap_eyes(), PfmFile::set_flat_texcoord_name() --- panda/src/display/config_display.cxx | 5 +++ panda/src/display/config_display.h | 1 + panda/src/display/displayRegion.I | 2 +- panda/src/display/displayRegion.h | 2 +- panda/src/display/graphicsOutput.I | 27 ++++++++++++++ panda/src/display/graphicsOutput.cxx | 19 ++++++---- panda/src/display/graphicsOutput.h | 4 +++ panda/src/display/graphicsStateGuardian.cxx | 19 +++++++++- panda/src/grutil/pfmFile.I | 39 +++++++++++++++++++++ panda/src/grutil/pfmFile.cxx | 35 +++++++++++++----- panda/src/grutil/pfmFile.h | 5 +++ 11 files changed, 140 insertions(+), 18 deletions(-) diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index de49ef3633..68986ca5ed 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -246,6 +246,11 @@ ConfigVariableDouble sbs_right_dimensions "four numbers, in the form left right top bottom, similar to a " "normal DisplayRegion layout.")); +ConfigVariableBool swap_eyes +("swap-eyes", false, + PRC_DESC("Set this true to reverse the left and right channel output of " + "stereo DisplayRegions.")); + ConfigVariableBool default_stereo_camera ("default-stereo-camera", true, PRC_DESC("When this is true, the default DisplayRegion created for " diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index ddaad07b57..fa3c372cda 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -62,6 +62,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableString red_blue_stereo_colors; extern EXPCL_PANDA_DISPLAY ConfigVariableBool side_by_side_stereo; extern EXPCL_PANDA_DISPLAY ConfigVariableDouble sbs_left_dimensions; extern EXPCL_PANDA_DISPLAY ConfigVariableDouble sbs_right_dimensions; +extern EXPCL_PANDA_DISPLAY ConfigVariableBool swap_eyes; extern EXPCL_PANDA_DISPLAY ConfigVariableBool default_stereo_camera; extern EXPCL_PANDA_DISPLAY ConfigVariableBool color_scale_via_lighting; extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture; diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 44fef67e9c..0ed2a2dcbb 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -753,7 +753,7 @@ get_sort() const { // set_stereo_channel(). //////////////////////////////////////////////////////////////////// INLINE Lens::StereoChannel DisplayRegionPipelineReader:: -get_stereo_channel() { +get_stereo_channel() const { return _cdata->_stereo_channel; } diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 421116dcd6..9c1b7ef837 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -305,7 +305,7 @@ public: INLINE NodePath get_camera() const; INLINE bool is_active() const; INLINE int get_sort() const; - INLINE Lens::StereoChannel get_stereo_channel(); + INLINE Lens::StereoChannel get_stereo_channel() const; INLINE int get_tex_view_offset(); INLINE bool get_clear_depth_between_eyes() const; INLINE int get_cube_map_index() const; diff --git a/panda/src/display/graphicsOutput.I b/panda/src/display/graphicsOutput.I index 19e52ef7f2..31545d99f9 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -324,6 +324,33 @@ get_inverted() const { return _inverted; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::set_swap_eyes +// Access: Public +// Description: Changes the "swap eyes" flag. This flag is normally +// false. When it is true, the left and right channels +// of a stereo DisplayRegion are sent to the opposite +// channels in the rendering backend. This is meant to +// work around hardware that inadvertently swaps the +// output channels, or hardware for which it cannot be +// determined which channel is which until runtime. +//////////////////////////////////////////////////////////////////// +INLINE void GraphicsOutput:: +set_swap_eyes(bool swap_eyes) { + _swap_eyes = swap_eyes; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::get_swap_eyes +// Access: Public +// Description: Returns the current setting of the "swap eyes" flag. +// See set_swap_eyes(). +//////////////////////////////////////////////////////////////////// +INLINE bool GraphicsOutput:: +get_swap_eyes() const { + return _swap_eyes; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::set_red_blue_stereo // Access: Published diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index d9d1a588c6..1a6de4216e 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -107,6 +107,7 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe, _got_child_sort = false; _internal_sort_index = 0; _inverted = window_inverted; + _swap_eyes = swap_eyes; _red_blue_stereo = false; _left_eye_color_mask = 0x0f; _right_eye_color_mask = 0x0f; @@ -698,9 +699,9 @@ make_stereo_display_region(const LVecBase4 &dimensions) { PN_stdfloat left_w = _sbs_left_dimensions[1] - _sbs_left_dimensions[0]; PN_stdfloat left_h = _sbs_left_dimensions[3] - _sbs_left_dimensions[2]; LVecBase4 left_dimensions(dimensions[0] * left_w + left_l, - dimensions[1] * left_w + left_l, - dimensions[2] * left_h + left_b, - dimensions[3] * left_h + left_b); + dimensions[1] * left_w + left_l, + dimensions[2] * left_h + left_b, + dimensions[3] * left_h + left_b); left = new DisplayRegion(this, left_dimensions); PN_stdfloat right_l = _sbs_right_dimensions[0]; @@ -708,11 +709,17 @@ make_stereo_display_region(const LVecBase4 &dimensions) { PN_stdfloat right_w = _sbs_right_dimensions[1] - _sbs_right_dimensions[0]; PN_stdfloat right_h = _sbs_right_dimensions[3] - _sbs_right_dimensions[2]; LVecBase4 right_dimensions(dimensions[0] * right_w + right_l, - dimensions[1] * right_w + right_l, - dimensions[2] * right_h + right_b, - dimensions[3] * right_h + right_b); + dimensions[1] * right_w + right_l, + dimensions[2] * right_h + right_b, + dimensions[3] * right_h + right_b); right = new DisplayRegion(this, right_dimensions); + if (_swap_eyes) { + DisplayRegion *t = left; + left = right; + right = t; + } + } else { // Not a side-by-side stereo window; thus, both the left and right // eyes are the same region: the region specified. diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 31120aaf54..8f4f7d0433 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -134,6 +134,9 @@ PUBLISHED: void set_inverted(bool inverted); INLINE bool get_inverted() const; + INLINE void set_swap_eyes(bool swap_eyes); + INLINE bool get_swap_eyes() const; + INLINE void set_red_blue_stereo(bool red_blue_stereo, unsigned int left_eye_color_mask, unsigned int right_eye_color_mask); @@ -305,6 +308,7 @@ private: protected: bool _inverted; + bool _swap_eyes; bool _red_blue_stereo; unsigned int _left_eye_color_mask; unsigned int _right_eye_color_mask; diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 28b7216bc7..35ad920432 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1318,7 +1318,24 @@ prepare_display_region(DisplayRegionPipelineReader *dr) { _stereo_buffer_mask = ~0; - switch (dr->get_stereo_channel()) { + Lens::StereoChannel output_channel = dr->get_stereo_channel(); + if (dr->get_window()->get_swap_eyes()) { + // Reverse the output channel. + switch (output_channel) { + case Lens::SC_left: + output_channel = Lens::SC_right; + break; + + case Lens::SC_right: + output_channel = Lens::SC_left; + break; + + default: + break; + } + } + + switch (output_channel) { case Lens::SC_left: _color_write_mask = dr->get_window()->get_left_eye_color_mask(); if (_current_properties->is_stereo()) { diff --git a/panda/src/grutil/pfmFile.I b/panda/src/grutil/pfmFile.I index 42f2b48621..22a6b3dffc 100755 --- a/panda/src/grutil/pfmFile.I +++ b/panda/src/grutil/pfmFile.I @@ -182,6 +182,45 @@ get_vis_inverse() const { return _vis_inverse; } +//////////////////////////////////////////////////////////////////// +// Function: PfmFile::set_flat_texcoord_name +// Access: Published +// Description: If the flat_texcoord_name is specified, it is the +// name of an additional vertex column that will be +// created for the "flat" texture coordinates, i.e. the +// original 0..1 values that correspond to the 2-D index +// position of each point in the original pfm file. +// +// These are the same values that will be assigned to +// the default texture coordinates if the vis_inverse +// flag is *not* true. +//////////////////////////////////////////////////////////////////// +INLINE void PfmFile:: +set_flat_texcoord_name(InternalName *flat_texcoord_name) { + _flat_texcoord_name = flat_texcoord_name; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmFile::clear_flat_texcoord_name +// Access: Published +// Description: Resets the flat_texcoord_name to empty, so that +// additional texture coordinates are not created. +//////////////////////////////////////////////////////////////////// +INLINE void PfmFile:: +clear_flat_texcoord_name() { + _flat_texcoord_name = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PfmFile::get_flat_texcoord_name +// Access: Published +// Description: Returns the flat_texcoord_name. See set_flat_texcoord_name(). +//////////////////////////////////////////////////////////////////// +INLINE InternalName *PfmFile:: +get_flat_texcoord_name() const { + return _flat_texcoord_name; +} + //////////////////////////////////////////////////////////////////// // Function: PfmFile::set_vis_2d // Access: Published diff --git a/panda/src/grutil/pfmFile.cxx b/panda/src/grutil/pfmFile.cxx index 3f8031b625..2d5855e5cd 100755 --- a/panda/src/grutil/pfmFile.cxx +++ b/panda/src/grutil/pfmFile.cxx @@ -840,27 +840,39 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const { << " pieces.\n"; } - CPT(GeomVertexFormat) format; + PT(GeomVertexArrayFormat) array_format; + if (_vis_2d) { // No normals needed if we're just generating a 2-d mesh. - format = GeomVertexFormat::get_v3t2(); + array_format = new GeomVertexArrayFormat + (InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point, + InternalName::get_texcoord(), 2, Geom::NT_stdfloat, Geom::C_texcoord); + } else { if (_vis_inverse) { // We need a 3-d texture coordinate if we're inverting the vis // and it's 3-d. But we still don't need normals in that case. - GeomVertexArrayFormat *v3t3 = new GeomVertexArrayFormat - (InternalName::get_vertex(), 3, - Geom::NT_stdfloat, Geom::C_point, - InternalName::get_texcoord(), 3, - Geom::NT_stdfloat, Geom::C_texcoord); - format = GeomVertexFormat::register_format(v3t3); + array_format = new GeomVertexArrayFormat + (InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point, + InternalName::get_texcoord(), 3, Geom::NT_stdfloat, Geom::C_texcoord); } else { // Otherwise, we only need a 2-d texture coordinate, and we do // want normals. - format = GeomVertexFormat::get_v3n3t2(); + array_format = new GeomVertexArrayFormat + (InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point, + InternalName::get_normal(), 3, Geom::NT_stdfloat, Geom::C_vector, + InternalName::get_texcoord(), 2, Geom::NT_stdfloat, Geom::C_texcoord); } } + if (_flat_texcoord_name != (InternalName *)NULL) { + // We need an additional texcoord column for the flat texcoords. + array_format->add_column(_flat_texcoord_name, 2, + Geom::NT_stdfloat, Geom::C_texcoord); + } + + CPT(GeomVertexFormat) format = GeomVertexFormat::register_format(array_format); + for (int yci = 0; yci < num_y_cells; ++yci) { int y_begin = (yci * _y_size) / num_y_cells; int y_end = ((yci + 1) * _y_size) / num_y_cells; @@ -895,6 +907,7 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const { GeomVertexWriter vertex(vdata, InternalName::get_vertex()); GeomVertexWriter normal(vdata, InternalName::get_normal()); GeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); + GeomVertexWriter texcoord2(vdata, _flat_texcoord_name); for (int yi = y_begin; yi < y_end; ++yi) { for (int xi = x_begin; xi < x_end; ++xi) { @@ -944,6 +957,10 @@ make_vis_mesh_geom(GeomNode *gnode, bool inverted) const { } normal.add_data3(n); } + + if (_flat_texcoord_name != (InternalName *)NULL) { + texcoord2.add_data2(uv); + } } } diff --git a/panda/src/grutil/pfmFile.h b/panda/src/grutil/pfmFile.h index a1d4bbc4c7..6c68b91698 100755 --- a/panda/src/grutil/pfmFile.h +++ b/panda/src/grutil/pfmFile.h @@ -19,6 +19,7 @@ #include "luse.h" #include "nodePath.h" #include "boundingHexahedron.h" +#include "internalName.h" class GeomNode; class Lens; @@ -70,6 +71,9 @@ PUBLISHED: INLINE void set_vis_inverse(bool vis_inverse); INLINE bool get_vis_inverse() const; + INLINE void set_flat_texcoord_name(InternalName *flat_texcoord_name); + INLINE void clear_flat_texcoord_name(); + INLINE InternalName *get_flat_texcoord_name() const; INLINE void set_vis_2d(bool vis_2d); INLINE bool get_vis_2d() const; @@ -115,6 +119,7 @@ private: bool _zero_special; bool _vis_inverse; + PT(InternalName) _flat_texcoord_name; bool _vis_2d; };