- create a function to set the various transformation matrices to
  factorize the code between the various code path
- fixed some logging stuff

diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c
index a67f396..bc5176d 100644
--- a/dlls/ddraw/d3ddevice/mesa.c
+++ b/dlls/ddraw/d3ddevice/mesa.c
@@ -588,88 +588,6 @@
     return DD_OK;
 }
 
-HRESULT WINAPI
-GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
-                                            D3DTRANSFORMSTATETYPE dtstTransformStateType,
-                                            LPD3DMATRIX lpD3DMatrix)
-{
-    ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
-    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
-
-    TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
-
-    ENTER_GL();
-
-    /* Using a trial and failure approach, I found that the order of
-       Direct3D transformations that works best is :
-
-       ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
-
-       As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
-       OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
-
-       If anyone has a good explanation of the three different matrices in
-       the SDK online documentation, feel free to point it to me. For example,
-       which matrices transform lights ? In OpenGL only the PROJECTION matrix
-       transform the lights, not the MODELVIEW. Using the matrix names, I
-       supposed that PROJECTION and VIEW (all 'camera' related names) do
-       transform lights, but WORLD do not. It may be wrong though... */
-
-    /* After reading through both OpenGL and Direct3D documentations, I
-       thought that D3D matrices were written in 'line major mode' transposed
-       from OpenGL's 'column major mode'. But I found out that a simple memcpy
-       works fine to transfer one matrix format to the other (it did not work
-       when transposing)....
-
-       So :
-         1) are the documentations wrong
-	 2) does the matrix work even if they are not read correctly
-	 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
-            loading using glLoadMatrix ?
-
-       Anyway, I always use 'conv_mat' to transfer the matrices from one format
-       to the other so that if I ever find out that I need to transpose them, I
-       will able to do it quickly, only by changing the macro conv_mat. */
-
-    switch (dtstTransformStateType) {
-        case D3DTRANSFORMSTATE_WORLD: {
-	    TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
-	    conv_mat(lpD3DMatrix, This->world_mat);
-	    if (glThis->last_vertices_transformed == FALSE) {
-	        glMatrixMode(GL_MODELVIEW);
-		glLoadMatrixf((float *) This->view_mat);
-		glMultMatrixf((float *) This->world_mat);
-	    }
-	} break;
-
-	case D3DTRANSFORMSTATE_VIEW: {
-	    TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
-	    conv_mat(lpD3DMatrix, This->view_mat);
-	    if (glThis->last_vertices_transformed == FALSE) {
-	        glMatrixMode(GL_MODELVIEW);
-		glLoadMatrixf((float *) This->view_mat);
-		glMultMatrixf((float *) This->world_mat);
-	    }
-	} break;
-
-	case D3DTRANSFORMSTATE_PROJECTION: {
-	    TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
-	    conv_mat(lpD3DMatrix, This->proj_mat);
-	    if (glThis->last_vertices_transformed == FALSE) {
-	        glMatrixMode(GL_PROJECTION);
-		glLoadMatrixf((float *) This->proj_mat);
-	    }
-	} break;
-
-	default:
-	    ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
-	    break;
-    }
-    LEAVE_GL();
-
-    return DD_OK;
-}
-
 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
 {
     switch (d3dpt) {
@@ -716,22 +634,23 @@
   
     /* Puts GL in the correct lighting / transformation mode */
     if ((vertex_transformed == FALSE) && 
-	(glThis->last_vertices_transformed == TRUE)) {
+	(glThis->transform_state != GL_TRANSFORM_NORMAL)) {
         /* Need to put the correct transformation again if we go from Transformed
 	   vertices to non-transformed ones.
 	*/
-        glMatrixMode(GL_MODELVIEW);
-	glLoadMatrixf((float *) This->view_mat);
-	glMultMatrixf((float *) This->world_mat);
-	glMatrixMode(GL_PROJECTION);
-	glLoadMatrixf((float *) This->proj_mat);
+        This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
+			   This->world_mat, This->view_mat, This->proj_mat);
+	glThis->transform_state = GL_TRANSFORM_NORMAL;
 
-	if (glThis->render_state.fog_on == TRUE) glEnable(GL_FOG);
+	if (glThis->render_state.fog_on == TRUE)
+	    glEnable(GL_FOG);
     } else if ((vertex_transformed == TRUE) &&
-	       (glThis->last_vertices_transformed == FALSE)) {
+	       (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
         GLfloat height, width;
 	GLfloat trans_mat[16];
 	
+	glThis->transform_state = GL_TRANSFORM_ORTHO;
+	
 	width = glThis->parent.surface->surface_desc.dwWidth;
 	height = glThis->parent.surface->surface_desc.dwHeight;
 
@@ -770,9 +689,6 @@
 	    }
 	}
     }
