[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