Browse Source

regularize cube map coordinate systems

David Rose 20 years ago
parent
commit
314630126f

+ 0 - 1
panda/src/display/config_display.cxx

@@ -260,7 +260,6 @@ ConfigVariableBool sync_video
           "cheesy estimate of scene complexity.  Some drivers may ignore "
           "this request."));
 
-
 ////////////////////////////////////////////////////////////////////
 //     Function: init_libdisplay
 //  Description: Initializes the library.  This must be called at

+ 1 - 1
panda/src/display/config_display.h

@@ -28,6 +28,7 @@
 #include "configVariableInt.h"
 #include "configVariableEnum.h"
 #include "configVariableFilename.h"
+#include "coordinateSystem.h"
 #include "dconfig.h"
 
 #include "pvector.h"
@@ -84,7 +85,6 @@ extern EXPCL_PANDA ConfigVariableInt multisamples;
 extern EXPCL_PANDA ConfigVariableDouble background_color;
 extern EXPCL_PANDA ConfigVariableBool sync_video;
 
-
 extern EXPCL_PANDA void init_libdisplay();
 
 #endif /* CONFIG_DISPLAY_H */

+ 11 - 10
panda/src/display/graphicsOutput.cxx

@@ -39,20 +39,21 @@ PStatCollector GraphicsOutput::_make_current_pcollector("Draw:Make current");
 PStatCollector GraphicsOutput::_copy_texture_pcollector("Draw:Copy texture");
 
 struct CubeFaceDef {
-  CubeFaceDef(const char *name, float h, float p, float r) :
-    _name(name), _hpr(h, p, r) { }
+  CubeFaceDef(const char *name, const LPoint3f &look_at, const LVector3f &up) :
+    _name(name), _look_at(look_at), _up(up) { }
 
   const char *_name;
-  LVecBase3f _hpr;
+  LPoint3f _look_at;
+  LVector3f _up;
 };
 
 static CubeFaceDef cube_faces[6] = {
-  CubeFaceDef("positive_x", -90, 0, -180),
-  CubeFaceDef("negative_x", 90, 0, -180),
-  CubeFaceDef("positive_y", 0, 90, 0),
-  CubeFaceDef("negative_y", 0, -90, 0),
-  CubeFaceDef("positive_z", 180, 0, -180),
-  CubeFaceDef("negative_z", 0, 0, -180),
+  CubeFaceDef("positive_x", LPoint3f(1, 0, 0), LVector3f(0, -1, 0)),
+  CubeFaceDef("negative_x", LPoint3f(-1, 0, 0), LVector3f(0, -1, 0)),
+  CubeFaceDef("positive_y", LPoint3f(0, 1, 0), LVector3f(0, 0, 1)),
+  CubeFaceDef("negative_y", LPoint3f(0, -1, 0), LVector3f(0, 0, -1)),
+  CubeFaceDef("positive_z", LPoint3f(0, 0, 1), LVector3f(0, -1, 0)),
+  CubeFaceDef("negative_z", LPoint3f(0, 0, -1), LVector3f(0, -1, 0))
 };
   
 ////////////////////////////////////////////////////////////////////