-
-    /* And save the current state */
-    glThis->last_vertices_transformed = vertex_transformed;
 }
 
 
@@ -883,67 +799,6 @@
     return ret_value;
 }
 
-DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
-{
-    DWORD size = 0;
-    DWORD elts = 0;
-    
-    if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
-    if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
-    if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
-    switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
-        case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
-        case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
-	default: TRACE(" matrix weighting not handled yet...\n");
-    }
-    size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
-    elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
-
-    if (elements) *elements = elts;
-
-    return size;
-}
-
-void dump_flexible_vertex(DWORD d3dvtVertexType)
-{
-    static const flag_info flags[] = {
-        FE(D3DFVF_NORMAL),
-	FE(D3DFVF_RESERVED1),
-	FE(D3DFVF_DIFFUSE),
-	FE(D3DFVF_SPECULAR)
-    };
-    int i;
-    
-    if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
-    switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
-#define GEN_CASE(a) case a: DPRINTF(#a " "); break
-        GEN_CASE(D3DFVF_XYZ);
-	GEN_CASE(D3DFVF_XYZRHW);
-	GEN_CASE(D3DFVF_XYZB1);
-	GEN_CASE(D3DFVF_XYZB2);
-	GEN_CASE(D3DFVF_XYZB3);
-	GEN_CASE(D3DFVF_XYZB4);
-	GEN_CASE(D3DFVF_XYZB5);
-    }
-    DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
-    switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
-        GEN_CASE(D3DFVF_TEX0);
-	GEN_CASE(D3DFVF_TEX1);
-	GEN_CASE(D3DFVF_TEX2);
-	GEN_CASE(D3DFVF_TEX3);
-	GEN_CASE(D3DFVF_TEX4);
-	GEN_CASE(D3DFVF_TEX5);
-	GEN_CASE(D3DFVF_TEX6);
-	GEN_CASE(D3DFVF_TEX7);
-	GEN_CASE(D3DFVF_TEX8);
-    }
-#undef GEN_CASE
-    for (i = 0; i < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); i++) {
-        DPRINTF(" T%d-s%ld", i + 1, (((d3dvtVertexType >> (16 + (2 * i))) + 1) & 0x03) + 1);
-    }
-    DPRINTF("\n");
-}
-
 /* These are the various handler used in the generic path */
 inline static void handle_xyz(D3DVALUE *coords) {
     glVertex3fv(coords);
@@ -1745,7 +1600,7 @@
     XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
     XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
     XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
-    XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
+    XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
     XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
     XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
     XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
@@ -2035,6 +1890,30 @@
      return DDERR_INVALIDPARAMS;
 }
 
+void
+d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
+		       D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
+{
+    if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
+        glMatrixMode(GL_MODELVIEW);
+	glLoadMatrixf((float *) view_mat);
+	glMultMatrixf((float *) world_mat);
+    }
+    if ((matrices & PROJMAT_CHANGED) != 0) {
+	glMatrixMode(GL_PROJECTION);
+	glLoadMatrixf((float *) proj_mat);
+    }
+}
+
+void
+d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
+{
+    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
+    if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
+        /* This will force an update of the transform state at the next drawing. */
+        glThis->transform_state = GL_TRANSFORM_NONE;
+    }
+}
 
 /* TODO for both these functions :
     - change / restore OpenGL parameters for pictures transfers in case they are ever modified
@@ -2152,6 +2031,8 @@
     object->surface = surface;
     object->set_context = set_context;
     object->clear = d3ddevice_clear;
+    object->set_matrices = d3ddevice_set_matrices;
+    object->matrices_updated = d3ddevice_matrices_updated;
 
     TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);