From 7f4cb0621b3ed89aa1835d036d08a6175cc07fd4 Mon Sep 17 00:00:00 2001 From: Christoph Frick Date: Tue, 7 Jan 2003 19:42:26 +0000 Subject: [PATCH] Implementation of (Get|Set)ClipPlane for d3d7. --- dlls/ddraw/d3d_private.h | 10 ++++++++++ dlls/ddraw/d3ddevice/main.c | 20 ++++++++++++------- dlls/ddraw/d3ddevice/mesa.c | 40 ++++++++++++++++++++++++++++++++++++- dlls/ddraw/mesa.c | 20 +++++++++++++++++-- 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h index b1f320ca68..73f82cada7 100644 --- a/dlls/ddraw/d3d_private.h +++ b/dlls/ddraw/d3d_private.h @@ -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, diff --git a/dlls/ddraw/d3ddevice/main.c b/dlls/ddraw/d3ddevice/main.c index 2e8a6f97dc..05452bbbbe 100644 --- a/dlls/ddraw/d3ddevice/main.c +++ b/dlls/ddraw/d3ddevice/main.c @@ -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 diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c index ea72ff3343..c2f175e41f 100644 --- a/dlls/ddraw/d3ddevice/mesa.c +++ b/dlls/ddraw/d3ddevice/mesa.c @@ -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(); diff --git a/dlls/ddraw/mesa.c b/dlls/ddraw/mesa.c index a0a016f876..9e370d752a 100644 --- a/dlls/ddraw/mesa.c +++ b/dlls/ddraw/mesa.c @@ -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 */ -- 2.32.0.93.g670b81a890