[D3D] Some viewport / clear fixes
Lionel Ulmer
lionel.ulmer at free.fr
Sun May 18 16:47:26 CDT 2003
Apparently, DungeonSiege loves to play with viewports and Clear rectangles
(which were not supported correctly in the D3D7 code as they were never
different from full screen).
Changelog:
- added support for non-full screen viewports and clearing
--
Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- dlls/ddraw_CVS/d3ddevice/main.c Fri May 16 09:51:47 2003
+++ dlls/ddraw/d3ddevice/main.c Sun May 18 20:52:03 2003
@@ -1087,25 +1087,8 @@
/* Activate this viewport */
This->current_viewport->active_device = This;
- This->current_viewport->activate(This->current_viewport);
+ This->current_viewport->activate(This->current_viewport);
- /* And copy the values in the structure used by the device */
- if (This->current_viewport->use_vp2) {
- This->active_viewport.dwX = This->current_viewport->viewports.vp2.dwX;
- This->active_viewport.dwY = This->current_viewport->viewports.vp2.dwY;
- This->active_viewport.dwHeight = This->current_viewport->viewports.vp2.dwHeight;
- This->active_viewport.dwWidth = This->current_viewport->viewports.vp2.dwWidth;
- This->active_viewport.dvMinZ = This->current_viewport->viewports.vp2.dvMinZ;
- This->active_viewport.dvMaxZ = This->current_viewport->viewports.vp2.dvMaxZ;
- } else {
- This->active_viewport.dwX = This->current_viewport->viewports.vp1.dwX;
- This->active_viewport.dwY = This->current_viewport->viewports.vp1.dwY;
- This->active_viewport.dwHeight = This->current_viewport->viewports.vp1.dwHeight;
- This->active_viewport.dwWidth = This->current_viewport->viewports.vp1.dwWidth;
- This->active_viewport.dvMinZ = This->current_viewport->viewports.vp1.dvMinZ;
- This->active_viewport.dvMaxZ = This->current_viewport->viewports.vp1.dvMaxZ;
- }
-
return DD_OK;
}
--- dlls/ddraw_CVS/d3ddevice/mesa.c Sun May 18 23:27:25 2003
+++ dlls/ddraw/d3ddevice/mesa.c Sun May 18 23:37:45 2003
@@ -2163,24 +2163,51 @@
TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
- if (dwIndex>=This->max_clipping_planes) {
+ 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]));
+ 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) );
+ glClipPlane( GL_CLIP_PLANE0 + dwIndex, (const GLdouble*) (&plane) );
return D3D_OK;
}
+HRESULT WINAPI
+GL_IDirect3DDeviceImpl_7_SetViewport(LPDIRECT3DDEVICE7 iface,
+ LPD3DVIEWPORT7 lpData)
+{
+ ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+ TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
+
+ if (TRACE_ON(ddraw)) {
+ TRACE(" viewport is : \n");
+ TRACE(" - dwX = %ld dwY = %ld\n",
+ lpData->dwX, lpData->dwY);
+ TRACE(" - dwWidth = %ld dwHeight = %ld\n",
+ lpData->dwWidth, lpData->dwHeight);
+ TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
+ lpData->dvMinZ, lpData->dvMaxZ);
+ }
+ This->active_viewport = *lpData;
+
+ /* Set the viewport */
+ glDepthRange(lpData->dvMinZ, lpData->dvMaxZ);
+ glViewport(lpData->dwX,
+ This->surface->surface_desc.dwHeight - (lpData->dwHeight + lpData->dwY),
+ lpData->dwWidth, lpData->dwHeight);
+
+ return DD_OK;
+}
+
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
#else
@@ -2203,7 +2230,7 @@
XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
- XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
+ XCAST(SetViewport) GL_IDirect3DDeviceImpl_7_SetViewport,
XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
@@ -2403,6 +2430,8 @@
GLbitfield bitfield = 0;
GLint old_stencil_clear_value;
GLfloat old_color_clear_value[4];
+ D3DRECT rect;
+ int i;
TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
if (TRACE_ON(ddraw)) {
@@ -2415,10 +2444,16 @@
}
}
- if (dwCount > 1) {
- WARN(" Warning, this function only for now clears the whole screen...\n");
+ if (dwCount == 0) {
+ /* Not sure if this is really needed... */
+ dwCount = 1;
+ rect.u1.x1 = 0;
+ rect.u2.y1 = 0;
+ rect.u3.x2 = This->surface->surface_desc.dwWidth;
+ rect.u4.y2 = This->surface->surface_desc.dwHeight;
+ lpRects = ▭
}
-
+
/* Clears the screen */
ENTER_GL();
if (dwFlags & D3DCLEAR_ZBUFFER) {
@@ -2444,8 +2479,14 @@
((dwColor >> 24) & 0xFF) / 255.0);
TRACE(" color value (ARGB) : %08lx\n", dwColor);
}
-
- glClear(bitfield);
+
+ glEnable(GL_SCISSOR_TEST);
+ for (i = 0; i < dwCount; i++) {
+ glScissor(lpRects[i].u1.x1, This->surface->surface_desc.dwHeight - lpRects[i].u4.y2,
+ lpRects[i].u3.x2 - lpRects[i].u1.x1, lpRects[i].u4.y2 - lpRects[i].u2.y1);
+ glClear(bitfield);
+ }
+ glDisable(GL_SCISSOR_TEST);
if (dwFlags & D3DCLEAR_ZBUFFER) {
glDepthMask(ztest);
@@ -2477,7 +2518,7 @@
/* This is easy to handle for the D3D Device... */
DWORD color = lpbltfx->u5.dwFillColor;
TRACE(" executing D3D Device override.\n");
- d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
+ d3ddevice_clear(This->d3ddevice, 1, rdst, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
return DD_OK;
}
return DDERR_INVALIDPARAMS;
--- dlls/ddraw_CVS/d3dviewport.c Thu Jan 30 22:07:23 2003
+++ dlls/ddraw/d3dviewport.c Sun May 18 20:54:28 2003
@@ -34,7 +34,8 @@
static void activate(IDirect3DViewportImpl* This) {
IDirect3DLightImpl* light;
-
+ D3DVIEWPORT7 vp;
+
/* Activate all the lights associated with this context */
light = This->lights;
@@ -42,6 +43,26 @@
light->activate(light);
light = light->next;
}
+
+ /* And copy the values in the structure used by the device */
+ if (This->use_vp2) {
+ vp.dwX = This->viewports.vp2.dwX;
+ vp.dwY = This->viewports.vp2.dwY;
+ vp.dwHeight = This->viewports.vp2.dwHeight;
+ vp.dwWidth = This->viewports.vp2.dwWidth;
+ vp.dvMinZ = This->viewports.vp2.dvMinZ;
+ vp.dvMaxZ = This->viewports.vp2.dvMaxZ;
+ } else {
+ vp.dwX = This->viewports.vp1.dwX;
+ vp.dwY = This->viewports.vp1.dwY;
+ vp.dwHeight = This->viewports.vp1.dwHeight;
+ vp.dwWidth = This->viewports.vp1.dwWidth;
+ vp.dvMinZ = This->viewports.vp1.dvMinZ;
+ vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
+ }
+
+ /* And also set the viewport */
+ IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
}
More information about the wine-patches
mailing list