more robustifying of clip planes

This commit is contained in:
David Rose 2005-04-26 19:42:43 +00:00
parent 10242ea013
commit 2f4327c5a0
12 changed files with 126 additions and 78 deletions

View File

@ -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;
}

View File

@ -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) {
}
////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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());
}

View File

@ -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();

View File

@ -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
////////////////////////////////////////////////////////////////////

View File

@ -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::

View File

@ -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;

View File

@ -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());
}

View File

@ -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();

View File

@ -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());

View File

@ -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();