/* Direct3D Viewport * Copyright (c) 1998 Lionel ULMER * * This file contains the implementation of Direct3DViewport2. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "windef.h" #include "winerror.h" #include "wine/obj_base.h" #include "ddraw.h" #include "d3d.h" #include "wine/debug.h" #include "d3d_private.h" #include "mesa_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); #ifdef HAVE_OPENGL #define D3DVPRIVATE(x) mesa_d3dv_private*dvpriv=((mesa_d3dv_private*)x->private) #define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private) static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable; /******************************************************************************* * Viewport1/2 static functions */ static void activate(IDirect3DViewport2Impl* This) { IDirect3DLightImpl* l; /* Activate all the lights associated with this context */ l = This->lights; while (l != NULL) { l->activate(l); l = l->next; } } /******************************************************************************* * Viewport1/2 Creation functions */ LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2) { IDirect3DViewport2Impl* vp; vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl)); vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private)); vp->ref = 1; ICOM_VTBL(vp) = &viewport2_vtable; vp->d3d.d3d2 = d3d2; vp->use_d3d2 = 1; vp->device.active_device2 = NULL; vp->activate = activate; vp->lights = NULL; ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0; return (LPDIRECT3DVIEWPORT2)vp; } LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1) { IDirect3DViewport2Impl* vp; vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl)); vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private)); vp->ref = 1; ICOM_VTBL(vp) = &viewport2_vtable; vp->d3d.d3d1 = d3d1; vp->use_d3d2 = 0; vp->device.active_device1 = NULL; vp->activate = activate; vp->lights = NULL; ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0; return (LPDIRECT3DVIEWPORT) vp; } /******************************************************************************* * IDirect3DViewport2 methods */ HRESULT WINAPI IDirect3DViewport2Impl_QueryInterface(LPDIRECT3DVIEWPORT2 iface, REFIID riid, LPVOID* ppvObj) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj); return S_OK; } ULONG WINAPI IDirect3DViewport2Impl_AddRef(LPDIRECT3DVIEWPORT2 iface) { ICOM_THIS(IDirect3DViewport2Impl,iface); TRACE("(%p)->()incrementing from %lu.\n", This, This->ref ); return ++(This->ref); } ULONG WINAPI IDirect3DViewport2Impl_Release(LPDIRECT3DVIEWPORT2 iface) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->() decrementing from %lu.\n", This, This->ref ); if (!--(This->ref)) { HeapFree(GetProcessHeap(),0,This->private); HeapFree(GetProcessHeap(),0,This); return 0; } return This->ref; } /*** IDirect3DViewport methods ***/ HRESULT WINAPI IDirect3DViewport2Impl_Initialize(LPDIRECT3DVIEWPORT2 iface, LPDIRECT3D d3d) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%p): stub\n", This, d3d); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_GetViewport(LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT lpvp) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%p): stub\n", This, lpvp); if (This->use_vp2 != 0) return DDERR_INVALIDPARAMS; *lpvp = This->viewport.vp1; return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_SetViewport(LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT lpvp) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%p): stub\n", This, lpvp); This->use_vp2 = 0; This->viewport.vp1 = *lpvp; TRACE("dwSize = %ld dwX = %ld dwY = %ld\n", lpvp->dwSize, lpvp->dwX, lpvp->dwY); TRACE("dwWidth = %ld dwHeight = %ld\n", lpvp->dwWidth, lpvp->dwHeight); TRACE("dvScaleX = %f dvScaleY = %f\n", lpvp->dvScaleX, lpvp->dvScaleY); TRACE("dvMaxX = %f dvMaxY = %f\n", lpvp->dvMaxX, lpvp->dvMaxY); TRACE("dvMinZ = %f dvMaxZ = %f\n", lpvp->dvMinZ, lpvp->dvMaxZ); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_TransformVertices(LPDIRECT3DVIEWPORT2 iface, DWORD dwVertexCount, LPD3DTRANSFORMDATA lpData, DWORD dwFlags, LPDWORD lpOffScreen) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%8ld,%p,%08lx,%p): stub\n", This, dwVertexCount, lpData, dwFlags, lpOffScreen); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_LightElements(LPDIRECT3DVIEWPORT2 iface, DWORD dwElementCount, LPD3DLIGHTDATA lpData) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%8ld,%p): stub\n", This, dwElementCount, lpData); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_SetBackground(LPDIRECT3DVIEWPORT2 iface, D3DMATERIALHANDLE hMat) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%08lx): stub\n", This, (DWORD) hMat); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_GetBackground(LPDIRECT3DVIEWPORT2 iface, LPD3DMATERIALHANDLE lphMat, LPBOOL lpValid) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%p,%p): stub\n", This, lphMat, lpValid); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_SetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface, LPDIRECTDRAWSURFACE lpDDSurface) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%p): stub\n", This, lpDDSurface); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_GetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface, LPDIRECTDRAWSURFACE* lplpDDSurface, LPBOOL lpValid) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%p,%p): stub\n", This, lplpDDSurface, lpValid); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_Clear(LPDIRECT3DVIEWPORT2 iface, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags) { ICOM_THIS(IDirect3DViewport2Impl,iface); GLboolean ztest; FIXME("(%p)->(%8ld,%p,%08lx): stub\n", This, dwCount, lpRects, dwFlags); /* For the moment, ignore the rectangles */ if (This->device.active_device1 != NULL) { /* Get the rendering context */ if (This->use_d3d2) This->device.active_device2->set_context(This->device.active_device2); else This->device.active_device1->set_context(This->device.active_device1); } /* Clears the screen */ ENTER_GL(); glGetBooleanv(GL_DEPTH_TEST, &ztest); glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthMask(ztest); LEAVE_GL(); return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_AddLight(LPDIRECT3DVIEWPORT2 iface, LPDIRECT3DLIGHT lpLight) { ICOM_THIS(IDirect3DViewport2Impl,iface); IDirect3DLightImpl* ilpLight=(IDirect3DLightImpl*)lpLight; FIXME("(%p)->(%p): stub\n", This, ilpLight); /* Add the light in the 'linked' chain */ ilpLight->next = This->lights; This->lights = ilpLight; /* If active, activate the light */ if (This->device.active_device1 != NULL) { D3DVPRIVATE(This); D3DLPRIVATE(ilpLight); /* Get the rendering context */ if (This->use_d3d2) This->device.active_device2->set_context(This->device.active_device2); else This->device.active_device1->set_context(This->device.active_device1); /* Activate the light */ dlpriv->light_num = dvpriv->nextlight++; ilpLight->activate(ilpLight); } return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_DeleteLight(LPDIRECT3DVIEWPORT2 iface, LPDIRECT3DLIGHT lpLight) { ICOM_THIS(IDirect3DViewport2Impl,iface); IDirect3DLightImpl** currentlplpLight; TRACE("(%p)->(%p): stub\n", This, lpLight); currentlplpLight = &(This->lights); while(*currentlplpLight) { if (*currentlplpLight == (IDirect3DLightImpl*)lpLight) { *currentlplpLight = (*currentlplpLight)->next; return DD_OK; } currentlplpLight = &((*currentlplpLight)->next); } return DDERR_INVALIDOBJECT; } HRESULT WINAPI IDirect3DViewport2Impl_NextLight(LPDIRECT3DVIEWPORT2 iface, LPDIRECT3DLIGHT lpLight, LPDIRECT3DLIGHT* lplpLight, DWORD dwFlags) { ICOM_THIS(IDirect3DViewport2Impl,iface); FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpLight, lplpLight, dwFlags); return DD_OK; } /*** IDirect3DViewport2 methods ***/ HRESULT WINAPI IDirect3DViewport2Impl_GetViewport2(LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT2 lpViewport2) { ICOM_THIS(IDirect3DViewport2Impl,iface); TRACE("(%p)->(%p)\n", This, lpViewport2); if (This->use_vp2 != 1) return DDERR_INVALIDPARAMS; *lpViewport2 = This->viewport.vp2; return DD_OK; } HRESULT WINAPI IDirect3DViewport2Impl_SetViewport2(LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT2 lpViewport2) { ICOM_THIS(IDirect3DViewport2Impl,iface); TRACE("(%p)->(%p)\n", This, lpViewport2); TRACE("dwSize = %ld dwX = %ld dwY = %ld\n", lpViewport2->dwSize, lpViewport2->dwX, lpViewport2->dwY); TRACE("dwWidth = %ld dwHeight = %ld\n", lpViewport2->dwWidth, lpViewport2->dwHeight); TRACE("dvClipX = %f dvClipY = %f\n", lpViewport2->dvClipX, lpViewport2->dvClipY); TRACE("dvClipWidth = %f dvClipHeight = %f\n", lpViewport2->dvClipWidth, lpViewport2->dvClipHeight); TRACE("dvMinZ = %f dvMaxZ = %f\n", lpViewport2->dvMinZ, lpViewport2->dvMaxZ); This->viewport.vp2 = *lpViewport2; This->use_vp2 = 1; return DD_OK; } /******************************************************************************* * IDirect3DViewport1/2 VTable */ static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE /*** IUnknown methods ***/ IDirect3DViewport2Impl_QueryInterface, IDirect3DViewport2Impl_AddRef, IDirect3DViewport2Impl_Release, /*** IDirect3DViewport methods ***/ IDirect3DViewport2Impl_Initialize, IDirect3DViewport2Impl_GetViewport, IDirect3DViewport2Impl_SetViewport, IDirect3DViewport2Impl_TransformVertices, IDirect3DViewport2Impl_LightElements, IDirect3DViewport2Impl_SetBackground, IDirect3DViewport2Impl_GetBackground, IDirect3DViewport2Impl_SetBackgroundDepth, IDirect3DViewport2Impl_GetBackgroundDepth, IDirect3DViewport2Impl_Clear, IDirect3DViewport2Impl_AddLight, IDirect3DViewport2Impl_DeleteLight, IDirect3DViewport2Impl_NextLight, /*** IDirect3DViewport2 methods ***/ IDirect3DViewport2Impl_GetViewport2, IDirect3DViewport2Impl_SetViewport2 }; #else /* HAVE_OPENGL */ LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1) { ERR("Should not be called...\n"); return NULL; } LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2) { ERR("Should not be called...\n"); return NULL; } #endif /* HAVE_OPENGL */