hi this is take2 of the patch - fixed the things Lionel mentioned. ChangeLog: Implementation of (Get|Set)ClipPlane for d3d7 Licence : LGPL CU! Index: dlls/ddraw/d3d_private.h =================================================================== RCS file: /home/wine/wine/dlls/ddraw/d3d_private.h,v retrieving revision 1.25 diff -u -r1.25 d3d_private.h --- dlls/ddraw/d3d_private.h 3 Jan 2003 21:08:50 -0000 1.25 +++ dlls/ddraw/d3d_private.h 5 Jan 2003 23:28:50 -0000 @@ -178,6 +178,12 @@ 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 @@ 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, Index: dlls/ddraw/mesa.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/mesa.c,v retrieving revision 1.32 diff -u -r1.32 mesa.c --- dlls/ddraw/mesa.c 5 Jan 2003 01:04:55 -0000 1.32 +++ dlls/ddraw/mesa.c 5 Jan 2003 23:28:53 -0000 @@ -455,8 +455,24 @@ 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 */ Index: dlls/ddraw/d3ddevice/main.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/main.c,v retrieving revision 1.32 diff -u -r1.32 main.c --- dlls/ddraw/d3ddevice/main.c 3 Jan 2003 22:32:30 -0000 1.32 +++ dlls/ddraw/d3ddevice/main.c 5 Jan 2003 23:29:07 -0000 @@ -875,14 +957,20 @@ 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 Index: dlls/ddraw/d3ddevice/mesa.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/mesa.c,v retrieving revision 1.77 diff -u -r1.77 mesa.c --- dlls/ddraw/d3ddevice/mesa.c 5 Jan 2003 01:04:55 -0000 1.77 +++ dlls/ddraw/d3ddevice/mesa.c 5 Jan 2003 23:29:17 -0000 @@ -328,6 +328,7 @@ ENTER_GL(); glXDestroyContext(glThis->display, glThis->gl_context); LEAVE_GL(); + HeapFree(GetProcessHeap(), 0, This->clipping_planes); HeapFree(GetProcessHeap(), 0, This); return 0; @@ -1590,6 +1591,32 @@ 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 @@ -1645,7 +1672,7 @@ 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, }; @@ -2030,6 +2057,7 @@ 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; @@ -2130,6 +2158,16 @@ 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(); @@ -2166,3 +2204,4 @@ return DD_OK; } +