Browse Source

GraphicsOutput::set_swap_eyes(), PfmFile::set_flat_texcoord_name()

David Rose 14 years ago
parent
commit
b7a51b133e

+ 5 - 0
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 "

+ 1 - 0
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;

+ 1 - 1
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;
 }
 

+ 1 - 1
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;

+ 27 - 0
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

+ 13 - 6
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.

+ 4 - 0
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;

+ 18 - 1
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()) {

+ 39 - 0
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

+ 26 - 9
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);
+          }
         }
       }
   

+ 5 - 0
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;
 };