Implementation of (Get|Set)ClipPlane for d3d7.

oldstable
Christoph Frick 2003-01-07 19:42:26 +00:00 committed by Alexandre Julliard
parent 44eb8bf59f
commit 7f4cb0621b
4 changed files with 80 additions and 10 deletions

View File

@ -178,6 +178,12 @@ struct IDirect3DExecuteBufferImpl
IDirect3DViewportImpl* vp);
};
/* Internal structure to store the state of the clipping planes */
typedef struct d3d7clippingplane
{
D3DVALUE plane[4];
} d3d7clippingplane;
/*****************************************************************************
* IDirect3DDevice implementation structure
*/
@ -218,6 +224,10 @@ struct IDirect3DDeviceImpl
DWORD active_lights, set_lights;
D3DLIGHT7 light_parameters[MAX_LIGHTS];
/* clipping planes */
DWORD max_clipping_planes;
d3d7clippingplane *clipping_planes;
void (*set_context)(IDirect3DDeviceImpl*);
HRESULT (*clear)(IDirect3DDeviceImpl *This,
DWORD dwCount,

View File

@ -875,14 +875,20 @@ Main_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface,
return DD_OK;
}
HRESULT WINAPI
Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface,
DWORD dwIndex,
D3DVALUE* pPlaneEquation)
HRESULT WINAPI
Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, D3DVALUE* pPlaneEquation)
{
ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwIndex, pPlaneEquation);
return DD_OK;
ICOM_THIS(IDirect3DDeviceImpl,iface);
TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
if (dwIndex>=This->max_clipping_planes) {
return DDERR_INVALIDPARAMS;
}
memcpy( pPlaneEquation, This->clipping_planes[dwIndex].plane, sizeof(D3DVALUE[4]));
return D3D_OK;
}
HRESULT WINAPI

View File

@ -328,6 +328,7 @@ GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
ENTER_GL();
glXDestroyContext(glThis->display, glThis->gl_context);
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, This->clipping_planes);
HeapFree(GetProcessHeap(), 0, This);
return 0;
@ -1572,6 +1573,32 @@ GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
return DD_OK;
}
HRESULT WINAPI
GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, CONST D3DVALUE* pPlaneEquation)
{
ICOM_THIS(IDirect3DDeviceImpl,iface);
GLdouble plane[4];
TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
if (dwIndex>=This->max_clipping_planes) {
return DDERR_INVALIDPARAMS;
}
TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] );
memcpy( This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4]));
plane[0] = pPlaneEquation[0];
plane[1] = pPlaneEquation[1];
plane[2] = pPlaneEquation[2];
plane[3] = pPlaneEquation[3];
/* XXX: is here also code needed to handle the transformation of the world? */
glClipPlane( GL_CLIP_PLANE0+dwIndex, (const GLdouble*)(&plane) );
return D3D_OK;
}
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
#else
@ -1627,7 +1654,7 @@ ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane,
XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
};
@ -2036,6 +2063,7 @@ d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfa
XVisualInfo template;
GLenum buffer = GL_FRONT;
int light;
GLint max_clipping_planes = 0;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
if (object == NULL) return DDERR_OUTOFMEMORY;
@ -2136,6 +2164,16 @@ d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfa
memcpy(object->view_mat , id_mat, 16 * sizeof(float));
memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
/* allocate the clipping planes */
glGetIntegerv(GL_MAX_CLIP_PLANES,&max_clipping_planes);
if (max_clipping_planes>32) {
object->max_clipping_planes=32;
} else {
object->max_clipping_planes = max_clipping_planes;
}
TRACE(" capable of %d clipping planes\n", (int)object->max_clipping_planes );
object->clipping_planes = (d3d7clippingplane*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane));
/* Initialisation */
TRACE(" setting current context\n");
LEAVE_GL();

View File

@ -455,8 +455,24 @@ void set_render_state(IDirect3DDeviceGLImpl* This,
break;
case D3DRENDERSTATE_CLIPPING: /* 136 */
/* Nothing to do here... Even if what we receive is already clipped by the application,
we cannot tell OpenGL to not re-clip it. */
case D3DRENDERSTATE_CLIPPLANEENABLE: /*152*/
{
GLint i;
DWORD mask, runner;
if (dwRenderStateType==D3DRENDERSTATE_CLIPPING) {
mask = ((dwRenderState)?(This->parent.state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE-1]):(0x0000));
} else {
mask = dwRenderState;
}
for (i = 0, runner = 1; i < This->parent.max_clipping_planes; i++, runner = (runner<<1)) {
if (mask & runner) {
glEnable(GL_CLIP_PLANE0 + i);
} else {
glDisable(GL_CLIP_PLANE0 + i);
}
}
}
break;
case D3DRENDERSTATE_LIGHTING: /* 137 */