From 2f4327c5a032b05048196f539586fa835c76f17c Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 26 Apr 2005 19:42:43 +0000 Subject: [PATCH] more robustifying of clip planes --- panda/src/display/graphicsStateGuardian.I | 4 +- panda/src/display/graphicsStateGuardian.cxx | 21 ++-- panda/src/display/graphicsStateGuardian.h | 6 +- panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx | 9 +- panda/src/dxgsg7/dxGraphicsStateGuardian7.h | 2 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.I | 30 ------ panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 101 +++++++++++++++--- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 9 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 9 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 2 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 9 +- .../src/glstuff/glGraphicsStateGuardian_src.h | 2 +- 12 files changed, 126 insertions(+), 78 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index b171c29c1e..3972df3bad 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/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; } diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 4c2091e792..460d94b080 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/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) { } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 143c0688d1..bdd9f2e3ae 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/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; }; diff --git a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx index cbd1b6c8c0..4506c8fdbf 100644 --- a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx +++ b/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()); } diff --git a/panda/src/dxgsg7/dxGraphicsStateGuardian7.h b/panda/src/dxgsg7/dxGraphicsStateGuardian7.h index 8053fd680e..ebfd8d2b94 100644 --- a/panda/src/dxgsg7/dxGraphicsStateGuardian7.h +++ b/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(); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I index fdbae60c5c..4ffe75ebbd 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I +++ b/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 //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 932aca0d1d..6408e9d7e7 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/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:: diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 3f008e1ba5..73302ecfcb 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/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; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 94aa973567..8df9400ecc 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/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()); } diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 257b794f83..f8758f9c83 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/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(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 8089ee5ab8..c32ea7f856 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/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()); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 7e2da5a496..723e32bd5b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/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();