DirectX uses a R/Z transform to translate a texture but under OpenGL a
Q transform must be used instead.

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index d9bb39c..6a39f76 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1615,7 +1615,7 @@
             int tex = d3dts - D3DTS_TEXTURE0;
             GLACTIVETEXTURE(tex);
             set_texture_matrix((float *)lpmatrix,
-                               This->updateStateBlock->textureState[tex][WINED3DTSS_TEXTURETRANSFORMFLAGS]);
+                               This->updateStateBlock->textureState[tex][WINED3DTSS_TEXTURETRANSFORMFLAGS], (This->stateBlock->textureState[tex][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != D3DTSS_TCI_PASSTHRU);
         }
 
     } else if (d3dts == D3DTS_VIEW) { /* handle the VIEW matrice */
@@ -3956,6 +3956,7 @@
               glDisable(GL_TEXTURE_GEN_S);
               glDisable(GL_TEXTURE_GEN_T);
               glDisable(GL_TEXTURE_GEN_R);
+              glDisable(GL_TEXTURE_GEN_Q);
               checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R)");
               break;
 
@@ -4070,6 +4071,7 @@
                 glDisable(GL_TEXTURE_GEN_S);
                 glDisable(GL_TEXTURE_GEN_T);
                 glDisable(GL_TEXTURE_GEN_R);
+                glDisable(GL_TEXTURE_GEN_Q);
                 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %lx\n", Value);
                 break;
             }
@@ -4078,7 +4080,7 @@
 
         /* Unhandled */
     case WINED3DTSS_TEXTURETRANSFORMFLAGS :
-        set_texture_matrix((float *)&This->stateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], Value);
+        set_texture_matrix((float *)&This->stateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], Value, (This->stateBlock->textureState[Stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != D3DTSS_TCI_PASSTHRU);
         break;
 
     case WINED3DTSS_BUMPENVMAT00          :
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index b93111c..234e48f 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1456,11 +1456,12 @@
 #endif
 
 /* Setup this textures matrix according to the texture flags*/
-void set_texture_matrix(const float *smat, DWORD flags)
+void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords)
 {
     float mat[16];
 
     glMatrixMode(GL_TEXTURE);
+    checkGLcall("glMatrixMode(GL_TEXTURE)");
 
     if (flags == D3DTTFF_DISABLE) {
         glLoadIdentity();
@@ -1470,28 +1471,38 @@
 
     if (flags == (D3DTTFF_COUNT1|D3DTTFF_PROJECTED)) {
         ERR("Invalid texture transform flags: D3DTTFF_COUNT1|D3DTTFF_PROJECTED\n");
-        checkGLcall("glLoadIdentity()");
         return;
     }
 
-    memcpy(mat, smat, 16*sizeof(float));
+    memcpy(mat, smat, 16 * sizeof(float));
 
     switch (flags & ~D3DTTFF_PROJECTED) {
-    case D3DTTFF_COUNT1: mat[1] = mat[5] = mat[9] = mat[13] = 0;
+    case D3DTTFF_COUNT1: mat[1] = mat[5] = mat[13] = 0;
     case D3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
     default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
     }
 
-    if (flags & D3DTTFF_PROJECTED) switch (flags & ~D3DTTFF_PROJECTED) {
-    case D3DTTFF_COUNT2:
-        mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
-        mat[1] = mat[5] = mat[9] = mat[13] = 0;
+    if (flags & D3DTTFF_PROJECTED) {
+        switch (flags & ~D3DTTFF_PROJECTED) {
+        case D3DTTFF_COUNT1:
+            mat[9] = 0;
         break;
-    case D3DTTFF_COUNT3:
-        mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
-        mat[2] = mat[6] = mat[10] = mat[14] = 0;
-        break;
+        case D3DTTFF_COUNT2:
+            mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
+            mat[1] = mat[5] = mat[9] = mat[13] = 0;
+            break;
+        case D3DTTFF_COUNT3:
+            mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
+            mat[2] = mat[6] = mat[10] = mat[14] = 0;
+            break;
+        }
+    } else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
+        mat[12] = mat[8];
+        mat[13] = mat[9];
+        mat[8] = 0;
+        mat[9] = 0;
     }
+
     glLoadMatrixf(mat);
     checkGLcall("glLoadMatrixf(mat)");
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 10d753d..5ac2842 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -937,7 +937,7 @@
 /* Routines for GL <-> D3D values */
 GLenum StencilOp(DWORD op);
 void   set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
-void   set_texture_matrix(const float *smat, DWORD flags);
+void   set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords);
 void   GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
 
 SHORT  D3DFmtGetBpp(IWineD3DDeviceImpl* This, D3DFORMAT fmt);