diff --git a/dlls/ddraw/d3ddevice/main.c b/dlls/ddraw/d3ddevice/main.c index 36a8c346228..4de426e501b 100644 --- a/dlls/ddraw/d3ddevice/main.c +++ b/dlls/ddraw/d3ddevice/main.c @@ -1100,15 +1100,24 @@ Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface, ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3); + /* Do nothing if the specified viewport is the same as the current one */ + if (This->current_viewport == ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3)) + return DD_OK; + /* Should check if the viewport was added or not */ + /* Release previous viewport and AddRef the new one */ + if (This->current_viewport) + IDirect3DViewport3_Release(ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3)); + IDirect3DViewport3_AddRef(lpDirect3DViewport3); + /* Set this viewport as the current viewport */ This->current_viewport = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3); /* Activate this viewport */ This->current_viewport->active_device = This; This->current_viewport->activate(This->current_viewport); - + return DD_OK; } @@ -1120,6 +1129,10 @@ Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface, TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3DViewport3); *lplpDirect3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3); + + /* AddRef the returned viewport */ + IDirect3DViewport3_AddRef(*lplpDirect3DViewport3); + TRACE(" returning interface %p\n", *lplpDirect3DViewport3); return DD_OK; diff --git a/dlls/ddraw/d3dviewport.c b/dlls/ddraw/d3dviewport.c index b0d324271af..8309bc3328f 100644 --- a/dlls/ddraw/d3dviewport.c +++ b/dlls/ddraw/d3dviewport.c @@ -180,6 +180,7 @@ Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface, LPD3DVIEWPORT lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); + LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p/%p)->(%p)\n", This, iface, lpData); if (TRACE_ON(ddraw)) { @@ -196,7 +197,14 @@ Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface, */ This->viewports.vp1.dvMinZ = 0.0; This->viewports.vp1.dvMaxZ = 1.0; - + + if (This->active_device) { + IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport); + if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This) + This->activate(This); + IDirect3DViewport3_Release(current_viewport); + } + return DD_OK; } @@ -402,6 +410,7 @@ Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface, LPD3DVIEWPORT2 lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); + LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p/%p)->(%p)\n", This, iface, lpData); if (TRACE_ON(ddraw)) { @@ -412,6 +421,14 @@ Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface, This->use_vp2 = 1; memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2)); memcpy(&(This->viewports.vp2), lpData, lpData->dwSize); + + if (This->active_device) { + IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), ¤t_viewport); + if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This) + This->activate(This); + IDirect3DViewport3_Release(current_viewport); + } + return DD_OK; }