Browse Source

more robustifying of clip planes

David Rose 20 years ago
parent
commit
2f4327c5a0

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

@@ -595,9 +595,9 @@ get_light(int light_id) const {
 //  Description: Returns the PlaneNode object that is bound to the
 //               indicated id, or NULL if no PlaneNode is bound.
 ////////////////////////////////////////////////////////////////////
-INLINE PlaneNode *GraphicsStateGuardian::
+INLINE NodePath GraphicsStateGuardian::
 get_clip_plane(int plane_id) const {
-  nassertr(plane_id >= 0 && plane_id < (int)_clip_plane_info.size(), (PlaneNode *)NULL);
+  nassertr(plane_id >= 0 && plane_id < (int)_clip_plane_info.size(), NodePath::fail());
   return _clip_plane_info[plane_id]._plane;
 }
 

+ 9 - 12
panda/src/display/graphicsStateGuardian.cxx

@@ -1147,17 +1147,14 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
   bool any_bound = false;
 
   int num_enabled = 0;
-  int num_planes = attrib->get_num_planes();
-  if (attrib->get_operation() == ClipPlaneAttrib::O_remove) {
-    num_planes = 0;
-  }
-  for (int li = 0; li < num_planes; li++) {
-    PlaneNode *plane = attrib->get_plane(li);
-    nassertv(plane != (PlaneNode *)NULL);
+  int num_on_planes = attrib->get_num_on_planes();
+  for (int li = 0; li < num_on_planes; li++) {
+    NodePath plane = attrib->get_on_plane(li);
+    nassertv(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()));
 
     num_enabled++;
 
-    // Planeing should be enabled before we apply any planes.
+    // Clipping should be enabled before we apply any planes.
     enable_clip_planes(true);
     _clip_planes_enabled = true;
     _clip_planes_enabled_this_frame = true;
@@ -1179,7 +1176,7 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
     // See if there are any unbound plane ids
     if (cur_plane_id == -1) {
       for (i = 0; i < max_planes; i++) {
-        if (_clip_plane_info[i]._plane == (PlaneNode *)NULL) {
+        if (_clip_plane_info[i]._plane.is_empty()) {
           _clip_plane_info[i]._plane = plane;
           cur_plane_id = i;
           break;
@@ -1191,7 +1188,7 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
     // a currently unused but previously bound id
     if (cur_plane_id == -1) {
       for (i = 0; i < max_planes; i++) {
-        if (!attrib->has_plane(_clip_plane_info[i]._plane)) {
+        if (!attrib->has_on_plane(_clip_plane_info[i]._plane)) {
           _clip_plane_info[i]._plane = plane;
           cur_plane_id = i;
           break;
@@ -1225,7 +1222,7 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
       
     } else if (cur_plane_id == -1) {
       gsg_cat.warning()
-        << "Failed to bind " << *plane << " to id.\n";
+        << "Failed to bind " << plane << " to id.\n";
     }
   }
 
@@ -1434,7 +1431,7 @@ begin_bind_clip_planes() {
 //               with the plane's properties.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
-bind_clip_plane(PlaneNode *plane, int plane_id) {
+bind_clip_plane(const NodePath &plane, int plane_id) {
 }
 
 ////////////////////////////////////////////////////////////////////

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

@@ -216,12 +216,12 @@ protected:
   virtual void begin_bind_lights();
   virtual void end_bind_lights();
 
-  INLINE PlaneNode *get_clip_plane(int plane_id) const;
+  INLINE NodePath get_clip_plane(int plane_id) const;
   virtual bool slot_new_clip_plane(int plane_id);
   virtual void enable_clip_planes(bool enable);
   virtual void enable_clip_plane(int plane_id, bool enable);
   virtual void begin_bind_clip_planes();
-  virtual void bind_clip_plane(PlaneNode *plane, int pane_id);
+  virtual void bind_clip_plane(const NodePath &plane, int pane_id);
   virtual void end_bind_clip_planes();
 
   virtual void set_blend_mode();
@@ -389,7 +389,7 @@ private:
   class ClipPlaneInfo {
   public:
     INLINE ClipPlaneInfo();
-    PT(PlaneNode) _plane;
+    NodePath _plane;
     bool _enabled;
     bool _next_enabled;
   };

+ 5 - 4
panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx

@@ -4508,14 +4508,15 @@ enable_clip_plane(int plane_id, bool enable) {
 //               properties.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian7::
-bind_clip_plane(PlaneNode *plane, int plane_id) {
+bind_clip_plane(const NodePath &plane, int plane_id) {
   // Get the plane in "world coordinates".  This means the plane in
   // the coordinate space of the camera, converted to DX's coordinate
   // system.
-  NodePath plane_np(plane);
-  const LMatrix4f &plane_mat = plane_np.get_mat(_scene_setup->get_camera_path());
+  const LMatrix4f &plane_mat = plane.get_mat(_scene_setup->get_camera_path());
   LMatrix4f rel_mat = plane_mat * LMatrix4f::convert_mat(CS_yup_left, CS_default);
-  Planef world_plane = plane->get_plane() * rel_mat;
+  const PlaneNode *plane_node;
+  DCAST_INTO_V(plane_node, plane.node());
+  Planef world_plane = plane_node->get_plane() * rel_mat;
 
   _pScrn->pD3DDevice->SetClipPlane(plane_id, (float *)world_plane.get_data());
 }

+ 1 - 1
panda/src/dxgsg7/dxGraphicsStateGuardian7.h

@@ -145,7 +145,7 @@ protected:
 
   virtual bool slot_new_clip_plane(int plane_id);
   virtual void enable_clip_plane(int plane_id, bool enable);
-  virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
+  virtual void bind_clip_plane(const NodePath &plane, int plane_id);
 
   virtual void set_blend_mode();
 

+ 0 - 30
panda/src/dxgsg8/dxGraphicsStateGuardian8.I

@@ -188,14 +188,6 @@ set_color_writemask(UINT color_writemask) {
   }
 }
 
-INLINE void DXGraphicsStateGuardian8::
-enable_primitive_clipping(bool val) {
-  if (_clipping_enabled != val) {
-    _clipping_enabled = val;
-    _pD3DDevice->SetRenderState(D3DRS_CLIPPING, (DWORD)val);
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian8::enable_fog
 //       Access:
@@ -537,28 +529,6 @@ get_fog_mode_type(Fog::Mode m) const {
   return D3DFOG_EXP;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::enable_clip_plane
-//       Access: Protected, Virtual
-//  Description: Intended to be overridden by a derived class to
-//               enable the indicated clip_plane id.  A specific
-//               PlaneNode will already have been bound to this id via
-//               bind_clip_plane().
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian8::
-enable_clip_plane(int plane_id, bool enable) {
-  assert(plane_id < D3DMAXUSERCLIPPLANES);
-
-  DWORD bitflag = ((DWORD)1 << plane_id);
-  if (enable) {
-    _clip_plane_bits |= bitflag;
-  } else {
-    _clip_plane_bits &= ~bitflag;
-  }
-
-  _pD3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, _clip_plane_bits);
-}
-
 /**  unimplemented
 
 ////////////////////////////////////////////////////////////////////

+ 88 - 13
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -355,6 +355,8 @@ dx_init(void) {
         << "\n";
     }
 
+    _max_lights = d3dCaps.MaxActiveLights;
+    _max_clip_planes = d3dCaps.MaxUserClipPlanes;
     _max_vertex_transforms = d3dCaps.MaxVertexBlendMatrices;
     _max_vertex_transform_indices = d3dCaps.MaxVertexBlendMatrixIndex;
 
@@ -372,7 +374,6 @@ dx_init(void) {
     _pD3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE , 0x0);
 
     _pD3DDevice->SetRenderState(D3DRS_CLIPPING, true);
-    _clipping_enabled = true;
 
     // these both reflect d3d defaults
     _color_writemask = 0xFFFFFFFF;
@@ -4241,7 +4242,12 @@ bind_light(PointLight *light, int light_id) {
   alight.Attenuation1 = att[1];
   alight.Attenuation2 = att[2];
 
-  HRESULT res = _pD3DDevice->SetLight(light_id, &alight);
+  HRESULT hr = _pD3DDevice->SetLight(light_id, &alight);
+  if (FAILED(hr)) {
+    wdxdisplay8_cat.warning() 
+      << "Could not set light properties for " << light 
+      << " to id " << light_id << ": " << D3DERRORSTRING(hr) << "\n";
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -4282,7 +4288,12 @@ bind_light(DirectionalLight *light, int light_id) {
   alight.Attenuation1 = 0.0f;       // linear
   alight.Attenuation2 = 0.0f;       // quadratic
 
-  HRESULT res = _pD3DDevice->SetLight(light_id, &alight);
+  HRESULT hr = _pD3DDevice->SetLight(light_id, &alight);
+  if (FAILED(hr)) {
+    wdxdisplay8_cat.warning() 
+      << "Could not set light properties for " << light 
+      << " to id " << light_id << ": " << D3DERRORSTRING(hr) << "\n";
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -4332,7 +4343,12 @@ bind_light(Spotlight *light, int light_id) {
   alight.Attenuation1 = att[1];
   alight.Attenuation2 = att[2];
 
-  HRESULT res = _pD3DDevice->SetLight(light_id, &alight);
+  HRESULT hr = _pD3DDevice->SetLight(light_id, &alight);
+  if (FAILED(hr)) {
+    wdxdisplay8_cat.warning() 
+      << "Could not set light properties for " << light 
+      << " to id " << light_id << ": " << D3DERRORSTRING(hr) << "\n";
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -4644,6 +4660,24 @@ do_auto_rescale_normal() {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian8::slot_new_light
+//       Access: Protected, Virtual
+//  Description: This will be called by the base class before a
+//               particular light id will be used for the first time.
+//               It is intended to allow the derived class to reserve
+//               any additional resources, if required, for the new
+//               light; and also to indicate whether the hardware
+//               supports this many simultaneous lights.
+//
+//               The return value should be true if the additional
+//               light is supported, or false if it is not.
+////////////////////////////////////////////////////////////////////
+bool DXGraphicsStateGuardian8::
+slot_new_light(int light_id) {
+  return (light_id < _max_lights);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian8::enable_lighting
 //       Access: Protected, Virtual
@@ -4667,8 +4701,7 @@ enable_lighting(bool enable) {
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
 set_ambient_light(const Colorf &color) {
-  _pD3DDevice->SetRenderState(D3DRS_AMBIENT,
-                                  Colorf_to_D3DCOLOR(color));
+  _pD3DDevice->SetRenderState(D3DRS_AMBIENT, Colorf_to_D3DCOLOR(color));
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -4680,12 +4713,17 @@ set_ambient_light(const Colorf &color) {
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
 enable_light(int light_id, bool enable) {
-  HRESULT res = _pD3DDevice->LightEnable(light_id, enable);
+  HRESULT hr = _pD3DDevice->LightEnable(light_id, enable);
 
 #ifdef GSG_VERBOSE
   dxgsg8_cat.debug()
     << "LightEnable(" << light_id << "=" << enable << ")" << endl;
 #endif
+  if (FAILED(hr)) {
+    wdxdisplay8_cat.warning() 
+      << "Could not enable light " << light_id << ": " 
+      << D3DERRORSTRING(hr) << "\n";
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -4704,7 +4742,24 @@ enable_light(int light_id, bool enable) {
 ////////////////////////////////////////////////////////////////////
 bool DXGraphicsStateGuardian8::
 slot_new_clip_plane(int plane_id) {
-  return (plane_id < D3DMAXUSERCLIPPLANES);
+  return (plane_id < _max_clip_planes);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian8::enable_clip_plane
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by a derived class to
+//               enable the indicated clip_plane id.  A specific
+//               PlaneNode will already have been bound to this id via
+//               bind_clip_plane().
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian8::
+enable_clip_plane(int plane_id, bool enable) {
+  if (enable) {
+    _clip_plane_bits |= ((DWORD)1 << plane_id);
+  } else {
+    _clip_plane_bits &= ~((DWORD)1 << plane_id);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -4716,16 +4771,36 @@ slot_new_clip_plane(int plane_id) {
 //               properties.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-bind_clip_plane(PlaneNode *plane, int plane_id) {
+bind_clip_plane(const NodePath &plane, int plane_id) {
   // Get the plane in "world coordinates".  This means the plane in
   // the coordinate space of the camera, converted to DX's coordinate
   // system.
-  NodePath plane_np(plane);
-  const LMatrix4f &plane_mat = plane_np.get_mat(_scene_setup->get_camera_path());
+  const LMatrix4f &plane_mat = plane.get_mat(_scene_setup->get_camera_path());
   LMatrix4f rel_mat = plane_mat * LMatrix4f::convert_mat(CS_yup_left, CS_default);
-  Planef world_plane = plane->get_plane() * rel_mat;
+  const PlaneNode *plane_node;
+  DCAST_INTO_V(plane_node, plane.node());
+  Planef world_plane = plane_node->get_plane() * rel_mat;
 
-  _pD3DDevice->SetClipPlane(plane_id, world_plane.get_data());
+  HRESULT hr = _pD3DDevice->SetClipPlane(plane_id, world_plane.get_data());
+  if (FAILED(hr)) {
+    wdxdisplay8_cat.warning() 
+      << "Could not set clip plane for " << plane 
+      << " to id " << plane_id << ": " << D3DERRORSTRING(hr) << "\n";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian8::end_bind_clip_planes
+//       Access: Protected, Virtual
+//  Description: Called after before bind_clip_plane() has been called one
+//               or more times (but before any geometry is issued or
+//               additional state is changed), this is intended to
+//               clean up any temporary changes to the state that may
+//               have been made by begin_bind_clip_planes().
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian8::
+end_bind_clip_planes() {
+  _pD3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, _clip_plane_bits);
 }
 
 void DXGraphicsStateGuardian8::

+ 6 - 3
panda/src/dxgsg8/dxGraphicsStateGuardian8.h

@@ -167,13 +167,15 @@ public:
   D3DPRESENT_PARAMETERS _PresReset;  // This is built during reset device
 
 protected:
+  virtual bool slot_new_light(int light_id);
   virtual void enable_lighting(bool enable);
   virtual void set_ambient_light(const Colorf &color);
   virtual void enable_light(int light_id, bool enable);
 
   virtual bool slot_new_clip_plane(int plane_id);
   virtual void enable_clip_plane(int plane_id, bool enable);
-  virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
+  virtual void bind_clip_plane(const NodePath &plane, int plane_id);
+  virtual void end_bind_clip_planes();
 
   virtual void set_blend_mode();
 
@@ -225,7 +227,6 @@ protected:
   INLINE D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm) const;
   INLINE D3DFOGMODE get_fog_mode_type(Fog::Mode m) const;
 
-  INLINE void enable_primitive_clipping(bool val);
   INLINE void enable_alpha_test(bool val);
   INLINE void enable_line_smooth(bool val);
   INLINE void enable_blend(bool val);
@@ -305,10 +306,12 @@ protected:
   D3DBLEND _blend_source_func;
   D3DBLEND _blend_dest_func;
 
+  int _max_lights;
+  int _max_clip_planes;
+
   bool _line_smooth_enabled;
   bool _color_material_enabled;
   bool _texturing_enabled;
-  bool _clipping_enabled;
   bool _dither_enabled;
   bool _stencil_test_enabled;
   bool _blend_enabled;

+ 5 - 4
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -3832,14 +3832,15 @@ slot_new_clip_plane(int plane_id) {
 //               properties.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian9::
-bind_clip_plane(PlaneNode *plane, int plane_id) {
+bind_clip_plane(const NodePath &plane, int plane_id) {
   // Get the plane in "world coordinates".  This means the plane in
   // the coordinate space of the camera, converted to DX's coordinate
   // system.
-  NodePath plane_np(plane);
-  const LMatrix4f &plane_mat = plane_np.get_mat(_scene_setup->get_camera_path());
+  const LMatrix4f &plane_mat = plane.get_mat(_scene_setup->get_camera_path());
   LMatrix4f rel_mat = plane_mat * LMatrix4f::convert_mat(CS_yup_left, CS_default);
-  Planef world_plane = plane->get_plane() * rel_mat;
+  const PlaneNode *plane_node;
+  DCAST_INTO_V(plane_node, plane.node());
+  Planef world_plane = plane_node->get_plane() * rel_mat;
 
   _pD3DDevice->SetClipPlane(plane_id, world_plane.get_data());
 }

+ 1 - 1
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -146,7 +146,7 @@ protected:
 
   virtual bool slot_new_clip_plane(int plane_id);
   virtual void enable_clip_plane(int plane_id, bool enable);
-  virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
+  virtual void bind_clip_plane(const NodePath &plane, int plane_id);
 
   virtual void set_blend_mode();
 

+ 5 - 4
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -5695,12 +5695,13 @@ begin_bind_clip_planes() {
 //               properties.
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-bind_clip_plane(PlaneNode *plane, int plane_id) {
+bind_clip_plane(const NodePath &plane, int plane_id) {
   GLenum id = get_clip_plane_id(plane_id);
 
-  NodePath plane_np(plane);
-  const LMatrix4f &plane_mat = plane_np.get_mat(_scene_setup->get_scene_root());
-  Planef xformed_plane = plane->get_plane() * plane_mat;
+  const LMatrix4f &plane_mat = plane.get_mat(_scene_setup->get_scene_root());
+  const PlaneNode *plane_node;
+  DCAST_INTO_V(plane_node, plane.node());
+  Planef xformed_plane = plane_node->get_plane() * plane_mat;
 
   Planed double_plane(LCAST(double, xformed_plane));
   GLP(ClipPlane)(id, double_plane.get_data());

+ 1 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -199,7 +199,7 @@ protected:
   virtual bool slot_new_clip_plane(int plane_id);
   virtual void enable_clip_plane(int plane_id, bool enable);
   virtual void begin_bind_clip_planes();
-  virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
+  virtual void bind_clip_plane(const NodePath &plane, int plane_id);
   virtual void end_bind_clip_planes();
 
   virtual void set_blend_mode();