Changelog: - actually use the background color when Clear-ing - replace glOrtho by a hand-built matrix - fix applications doing SetTransform + using XYZRHW vertices -- Lionel Ulmer - http://www.bbrox.org/
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3ddevice/mesa.c 2002-12-23 18:34:52.000000000 +0100 +++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3ddevice/mesa.c 2002-12-23 22:09:39.000000000 +0100 @@ -644,11 +644,14 @@ } break; default: - ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType); + ERR("Unknown transform type %08x !!!\n", dtstTransformStateType); break; } LEAVE_GL(); + /* And set the 'matrix changed' flag */ + glThis->matrices_changed = TRUE; + return DD_OK; } @@ -695,7 +698,9 @@ BOOLEAN vertex_transformed, BOOLEAN vertex_lit) { /* Puts GL in the correct lighting / transformation mode */ - if ((glThis->last_vertices_transformed == TRUE) && (vertex_transformed == FALSE)) { + if ((vertex_transformed == FALSE) && + ((glThis->last_vertices_transformed == TRUE) || + (glThis->matrices_changed == TRUE))) { /* Need to put the correct transformation again if we go from Transformed vertices to non-transformed ones. */ @@ -704,23 +709,30 @@ glMultMatrixf((float *) glThis->world_mat); glMatrixMode(GL_PROJECTION); glLoadMatrixf((float *) glThis->proj_mat); - } else if ((glThis->last_vertices_transformed == FALSE) && (vertex_transformed == TRUE)) { - GLdouble height, width, minZ, maxZ, minX, minY; - + } else if ((vertex_transformed == TRUE) && + ((glThis->last_vertices_transformed == FALSE) || + (glThis->matrices_changed == TRUE))) { + GLfloat height, width; + GLfloat trans_mat[16]; + + width = glThis->parent.surface->surface_desc.dwWidth; + height = glThis->parent.surface->surface_desc.dwHeight; + + /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates + to OpenGL screen coordinates (ie the upper left corner is not the same). + For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between + -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */ + trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0; + trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0; + trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0; + trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0; + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - minX = (GLdouble) glThis->parent.active_viewport.dwX; - minY = (GLdouble) glThis->parent.active_viewport.dwY; - height = (GLdouble) glThis->parent.active_viewport.dwHeight; - width = (GLdouble) glThis->parent.active_viewport.dwWidth; - minZ = (GLdouble) glThis->parent.active_viewport.dvMinZ; - maxZ = (GLdouble) glThis->parent.active_viewport.dvMaxZ; - - glOrtho(minX, width, height, minY, -minZ, -maxZ); + glLoadMatrixf(trans_mat); } + glThis->matrices_changed = FALSE; if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) { glEnable(GL_LIGHTING); @@ -900,12 +912,15 @@ } inline static void handle_xyzrhw(D3DVALUE *coords) { if (coords[3] < 0.00001) - glVertex3f(coords[0], coords[1], coords[2]); - else - glVertex4f(coords[0] / coords[3], - coords[1] / coords[3], - coords[2] / coords[3], - 1.0 / coords[3]); + glVertex3fv(coords); + else { + GLfloat w = 1.0 / coords[3]; + + glVertex4f(coords[0] * w, + coords[1] * w, + coords[2] * w, + w); + } } inline static void handle_normal(D3DVALUE *coords) { glNormal3fv(coords); @@ -1148,7 +1163,7 @@ } for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { strided.textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset; - current_offset += 2*sizeof(D3DVALUE); + current_offset += 2 * sizeof(D3DVALUE); } strided.position.dwStride = current_offset; strided.normal.dwStride = current_offset; @@ -1837,7 +1856,8 @@ gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float)); gl_object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float)); gl_object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float)); - + gl_object->matrices_changed = TRUE; + memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float)); memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float)); memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float)); --- /home/ulmer/Wine/wine_base//dlls/ddraw/d3d_private.h 2002-12-23 18:34:52.000000000 +0100 +++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3d_private.h 2002-12-23 21:36:16.000000000 +0100 @@ -122,6 +122,9 @@ /* Lights list */ IDirect3DLightImpl *lights; + + /* Background material */ + IDirect3DMaterialImpl *background; }; /***************************************************************************** --- /home/ulmer/Wine/wine_base//dlls/ddraw/d3dviewport.c 2002-12-23 18:34:52.000000000 +0100 +++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3dviewport.c 2002-12-23 22:10:26.000000000 +0100 @@ -27,7 +27,6 @@ #include "wine/debug.h" #include "d3d_private.h" -#include "mesa_private.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); @@ -193,7 +192,15 @@ D3DMATERIALHANDLE hMat) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, (DWORD) hMat); + TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat); + + This->background = (IDirect3DMaterialImpl *) hMat; + TRACE(" setting background color : %f %f %f %f\n", + This->background->mat.u.diffuse.u1.r, + This->background->mat.u.diffuse.u2.g, + This->background->mat.u.diffuse.u3.b, + This->background->mat.u.diffuse.u4.a); + return DD_OK; } @@ -233,12 +240,27 @@ DWORD dwFlags) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); + DWORD color = 0x00000000; + TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags); if (This->active_device == NULL) { ERR(" Trying to clear a viewport not attached to a device !\n"); return D3DERR_VIEWPORTHASNODEVICE; } - return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, 0x00000000, 0.0, 0x00000000); + if (dwFlags & D3DCLEAR_TARGET) { + if (This->background == NULL) { + ERR(" Trying to clear the color buffer without background material !\n"); + } else { + color = + ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) | + ((int) ((This->background->mat.u.diffuse.u2.g) * 255) << 8) | + ((int) ((This->background->mat.u.diffuse.u3.b) * 255) << 0) | + ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24); + } + } + return This->active_device->clear(This->active_device, dwCount, lpRects, + dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET), + color, 1.0, 0x00000000); } HRESULT WINAPI --- /home/ulmer/Wine/wine_base//dlls/ddraw/mesa_private.h 2002-12-22 12:06:18.000000000 +0100 +++ /home/ulmer/Wine/wine_work//dlls/ddraw/mesa_private.h 2002-12-23 22:09:54.000000000 +0100 @@ -127,7 +127,8 @@ D3DMATRIX *world_mat; D3DMATRIX *view_mat; D3DMATRIX *proj_mat; - + BOOLEAN matrices_changed; + Display *display; Drawable drawable; } IDirect3DDeviceGLImpl;