@@ -655,7 +656,7 @@ make_cube_map(const string &name, int size, bool to_ram,
     camera->set_lens(lens);
     camera->set_camera_mask(camera_mask);
     NodePath camera_np = camera_rig.attach_new_node(camera);
-    camera_np.set_hpr(cube_faces[i]._hpr);
+    camera_np.look_at(cube_faces[i]._look_at, cube_faces[i]._up);
     
     DisplayRegion *dr = buffer->make_display_region();
     dr->set_cube_map_index(i);

+ 13 - 13
panda/src/display/graphicsStateGuardian.I

@@ -432,6 +432,19 @@ get_color_scale_via_lighting() const {
   return _color_scale_via_lighting;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_coordinate_system
+//       Access: Published
+//  Description: Returns the coordinate system in effect on this
+//               particular gsg.  Normally, this will be the default
+//               coordinate system, but it might be set differently at
+//               runtime.
+////////////////////////////////////////////////////////////////////
+INLINE CoordinateSystem GraphicsStateGuardian::
+get_coordinate_system() const {
+  return _coordinate_system;
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::set_scene
@@ -696,19 +709,6 @@ pop_display_region(DisplayRegionStack &node) {
   node._stack_level = -1;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::get_coordinate_system
-//       Access: Public
-//  Description: Returns the coordinate system in effect on this
-//               particular gsg.  Normally, this will be the default
-//               coordinate system, but it might be set differently at
-//               runtime.
-////////////////////////////////////////////////////////////////////
-INLINE CoordinateSystem GraphicsStateGuardian::
-get_coordinate_system() const {
-  return _coordinate_system;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_cs_transform
 //       Access: Public

+ 53 - 52
panda/src/display/graphicsStateGuardian.cxx

@@ -100,6 +100,7 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
   _coordinate_system = CS_invalid;
   _external_transform = TransformState::make_identity();
   _internal_transform = TransformState::make_identity();
+  
   set_coordinate_system(get_default_coordinate_system());
 
   _current_display_region = (DisplayRegion*)0L;
@@ -199,6 +200,58 @@ get_supported_geom_rendering() const {
   return _supported_geom_rendering;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::set_coordinate_system
+//       Access: Published
+//  Description: Changes the coordinate system in effect on this
+//               particular gsg.  This is also called the "external"
+//               coordinate system, since it is the coordinate system
+//               used by the scene graph, external to to GSG.
+//
+//               Normally, this will be the default coordinate system,
+//               but it might be set differently at runtime.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+set_coordinate_system(CoordinateSystem cs) {
+  _coordinate_system = cs;
+
+  // Changing the external coordinate system changes the cs_transform.
+  if (_internal_coordinate_system == CS_default ||
+      _internal_coordinate_system == _coordinate_system) {
+    _cs_transform = TransformState::make_identity();
+    _inv_cs_transform = TransformState::make_identity();
+
+  } else {
+    _cs_transform = 
+      TransformState::make_mat
+      (LMatrix4f::convert_mat(_coordinate_system,
+                              _internal_coordinate_system));
+    _inv_cs_transform = 
+      TransformState::make_mat
+      (LMatrix4f::convert_mat(_internal_coordinate_system,
+                              _coordinate_system));
+  }
+  _internal_transform = _cs_transform->compose(_external_transform);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_internal_coordinate_system
+//       Access: Published, Virtual
+//  Description: Returns the coordinate system used internally by the
+//               GSG.  This may be the same as the external coordinate
+//               system reported by get_coordinate_system(), or it may
+//               be something different.
+//
+//               In any case, vertices that have been transformed
+//               before being handed to the GSG (that is, vertices
+//               with a contents value of C_clip_point) will be
+//               expected to be in this coordinate system.
+////////////////////////////////////////////////////////////////////
+CoordinateSystem GraphicsStateGuardian::
+get_internal_coordinate_system() const {
+  return _internal_coordinate_system;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::reset
 //       Access: Public, Virtual
@@ -934,58 +987,6 @@ void GraphicsStateGuardian::
 framebuffer_release_texture(GraphicsOutput *, Texture *) {
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::set_coordinate_system
-//       Access: Public
-//  Description: Changes the coordinate system in effect on this
-//               particular gsg.  This is also called the "external"
-//               coordinate system, since it is the coordinate system
-//               used by the scene graph, external to to GSG.
-//
-//               Normally, this will be the default coordinate system,
-//               but it might be set differently at runtime.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-set_coordinate_system(CoordinateSystem cs) {
-  _coordinate_system = cs;
-
-  // Changing the external coordinate system changes the cs_transform.
-  if (_internal_coordinate_system == CS_default ||
-      _internal_coordinate_system == _coordinate_system) {
-    _cs_transform = TransformState::make_identity();
-    _inv_cs_transform = TransformState::make_identity();
-
-  } else {
-    _cs_transform = 
-      TransformState::make_mat
-      (LMatrix4f::convert_mat(_coordinate_system,
-                              _internal_coordinate_system));
-    _inv_cs_transform = 
-      TransformState::make_mat
-      (LMatrix4f::convert_mat(_internal_coordinate_system,
-                              _coordinate_system));
-  }
-  _internal_transform = _cs_transform->compose(_external_transform);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::get_internal_coordinate_system
-//       Access: Public, Virtual
-//  Description: Returns the coordinate system used internally by the
-//               GSG.  This may be the same as the external coordinate
-//               system reported by get_coordinate_system(), or it may
-//               be something different.
-//
-//               In any case, vertices that have been transformed
-//               before being handed to the GSG (that is, vertices
-//               with a contents value of C_clip_point) will be
-//               expected to be in this coordinate system.
-////////////////////////////////////////////////////////////////////
-CoordinateSystem GraphicsStateGuardian::
-get_internal_coordinate_system() const {
-  return _internal_coordinate_system;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::issue_transform
 //       Access: Public, Virtual

+ 4 - 4
panda/src/display/graphicsStateGuardian.h

@@ -116,6 +116,10 @@ PUBLISHED:
 
   INLINE bool get_color_scale_via_lighting() const;
 
+  void set_coordinate_system(CoordinateSystem cs);
+  INLINE CoordinateSystem get_coordinate_system() const;
+  virtual CoordinateSystem get_internal_coordinate_system() const;
+
 public:
   INLINE bool set_scene(SceneSetup *scene_setup);
   INLINE SceneSetup *get_scene() const;
@@ -204,10 +208,6 @@ public:
   INLINE DisplayRegionStack push_display_region(const DisplayRegion *dr);
   INLINE void pop_display_region(DisplayRegionStack &node);
 
-  void set_coordinate_system(CoordinateSystem cs);
-  INLINE CoordinateSystem get_coordinate_system() const;
-  virtual CoordinateSystem get_internal_coordinate_system() const;
-
   INLINE const TransformState *get_cs_transform() const;
   INLINE const TransformState *get_inv_cs_transform() const;
 

+ 7 - 9
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -2290,16 +2290,15 @@ do_issue_texture() {
         _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, 
                                           texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
         texcoords_3d = true;
-        CPT(TransformState) camera_transform = _cs_transform->compose(_scene_setup->get_camera_transform())->compose(_inv_cs_transform);
-        CPT(TransformState) rotate_transform = invert_z->compose(camera_transform);
-        tex_mat = tex_mat->compose(rotate_transform->set_pos(LVecBase3f::zero()));
+        CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
+        tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero()));
       }
       break;
 
     case TexGenAttrib::M_eye_cube_map:
       _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, 
                                         texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
-      tex_mat = tex_mat->compose(invert_z);
+      tex_mat = tex_mat->compose(_inv_cs_transform);
       texcoords_3d = true;
       break;
 
@@ -2312,23 +2311,22 @@ do_issue_texture() {
         _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, 
                                           texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
         texcoords_3d = true;
-        CPT(TransformState) camera_transform = _cs_transform->compose(_scene_setup->get_camera_transform())->compose(_inv_cs_transform);
-        CPT(TransformState) rotate_transform = invert_z->compose(camera_transform);
-        tex_mat = tex_mat->compose(rotate_transform->set_pos(LVecBase3f::zero()));
+        CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
+        tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero()));
       }
       break;
 
     case TexGenAttrib::M_eye_normal:
       _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, 
                                         texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
-      tex_mat = tex_mat->compose(invert_z);
       texcoords_3d = true;
+      tex_mat = tex_mat->compose(_inv_cs_transform);
       break;
 
     case TexGenAttrib::M_world_position:
       // To achieve world position, we must transform camera
       // coordinates to world coordinates; i.e. apply the
-      // inverse root_transform.
+      // camera transform.
       {
         _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, 
                                           texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);

+ 78 - 36
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -4241,25 +4241,47 @@ finish_modify_state() {
         break;
         
       case TexGenAttrib::M_eye_cube_map:
+        if (_supports_cube_map) {
+          // We need to rotate the normals out of GL's coordinate
+          // system and into the user's coordinate system.  We do this
+          // by composing a transform onto the texture matrix.
+          LMatrix4f mat = _inv_cs_transform->get_mat();
+          mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+          GLP(MatrixMode)(GL_TEXTURE);
+          GLP(MultMatrixf)(mat.get_data());
+          
+          // Now we need to reset the texture matrix next time
+          // around to undo this.
+          _tex_gen_modifies_mat = true;
+
+          GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+          GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+          GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+          GLP(Enable)(GL_TEXTURE_GEN_S);
+          GLP(Enable)(GL_TEXTURE_GEN_T);
+          GLP(Enable)(GL_TEXTURE_GEN_R);
+          force_normal = true;
+        }
+        break;
+
       case TexGenAttrib::M_world_cube_map:
         if (_supports_cube_map) {
-          if (mode != TexGenAttrib::M_eye_cube_map) {
-            // We dynamically transform normals from eye space to
-            // world space by applying the appropriate rotation
-            // transform to the current texture matrix.  Although it's
-            // tempting to try, we can't safely convert to object
-            // space, since this method doesn't get called with each
-            // different object.
-            CPT(TransformState) camera_transform = _cs_transform->compose(_scene_setup->get_camera_transform())->compose(_inv_cs_transform);
-            LMatrix4f mat = camera_transform->get_mat();
-            mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
-            GLP(MatrixMode)(GL_TEXTURE);
-            GLP(MultMatrixf)(mat.get_data());
-
-            // Now we need to reset the texture matrix next time
-            // around to undo this.
-            _tex_gen_modifies_mat = true;
-          }
+          // We dynamically transform normals from eye space to world
+          // space by applying the appropriate rotation transform to
+          // the current texture matrix.  Unlike M_world_position, we
+          // can't achieve this effect by monkeying with the modelview
+          // transform, since the current modelview doesn't affect
+          // GL_REFLECTION_MAP.
+          CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
+
+          LMatrix4f mat = camera_transform->get_mat();
+          mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+          GLP(MatrixMode)(GL_TEXTURE);
+          GLP(MultMatrixf)(mat.get_data());
+          
+          // Now we need to reset the texture matrix next time
+          // around to undo this.
+          _tex_gen_modifies_mat = true;
 
           GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
           GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
@@ -4272,27 +4294,47 @@ finish_modify_state() {
         break;
         
       case TexGenAttrib::M_eye_normal:
+        if (_supports_cube_map) {
+          // We need to rotate the normals out of GL's coordinate
+          // system and into the user's coordinate system.  We do this
+          // by composing a transform onto the texture matrix.
+          LMatrix4f mat = _inv_cs_transform->get_mat();
+          mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+          GLP(MatrixMode)(GL_TEXTURE);
+          GLP(MultMatrixf)(mat.get_data());
+          
+          // Now we need to reset the texture matrix next time
+          // around to undo this.
+          _tex_gen_modifies_mat = true;
+
+          GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+          GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+          GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+          GLP(Enable)(GL_TEXTURE_GEN_S);
+          GLP(Enable)(GL_TEXTURE_GEN_T);
+          GLP(Enable)(GL_TEXTURE_GEN_R);
+          force_normal = true;
+        }
+        break;
+
       case TexGenAttrib::M_world_normal:
         if (_supports_cube_map) {
-          if (mode != TexGenAttrib::M_eye_normal) {
-            // We dynamically transform normals from eye space to
-            // world space by applying the appropriate rotation
-            // transform to the current texture matrix.  Although it's
-            // tempting to try, we can't safely convert to object
-            // space, since this method doesn't get called with each
-            // different object.
-            CPT(TransformState) transform = 
-              _cs_transform->compose(_scene_setup->get_world_transform());
-            transform = transform->invert_compose(TransformState::make_identity());
-            LMatrix4f mat = transform->get_mat();
-            mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
-            GLP(MatrixMode)(GL_TEXTURE);
-            GLP(MultMatrixf)(mat.get_data());
-
-            // Now we need to reset the texture matrix next time
-            // around to undo this.
-            _tex_gen_modifies_mat = true;
-          }
+          // We dynamically transform normals from eye space to world
+          // space by applying the appropriate rotation transform to
+          // the current texture matrix.  Unlike M_world_position, we
+          // can't achieve this effect by monkeying with the modelview
+          // transform, since the current modelview doesn't affect
+          // GL_NORMAL_MAP.
+          CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
+
+          LMatrix4f mat = camera_transform->get_mat();
+          mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+          GLP(MatrixMode)(GL_TEXTURE);
+          GLP(MultMatrixf)(mat.get_data());
+          
+          // Now we need to reset the texture matrix next time
+          // around to undo this.
+          _tex_gen_modifies_mat = true;
 
           GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
           GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);

+ 4 - 2
panda/src/gobj/texture.I

@@ -662,7 +662,7 @@ set_x_size(int x_size) {
 INLINE void Texture::
 set_y_size(int y_size) {
   if (_y_size != y_size) {
-    nassertv(_texture_type != Texture::TT_1d_texture);
+    nassertv(_texture_type != Texture::TT_1d_texture || y_size == 1);
     _y_size = y_size;
     clear_ram_image();
   }
@@ -678,7 +678,9 @@ set_y_size(int y_size) {
 INLINE void Texture::
 set_z_size(int z_size) {
   if (_z_size != z_size) {
-    nassertv(_texture_type == Texture::TT_3d_texture);
+    nassertv(_texture_type == Texture::TT_3d_texture ||
+             (_texture_type == Texture::TT_cube_map && z_size == 6) ||
+             (z_size == 1));
     _z_size = z_size;
     clear_ram_image();
   }

+ 16 - 0
panda/src/gobj/texture.cxx

@@ -413,6 +413,22 @@ read_pages(const Filename &fullpath_template, int z_size) {
 
   clear_ram_image();
 
+  if (z_size == 0) {
+    switch (_texture_type) {
+    case TT_1d_texture:
+    case TT_2d_texture:
+      z_size = 1;
+      break;
+
+    case TT_cube_map:
+      z_size = 6;
+      break;
+
+    default:
+      break;
+    }
+  }
+
   if (z_size != 0) {
     set_z_size(z_size);
     for (int z = 0; z < z_size; z++) {

+ 3 - 2
panda/src/linmath/coordinateSystem.cxx

@@ -28,8 +28,9 @@
 
 static ConfigVariableEnum<CoordinateSystem> default_cs
 ("coordinate-system", CS_zup_right,
- "The default coordinate system to use throughout Panda for rendering, "
- "user input, and matrix operations, unless specified otherwise.");
+ PRC_DESC("The default coordinate system to use throughout Panda for "
+          "rendering, user input, and matrix operations, unless specified "
+          "otherwise."));
 
 
 CoordinateSystem