Partially implemented kernel/user times in GetThreadTimes (based on a
[wine] / dlls / d3d8 / device.c
1 /*
2  * IDirect3DDevice8 implementation
3  *
4  * Copyright 2002 Jason Edmeades
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <math.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winuser.h"
25 #include "wingdi.h"
26 #include "wine/debug.h"
27
28 #include "d3d8_private.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31
32 /* CreateVertexShader can return > 0xFFFF */
33 #define VS_HIGHESTFIXEDFXF 0xF0000000
34
35 /* Used for CreateStateBlock */
36 #define NUM_SAVEDPIXELSTATES_R     38
37 #define NUM_SAVEDPIXELSTATES_T     27
38 #define NUM_SAVEDVERTEXSTATES_R    33
39 #define NUM_SAVEDVERTEXSTATES_T    2
40
41 /*
42  * Utility functions or macros
43  */
44 #define conv_mat(mat,gl_mat)                    \
45 {                                               \
46     TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
47     TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
48     TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
49     TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
50     memcpy(gl_mat, (mat), 16 * sizeof(float));      \
51 };
52
53 /*
54  * Globals
55  */
56 extern DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R];
57 extern DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T];
58 extern DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R];
59 extern DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T];
60
61 static const float idmatrix[16] = {
62     1.0, 0.0, 0.0, 0.0,
63     0.0, 1.0, 0.0, 0.0,
64     0.0, 0.0, 1.0, 0.0,
65     0.0, 0.0, 0.0, 1.0
66 };
67
68 /* Routine common to the draw primitive and draw indexed primitive routines
69    Doesnt use gl pointer arrays as I dont believe we can support the blending
70    coordinates that way.                                                      */
71
72 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
73                     int PrimitiveType,
74                     long NumPrimitives,
75                     BOOL  isIndexed,
76
77                     /* For Both:*/
78                     D3DFORMAT fvf,
79                     const void *vertexBufData,
80
81                     /* for Indexed: */
82                     long  StartVertexIndex,
83                     long  StartIdx,
84                     short idxBytes,
85                     const void *idxData) {
86
87     int vx_index;
88     int NumVertexes = NumPrimitives;
89
90     ICOM_THIS(IDirect3DDevice8Impl,iface);
91
92     /* Dont understand how to handle multiple streams, but if a fixed
93          FVF is passed in rather than a handle, it must use stream 0 */
94
95     if (This->StateBlock.VertexShader > VS_HIGHESTFIXEDFXF) {
96         FIXME("Cant handle created shaders yet\n");
97         return;
98     } else {
99
100         int                         skip = This->StateBlock.stream_stride[0];
101
102         BOOL                        normal;
103         BOOL                        isRHW;
104         BOOL                        isPtSize;
105         BOOL                        isDiffuse;
106         BOOL                        isSpecular;
107         int                         numTextures;
108         int                         textureNo;
109         const void                 *curVtx = NULL;
110         const short                *pIdxBufS = NULL;
111         const long                 *pIdxBufL = NULL;
112         const void                 *curPos;
113         BOOL                        isLightingOn = FALSE;
114
115         float x=0.0, y=0.0, z=0.0;             /* x,y,z coordinates          */
116         float nx=0.0, ny=0.0, nz=0.0;          /* normal x,y,z coordinates   */
117         float rhw=0.0;                         /* rhw                        */
118         float ptSize=0.0;                      /* Point size                 */
119         DWORD diffuseColor=0;                  /* Diffusre Color             */
120         DWORD specularColor=0;                 /* Specular Color             */
121
122         ENTER_GL();
123
124         if (isIndexed) {
125             if (idxBytes == 2) pIdxBufS = (short *) idxData;
126             else pIdxBufL = (long *) idxData;
127         }
128
129         /* Check vertex formats expected ? */
130         normal        = fvf & D3DFVF_NORMAL;
131         isRHW         = fvf & D3DFVF_XYZRHW;
132         /*numBlends     = 5 - ((~fvf) & 0xe);*/  /* There must be a simpler way? */
133         isPtSize      = fvf & D3DFVF_PSIZE;
134         isDiffuse     = fvf & D3DFVF_DIFFUSE;
135         isSpecular    = fvf & D3DFVF_SPECULAR;
136         numTextures =  (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
137
138         TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d)\n",
139               fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures);
140
141         /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is 
142            set by the appropriate render state                                    */
143         if (!normal) {
144             isLightingOn = glIsEnabled(GL_LIGHTING);
145             glDisable(GL_LIGHTING);
146             TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
147         }
148
149
150         if (isRHW) {
151
152             double height, width, minZ, maxZ;
153
154             /*
155                  * Already transformed vertex do not need transform
156                  * matrices. Reset all matrices to identity.
157                  * Leave the default matrix in world mode.
158                 */
159             glMatrixMode(GL_PROJECTION);
160             checkGLcall("glMatrixMode");
161             glLoadIdentity();
162             checkGLcall("glLoadIdentity");
163             glMatrixMode(GL_MODELVIEW);
164             checkGLcall("glMatrixMode");
165             glLoadIdentity();
166             checkGLcall("glLoadIdentity");
167             height = This->StateBlock.viewport.Height;
168             width = This->StateBlock.viewport.Width;
169             minZ = This->StateBlock.viewport.MinZ;
170             maxZ = This->StateBlock.viewport.MaxZ;
171             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
172             glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
173             checkGLcall("glOrtho");
174
175         } else {
176             glMatrixMode(GL_PROJECTION);
177                 checkGLcall("glMatrixMode");
178             glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
179             checkGLcall("glLoadMatrixf");
180
181             glMatrixMode(GL_MODELVIEW);
182             checkGLcall("glMatrixMode");
183             glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
184             checkGLcall("glLoadMatrixf");
185             glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
186             checkGLcall("glMultMatrixf");
187         }
188
189         /* Set OpenGL to the appropriate Primitive Type */
190         switch (PrimitiveType) {
191         case D3DPT_POINTLIST:
192             TRACE("glBegin, Start POINTS\n");
193             glBegin(GL_POINTS);
194             NumVertexes = NumPrimitives;
195             break;
196
197         case D3DPT_LINELIST:
198             TRACE("glBegin, Start LINES\n");
199             glBegin(GL_LINES);
200             NumVertexes = NumPrimitives * 2;
201             break;
202
203         case D3DPT_LINESTRIP:
204             TRACE("glBegin, Start LINE_STRIP\n");
205             glBegin(GL_LINE_STRIP);
206             NumVertexes = NumPrimitives + 1;
207             break;
208
209         case D3DPT_TRIANGLELIST:
210             TRACE("glBegin, Start TRIANGLES\n");
211             glBegin(GL_TRIANGLES);
212             NumVertexes = NumPrimitives * 3;
213             break;
214
215         case D3DPT_TRIANGLESTRIP:
216             TRACE("glBegin, Start TRIANGLE_STRIP\n");
217             glBegin(GL_TRIANGLE_STRIP);
218             NumVertexes = NumPrimitives + 2;
219             break;
220
221         case D3DPT_TRIANGLEFAN:
222             TRACE("glBegin, Start TRIANGLE_FAN\n");
223             glBegin(GL_TRIANGLE_FAN);
224             NumVertexes = NumPrimitives + 2;
225             break;
226
227         default:
228             FIXME("Unhandled primitive\n");
229             break;
230         }
231
232
233         /* Draw the primitives */
234         curVtx = vertexBufData + (StartVertexIndex * skip);
235
236         for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
237
238             if (!isIndexed) {
239                 curPos = curVtx;
240             } else {
241                 if (idxBytes == 2) {
242                     TRACE("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index]));
243                     curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
244                 } else {
245                     TRACE("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index]));
246                     curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
247                 }
248             }
249
250             /* Work through the vertex buffer */
251             x = *(float *)curPos;
252             curPos = curPos + sizeof(float);
253             y = *(float *)curPos;
254             curPos = curPos + sizeof(float);
255             z = *(float *)curPos;
256             curPos = curPos + sizeof(float);
257             TRACE("x,y,z=%f,%f,%f\n", x,y,z);
258
259             /* RHW follows, only if transformed */
260             if (isRHW) {
261                 rhw = *(float *)curPos;
262                 curPos = curPos + sizeof(float);
263                 TRACE("rhw=%f\n", rhw);
264             }
265
266
267             /* FIXME: Skip Blending data */
268
269             /* Vertex Normal Data (untransformed only) */
270             if (normal) {
271                 nx = *(float *)curPos;
272                 curPos = curPos + sizeof(float);
273                 ny = *(float *)curPos;
274                 curPos = curPos + sizeof(float);
275                 nz = *(float *)curPos;
276                 curPos = curPos + sizeof(float);
277                 TRACE("nx,ny,nz=%f,%f,%f\n", nx,ny,nz);
278             }
279
280             if (isPtSize) {
281                 ptSize = *(float *)curPos;
282                 curPos = curPos + sizeof(float);
283                 TRACE("ptSize=%f\n", ptSize);
284             }
285             if (isDiffuse) {
286                 diffuseColor = *(DWORD *)curPos;
287                 TRACE("diffuseColor=%lx\n", diffuseColor);
288                 curPos = curPos + sizeof(DWORD);
289             }
290             if (isSpecular) {
291                 specularColor = *(DWORD *)curPos;
292                 TRACE("specularColor=%lx\n", specularColor);
293                 curPos = curPos + sizeof(DWORD);
294             }
295
296             /* ToDo: Texture coords */
297             for (textureNo = 0;textureNo<numTextures; textureNo++) {
298
299                 float s,t,r,q;
300
301                 /* Query tex coords */
302                 if (This->StateBlock.textures[textureNo] != NULL) {
303                     switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
304                     case D3DRTYPE_TEXTURE:
305                         s = *(float *)curPos;
306                         curPos = curPos + sizeof(float);
307                         t = *(float *)curPos;
308                         curPos = curPos + sizeof(float);
309                         TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t);
310                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
311                         break;
312
313                     case D3DRTYPE_VOLUMETEXTURE:
314                         s = *(float *)curPos;
315                         curPos = curPos + sizeof(float);
316                         t = *(float *)curPos;
317                         curPos = curPos + sizeof(float);
318                         r = *(float *)curPos;
319                         curPos = curPos + sizeof(float);
320                         TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r);
321                         glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
322                         break;
323
324                     default:
325                         r=0;q=0; /* Avoid compiler warnings, need these vars later for other textures */
326                         FIXME("Unhandled texture type\n");
327                     }
328                 } else {
329                     /* Note I have seen a program actually do this, so just hide it and continue */
330                     TRACE("Very odd - texture requested in FVF but not bound!\n");
331                 }
332
333             }
334
335             /* Handle these vertexes */
336             if (isDiffuse) {
337                 glColor4f(((diffuseColor >> 16) & 0xFF) / 255.0,
338                           ((diffuseColor >>  8) & 0xFF) / 255.0,
339                           ((diffuseColor >>  0) & 0xFF) / 255.0,
340                           ((diffuseColor >> 24) & 0xFF) / 255.0);
341                 TRACE("glColor4f: r,g,b,a=%f,%f,%f,%f\n", ((diffuseColor >> 16) & 0xFF) / 255.0, ((diffuseColor >>  8) & 0xFF) / 255.0,
342                        ((diffuseColor >>  0) & 0xFF) / 255.0, ((diffuseColor >> 24) & 0xFF) / 255.0);
343             }
344
345             if (normal) {
346                 TRACE("Vertex: glVertex:x,y,z=%f,%f,%f  /  glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz);
347                 glNormal3f(nx, ny, nz);
348                 glVertex3f(x, y, z);
349
350             } else {
351                 if (rhw < 0.01) {
352                     TRACE("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z);
353                     glVertex3f(x, y, z);
354                 } else {
355                     TRACE("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw);
356                     glVertex4f(x / rhw, y / rhw, z / rhw, 1.0 / rhw);
357                 }
358             }
359
360             if (!isIndexed) {
361                 curVtx = curVtx + skip;
362             }
363         }
364
365         glEnd();
366         checkGLcall("glEnd and previous calls");
367
368         /* If no normals, restore previous lighting state */
369         if (!normal) {
370             if (isLightingOn) glEnable(GL_LIGHTING);
371             else glDisable(GL_LIGHTING);
372             TRACE("Restored lighting to original state\n");
373         }
374
375     }
376     LEAVE_GL();
377
378     TRACE("glEnd\n");
379 }
380
381 /*
382     Simple utility routines used for dx -> gl mapping of byte formats
383  */
384 SHORT bytesPerPixel(D3DFORMAT fmt) {
385     SHORT retVal;
386
387     switch (fmt) {
388     case D3DFMT_A4R4G4B4:         retVal = 2; break;
389     case D3DFMT_A8R8G8B8:         retVal = 4; break;
390     case D3DFMT_X8R8G8B8:         retVal = 4; break;
391     case D3DFMT_R8G8B8:           retVal = 3; break;
392     case D3DFMT_R5G6B5:           retVal = 2; break;
393     case D3DFMT_A1R5G5B5:         retVal = 2; break;
394     default:
395         FIXME("Unhandled fmt %d\n", fmt);
396         retVal = 4;
397     }
398
399
400     TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
401     return retVal;
402 }
403
404 GLint fmt2glintFmt(D3DFORMAT fmt) {
405     GLint retVal;
406
407     switch (fmt) {
408     case D3DFMT_A4R4G4B4:         retVal = GL_RGBA4; break;
409     case D3DFMT_A8R8G8B8:         retVal = GL_RGBA8; break;
410     case D3DFMT_X8R8G8B8:         retVal = GL_RGB8; break;
411     case D3DFMT_R8G8B8:           retVal = GL_RGB8; break;
412     case D3DFMT_R5G6B5:           retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
413     case D3DFMT_A1R5G5B5:         retVal = GL_RGB5_A1; break;
414     default:
415         FIXME("Unhandled fmt %d\n", fmt);
416         retVal = 4;
417     }
418     TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
419     return retVal;
420 }
421 GLenum fmt2glFmt(D3DFORMAT fmt) {
422     GLenum retVal;
423
424     switch (fmt) {
425     case D3DFMT_A4R4G4B4:         retVal = GL_BGRA; break;
426     case D3DFMT_A8R8G8B8:         retVal = GL_BGRA; break;
427     case D3DFMT_X8R8G8B8:         retVal = GL_BGRA; break;
428     case D3DFMT_R8G8B8:           retVal = GL_BGR; break;
429     case D3DFMT_R5G6B5:           retVal = GL_BGR; break;
430     case D3DFMT_A1R5G5B5:         retVal = GL_BGRA; break;
431     default:
432         FIXME("Unhandled fmt %d\n", fmt);
433         retVal = 4;
434     }
435     TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
436     return retVal;
437 }
438 DWORD fmt2glType(D3DFORMAT fmt) {
439     GLenum retVal;
440
441     switch (fmt) {
442     case D3DFMT_A4R4G4B4:         retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
443     case D3DFMT_A8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
444     case D3DFMT_X8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
445     case D3DFMT_R5G6B5:           retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
446     case D3DFMT_R8G8B8:           retVal = GL_UNSIGNED_BYTE; break;
447     case D3DFMT_A1R5G5B5:         retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
448     default:
449         FIXME("Unhandled fmt %d\n", fmt);
450         retVal = 4;
451     }
452
453
454     TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
455     return retVal;
456 }
457
458 int SOURCEx_RGB_EXT(DWORD arg) {
459     switch(arg) {
460     case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
461     case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
462     case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
463     case D3DTSS_ALPHAARG0:
464     case D3DTSS_ALPHAARG1:
465     case D3DTSS_ALPHAARG2:
466     default:
467         FIXME("Invalid arg %ld\n", arg);
468         return GL_SOURCE0_RGB_EXT;
469     }
470 }
471 int OPERANDx_RGB_EXT(DWORD arg) {
472     switch(arg) {
473     case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
474     case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
475     case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
476     case D3DTSS_ALPHAARG0:
477     case D3DTSS_ALPHAARG1:
478     case D3DTSS_ALPHAARG2:
479     default:
480         FIXME("Invalid arg %ld\n", arg);
481         return GL_OPERAND0_RGB_EXT;
482     }
483 }
484 int SOURCEx_ALPHA_EXT(DWORD arg) {
485     switch(arg) {
486     case D3DTSS_ALPHAARG0:  return GL_SOURCE2_ALPHA_EXT;
487     case D3DTSS_ALPHAARG1:  return GL_SOURCE0_ALPHA_EXT;
488     case D3DTSS_ALPHAARG2:  return GL_SOURCE1_ALPHA_EXT;
489     case D3DTSS_COLORARG0:
490     case D3DTSS_COLORARG1:
491     case D3DTSS_COLORARG2:
492     default:
493         FIXME("Invalid arg %ld\n", arg);
494         return GL_SOURCE0_ALPHA_EXT;
495     }
496 }
497 int OPERANDx_ALPHA_EXT(DWORD arg) {
498     switch(arg) {
499     case D3DTSS_ALPHAARG0:  return GL_OPERAND2_ALPHA_EXT;
500     case D3DTSS_ALPHAARG1:  return GL_OPERAND0_ALPHA_EXT;
501     case D3DTSS_ALPHAARG2:  return GL_OPERAND1_ALPHA_EXT;
502     case D3DTSS_COLORARG0:
503     case D3DTSS_COLORARG1:
504     case D3DTSS_COLORARG2:
505     default:
506         FIXME("Invalid arg %ld\n", arg);
507         return GL_OPERAND0_ALPHA_EXT;
508     }
509 }
510 GLenum StencilOp(DWORD op) {
511     switch(op) {                
512     case D3DSTENCILOP_KEEP    : return GL_KEEP;
513     case D3DSTENCILOP_ZERO    : return GL_ZERO;
514     case D3DSTENCILOP_REPLACE : return GL_REPLACE;
515     case D3DSTENCILOP_INCRSAT : return GL_INCR;
516     case D3DSTENCILOP_DECRSAT : return GL_DECR;
517     case D3DSTENCILOP_INVERT  : return GL_INVERT;
518     case D3DSTENCILOP_INCR    : FIXME("Unsupported stencil op %ld\n", op);
519                                 return GL_INCR; /* Fixme - needs to support wrap */
520     case D3DSTENCILOP_DECR    : FIXME("Unsupported stencil op %ld\n", op);
521                                 return GL_DECR; /* Fixme - needs to support wrap */
522     default:
523         FIXME("Invalid stencil op %ld\n", op);
524         return GL_ALWAYS;
525     }
526 }
527
528 /* Apply the current values to the specified texture stage */
529 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
530     ICOM_THIS(IDirect3DDevice8Impl,iface);
531     int i=0;
532     float col[4];
533
534     /* Make appropriate texture active */
535     glActiveTextureARB(GL_TEXTURE0_ARB + i);
536     checkGLcall("glActiveTextureARB");
537
538     TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
539     for (i=1; i<29; i++) {
540         IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock.texture_state[Stage][i]);
541     }
542
543     /* Note the D3DRS value applies to all textures, but GL has one
544        per texture, so apply it now ready to be used!               */
545     col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
546     col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
547     col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
548     col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
549     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
550     checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
551
552     TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
553 }
554
555 /* IDirect3D IUnknown parts follow: */
556 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
557 {
558     ICOM_THIS(IDirect3DDevice8Impl,iface);
559
560     if (IsEqualGUID(riid, &IID_IUnknown)
561         || IsEqualGUID(riid, &IID_IClassFactory)) {
562         IDirect3DDevice8Impl_AddRef(iface);
563         *ppobj = This;
564         return D3D_OK;
565     }
566
567     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
568     return E_NOINTERFACE;
569 }
570
571 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
572     ICOM_THIS(IDirect3DDevice8Impl,iface);
573     TRACE("(%p) : AddRef from %ld\n", This, This->ref);
574     return ++(This->ref);
575 }
576
577 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
578     ICOM_THIS(IDirect3DDevice8Impl,iface);
579     ULONG ref = --This->ref;
580     TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
581     if (ref == 0) {
582         HeapFree(GetProcessHeap(), 0, This);
583     }
584     return ref;
585 }
586
587 /* IDirect3DDevice Interface follow: */
588 HRESULT  WINAPI  IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
589     ICOM_THIS(IDirect3DDevice8Impl,iface);
590     TRACE("(%p) : stub\n", This);    /* No way of notifying yet! */
591     return D3D_OK;
592 }
593
594
595 UINT     WINAPI  IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
596     ICOM_THIS(IDirect3DDevice8Impl,iface);
597     TRACE("(%p) : stub, emulating 32Mb for now\n", This);
598     /*
599      * pretend we have 32MB of any type of memory queried.
600      */
601     return (1024*1024*32);
602 }
603
604 HRESULT  WINAPI  IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
605     ICOM_THIS(IDirect3DDevice8Impl,iface);
606     FIXME("(%p) : stub\n", This);    return D3D_OK;
607 }
608 HRESULT  WINAPI  IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
609     ICOM_THIS(IDirect3DDevice8Impl,iface);
610     TRACE("(%p) : returning %p\n", This, This->direct3d8);
611
612     /* Inc ref count */
613     IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
614
615     *ppD3D8 = (IDirect3D8 *)This->direct3d8;
616     return D3D_OK;
617 }
618 HRESULT  WINAPI  IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
619     ICOM_THIS(IDirect3DDevice8Impl,iface);
620     FIXME("(%p) : stub, calling idirect3d for now\n", This);
621     IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
622     return D3D_OK;
623 }
624 HRESULT  WINAPI  IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
625
626     HDC hdc;
627     int bpp = 0;
628
629     ICOM_THIS(IDirect3DDevice8Impl,iface);
630     pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
631     pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
632     pMode->RefreshRate  = 85; /*FIXME: How to identify? */
633
634     hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
635     bpp = GetDeviceCaps(hdc, BITSPIXEL);
636     DeleteDC(hdc);
637
638     switch (bpp) {
639     case  8: pMode->Format       = D3DFMT_R8G8B8; break;
640     case 16: pMode->Format       = D3DFMT_R5G6B5; break;
641     case 24: pMode->Format       = D3DFMT_R8G8B8; break;
642     case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
643     default: pMode->Format       = D3DFMT_UNKNOWN;
644     }
645
646     FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
647     return D3D_OK;
648 }
649 HRESULT  WINAPI  IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
650     ICOM_THIS(IDirect3DDevice8Impl,iface);
651     TRACE("(%p) copying to %p\n", This, pParameters);    
652     memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
653     return D3D_OK;
654 }
655 HRESULT  WINAPI  IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
656     ICOM_THIS(IDirect3DDevice8Impl,iface);
657     FIXME("(%p) : stub\n", This);    return D3D_OK;
658 }
659 void     WINAPI  IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
660     ICOM_THIS(IDirect3DDevice8Impl,iface);
661     FIXME("(%p) : stub\n", This);    return;
662 }
663 BOOL     WINAPI  IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
664     ICOM_THIS(IDirect3DDevice8Impl,iface);
665     FIXME("(%p) : stub\n", This);    return D3D_OK;
666 }
667 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
668     ICOM_THIS(IDirect3DDevice8Impl,iface);
669     FIXME("(%p) : stub\n", This);    return D3D_OK;
670 }
671 HRESULT  WINAPI  IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
672     ICOM_THIS(IDirect3DDevice8Impl,iface);
673     FIXME("(%p) : stub\n", This);    return D3D_OK;
674 }
675 HRESULT  WINAPI  IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
676     ICOM_THIS(IDirect3DDevice8Impl,iface);
677     TRACE("(%p) : complete stub!\n", This);
678
679     ENTER_GL();
680
681     glXSwapBuffers(This->display, This->win);
682     checkGLcall("glXSwapBuffers");
683
684     LEAVE_GL();
685
686     return D3D_OK;
687 }
688 HRESULT  WINAPI  IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
689     ICOM_THIS(IDirect3DDevice8Impl,iface);
690     *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
691     TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
692
693     /* Note inc ref on returned surface */
694     IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
695
696     return D3D_OK;
697 }
698 HRESULT  WINAPI  IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
699     ICOM_THIS(IDirect3DDevice8Impl,iface);
700     FIXME("(%p) : stub\n", This);    return D3D_OK;
701 }
702 void     WINAPI  IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
703     ICOM_THIS(IDirect3DDevice8Impl,iface);
704     FIXME("(%p) : stub\n", This);    return;
705 }
706 void     WINAPI  IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
707     ICOM_THIS(IDirect3DDevice8Impl,iface);
708     FIXME("(%p) : stub\n", This);    return;
709 }
710 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
711                                                     D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
712     IDirect3DTexture8Impl *object;
713     int i;
714     UINT tmpW;
715     UINT tmpH;
716
717     ICOM_THIS(IDirect3DDevice8Impl,iface);
718
719     /* Allocate the storage for the device */
720     TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
721     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
722     object->lpVtbl = &Direct3DTexture8_Vtbl;
723     object->Device = This;
724     object->ResourceType = D3DRTYPE_TEXTURE;
725     object->ref = 1;
726     object->width = Width;
727     object->height = Height;
728     object->levels = Levels;
729     object->usage = Usage;
730     object->format = Format;
731     object->device = This;
732
733     /* Calculate levels for mip mapping */
734     if (Levels == 0) {
735         object->levels++;
736         tmpW = Width;
737         tmpH = Height;
738         while (tmpW > 1 && tmpH > 1) {
739             tmpW = max(1,tmpW / 2);
740             tmpH = max(1, tmpH / 2);
741             object->levels++;
742         }
743         TRACE("Calculated levels = %d\n", object->levels);
744     }
745
746     /* Generate all the surfaces */
747     tmpW = Width;
748     tmpH = Height;
749     /*for (i=0; i<object->levels; i++) { */
750     i=0;
751     {
752         IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
753         object->surfaces[i]->Container = object;
754         object->surfaces[i]->myDesc.Usage = Usage;
755         object->surfaces[i]->myDesc.Pool = Pool ;
756
757         TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
758         tmpW = max(1,tmpW / 2);
759         tmpH = max(1, tmpH / 2);
760     }
761
762     *ppTexture = (LPDIRECT3DTEXTURE8)object;
763     return D3D_OK;
764 }
765 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
766
767     IDirect3DVolumeTexture8Impl *object;
768     int i;
769     UINT tmpW;
770     UINT tmpH;
771     UINT tmpD;
772
773     ICOM_THIS(IDirect3DDevice8Impl,iface);
774
775     /* Allocate the storage for it */
776     TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Depth, Levels, Usage, Format, Pool);
777     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
778     object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
779     object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
780     object->ref = 1;
781
782
783     object->width = Width;
784     object->height = Height;
785     object->depth = Depth;
786     object->levels = Levels;
787     object->usage = Usage;
788     object->format = Format;
789     object->device = This;
790
791     /* Calculate levels for mip mapping */
792     if (Levels == 0) {
793         object->levels++;
794         tmpW = Width;
795         tmpH = Height;
796         tmpD = Depth;
797         while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
798             tmpW = max(1,tmpW / 2);
799             tmpH = max(1, tmpH / 2);
800             tmpD = max(1, tmpD / 2);
801             object->levels++;
802         }
803         TRACE("Calculated levels = %d\n", object->levels);
804     }
805
806     /* Generate all the surfaces */
807     tmpW = Width;
808     tmpH = Height;
809     tmpD = Depth;
810
811     /*for (i=0; i<object->levels; i++) { */
812     i=0;
813     {
814         IDirect3DVolume8Impl *volume;
815
816         /* Create the volume - No entry point for this seperately?? */
817         volume  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
818         object->volumes[i] = (IDirect3DVolume8Impl *) volume;
819
820         volume->lpVtbl = &Direct3DVolume8_Vtbl;
821         volume->Device = This;
822         volume->ResourceType = D3DRTYPE_VOLUME;
823         volume->Container = object;
824         volume->ref = 1;
825
826         volume->myDesc.Width = Width;
827         volume->myDesc.Height= Height;
828         volume->myDesc.Depth = Depth;
829         volume->myDesc.Format= Format;
830         volume->myDesc.Type  = D3DRTYPE_VOLUME;
831         volume->myDesc.Pool  = Pool;
832         volume->myDesc.Usage = Usage;
833         volume->bytesPerPixel   = bytesPerPixel(Format);
834         volume->myDesc.Size     = (Width * volume->bytesPerPixel) * Height * Depth;
835         volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
836
837         TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format, 
838                   volume, volume->allocatedMemory, volume->myDesc.Size);
839
840         tmpW = max(1,tmpW / 2);
841         tmpH = max(1, tmpH / 2);
842         tmpD = max(1, tmpD / 2);
843     }
844
845     *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
846     return D3D_OK;
847 }
848 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
849
850     IDirect3DCubeTexture8Impl *object;
851     ICOM_THIS(IDirect3DDevice8Impl,iface);
852     int i,j;
853     UINT tmpW;
854
855     /* Allocate the storage for it */
856     TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
857     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
858     object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
859     object->ref = 1;
860     object->Device = This;
861     object->ResourceType = D3DRTYPE_CUBETEXTURE;
862
863     object->edgeLength = EdgeLength;
864     object->levels = Levels;
865     object->usage = Usage;
866     object->format = Format;
867     object->device = This;
868
869     /* Calculate levels for mip mapping */
870     if (Levels == 0) {
871         object->levels++;
872         tmpW = EdgeLength;
873         while (tmpW > 1) {
874             tmpW = max(1,tmpW / 2);
875             object->levels++;
876         }
877         TRACE("Calculated levels = %d\n", object->levels);
878     }
879
880     /* Generate all the surfaces */
881     tmpW = EdgeLength;
882     /*for (i=0; i<object->levels; i++) { */
883     i=0;
884     {
885         /* Create the 6 faces */
886         for (j=0;j<6;j++) {
887            IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
888            object->surfaces[j][i]->Container = object;
889            object->surfaces[j][i]->myDesc.Usage = Usage;
890            object->surfaces[j][i]->myDesc.Pool = Pool ;
891
892            TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
893            tmpW = max(1,tmpW / 2);
894         }
895     }
896
897     TRACE("(%p) : Iface@%p\n", This, object);
898     *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
899     return D3D_OK;
900 }
901 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size,DWORD Usage,
902                                                          DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8** ppVertexBuffer) {
903     IDirect3DVertexBuffer8Impl *object;
904
905     ICOM_THIS(IDirect3DDevice8Impl,iface);
906
907     /* Allocate the storage for the device */
908     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
909     object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
910     object->Device = This;
911     object->ResourceType = D3DRTYPE_VERTEXBUFFER;
912     object->ref = 1;
913     object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
914     object->currentDesc.Usage = Usage;
915     object->currentDesc.Pool  = Pool;
916     object->currentDesc.FVF   = FVF;
917     object->currentDesc.Size  = Size;
918
919     TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
920
921     *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
922
923     return D3D_OK;
924 }
925 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
926
927     IDirect3DIndexBuffer8Impl *object;
928
929     ICOM_THIS(IDirect3DDevice8Impl,iface);
930     TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
931
932     /* Allocate the storage for the device */
933     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
934     object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
935     object->ref = 1;
936     object->Device = This;
937     object->ResourceType = D3DRTYPE_INDEXBUFFER;
938
939     object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
940     object->currentDesc.Usage = Usage;
941     object->currentDesc.Pool  = Pool;
942     object->currentDesc.Format  = Format;
943     object->currentDesc.Size  = Length;
944
945     object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
946
947     TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
948
949     *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
950
951     return D3D_OK;
952 }
953 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
954     ICOM_THIS(IDirect3DDevice8Impl,iface);
955     /* up ref count on surface, surface->container = This */
956     FIXME("(%p) : stub\n", This);    return D3D_OK;
957 }
958 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
959     ICOM_THIS(IDirect3DDevice8Impl,iface);
960     /* surface->container = This */
961     FIXME("(%p) : stub\n", This);    return D3D_OK;
962 }
963 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
964     IDirect3DSurface8Impl *object;
965
966     ICOM_THIS(IDirect3DDevice8Impl,iface);
967
968     object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
969     *ppSurface = (LPDIRECT3DSURFACE8) object;
970     object->lpVtbl = &Direct3DSurface8_Vtbl;
971     object->Device = This;
972     object->ResourceType = D3DRTYPE_SURFACE;
973     object->Container = This;
974
975     object->ref = 1;
976     object->myDesc.Width = Width;
977     object->myDesc.Height= Height;
978     object->myDesc.Format= Format;
979     object->myDesc.Type = D3DRTYPE_SURFACE;
980     /*object->myDesc.Usage */
981     object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
982     object->bytesPerPixel = bytesPerPixel(Format);
983     object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
984     object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
985
986     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, *ppSurface, object->allocatedMemory, object->myDesc.Size);
987     return D3D_OK;
988 }
989 HRESULT  WINAPI  IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
990                                                 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
991
992     HRESULT rc = D3D_OK;
993
994     IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
995     IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
996
997     ICOM_THIS(IDirect3DDevice8Impl,iface);
998     TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
999           pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1000
1001     if (src->myDesc.Format != dst->myDesc.Format) {
1002         TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1003         rc = D3DERR_INVALIDCALL;
1004     }
1005
1006     /* Quick if complete copy ... */
1007     if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1008                          src->myDesc.Width == dst->myDesc.Width &&
1009                          src->myDesc.Height == dst->myDesc.Height)) {
1010         TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1011         memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1012
1013     } else {
1014         int i;
1015         int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1016         int pitchFrom     = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1017         int pitchTo       = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1018
1019         void *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1020         void *copyto   = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1021
1022         /* Copy rect by rect */
1023         for (i=0; i<cRects; i++) {
1024             CONST RECT *r = &pSourceRectsArray[i];
1025             CONST POINT *p = &pDestPointsArray[i];
1026             void *from;
1027             void *to;
1028             int   copyperline   = (r->right - r->left) * bytesPerPixel;
1029             int j;
1030
1031             TRACE("Copying rect %d (%d,%d),(%d,%d) -> (%ld,%ld)\n", i, r->left, r->top, 
1032                   r->right, r->bottom, p->x, p->y);
1033
1034             /* Find where to start */
1035             from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1036             to   = copyto   + (p->y * pitchFrom) + (p->x * bytesPerPixel);
1037
1038             /* Copy line by line */
1039             for (j=0; j<(r->bottom - r->top); j++) {
1040                memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1041             }
1042         }
1043     }
1044     return D3D_OK;
1045 }
1046 HRESULT  WINAPI  IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1047     ICOM_THIS(IDirect3DDevice8Impl,iface);
1048     FIXME("(%p) : stub\n", This);    return D3D_OK;
1049 }
1050 HRESULT  WINAPI  IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1051     ICOM_THIS(IDirect3DDevice8Impl,iface);
1052     FIXME("(%p) : stub\n", This);    return D3D_OK;
1053 }
1054 HRESULT  WINAPI  IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1055     ICOM_THIS(IDirect3DDevice8Impl,iface);
1056     FIXME("(%p) : stub\n", This);
1057
1058     return D3D_OK;
1059 }
1060 HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1061     ICOM_THIS(IDirect3DDevice8Impl,iface);
1062     /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1063     FIXME("(%p) : stub\n", This);
1064
1065     /*
1066      **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1067      *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1068      */
1069
1070     return D3D_OK;
1071 }
1072 HRESULT  WINAPI  IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1073
1074     ICOM_THIS(IDirect3DDevice8Impl,iface);
1075
1076     /* Note inc ref on returned surface *
1077     IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1078
1079     FIXME("(%p) : stub\n", This);
1080     return D3D_OK;
1081 }
1082
1083 HRESULT  WINAPI  IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1084     ICOM_THIS(IDirect3DDevice8Impl,iface);
1085     TRACE("(%p) : stub\n", This);
1086     return D3D_OK;
1087 }
1088 HRESULT  WINAPI  IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1089     ICOM_THIS(IDirect3DDevice8Impl,iface);
1090     TRACE("(%p)\n", This);
1091
1092     ENTER_GL();
1093
1094     glFlush();
1095     checkGLcall("glFlush");
1096
1097     /* Useful for debugging sometimes!
1098     printf("Hit Enter ...\n");
1099     getchar(); */
1100
1101     LEAVE_GL();
1102     return D3D_OK;
1103 }
1104 HRESULT  WINAPI  IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1105     ICOM_THIS(IDirect3DDevice8Impl,iface);
1106
1107     /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1108       render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1109       when the depth-buffer format does not contain stencil buffer information, this method fails. */
1110     GLbitfield glMask = 0;
1111     int i;
1112     CONST D3DRECT   *curRect;
1113
1114     TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1115           Count, pRects, Flags, Z, Stencil);
1116
1117     ENTER_GL();
1118     if (Count > 0 && pRects) {
1119         glEnable(GL_SCISSOR_TEST);
1120         checkGLcall("glEnable GL_SCISSOR_TEST");
1121         curRect = pRects;
1122     } else {
1123         curRect = NULL;
1124     }
1125
1126     for (i=0;i<Count || i==0; i++) {
1127
1128         if (curRect) {
1129             /* Note gl uses lower left, width/height */
1130             TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1131                   curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1132                   curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1133             glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1134             checkGLcall("glScissor");
1135         }
1136
1137         /* Clear the whole screen */
1138         if (Flags & D3DCLEAR_STENCIL) {
1139             glClearStencil(Stencil);
1140             checkGLcall("glClearStencil");
1141             glMask = glMask | GL_STENCIL_BUFFER_BIT;
1142         }
1143
1144         if (Flags & D3DCLEAR_ZBUFFER) {
1145             glClearDepth(Z);
1146             checkGLcall("glClearDepth");
1147             glMask = glMask | GL_DEPTH_BUFFER_BIT;
1148         }
1149
1150         if (Flags & D3DCLEAR_TARGET) {
1151             TRACE("Clearing screen with glClear to color %lx\n", Color);
1152             glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >>  8) & 0xFF) / 255.0,
1153                          ((Color >>  0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1154             checkGLcall("glClearColor");
1155             glMask = glMask | GL_COLOR_BUFFER_BIT;
1156         }
1157
1158         glClear(glMask);
1159         checkGLcall("glClear");
1160
1161         if (curRect) curRect = curRect + sizeof(D3DRECT);
1162     }
1163
1164     if (Count > 0 && pRects) {
1165         glDisable(GL_SCISSOR_TEST);
1166         checkGLcall("glDisable");
1167     }
1168     LEAVE_GL();
1169
1170     return D3D_OK;
1171 }
1172 HRESULT  WINAPI  IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1173     ICOM_THIS(IDirect3DDevice8Impl,iface);
1174     int k;
1175
1176     /* Most of this routine, comments included copied from ddraw tree initially: */
1177     TRACE("(%p) : State=%d\n", This, d3dts);
1178
1179     This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1180     This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1181     memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1182
1183     /* Handle recording of state blocks */
1184     if (This->isRecordingState) {
1185         TRACE("Recording... not performing anything\n");
1186         return D3D_OK;
1187     }
1188
1189     /*
1190        ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1191
1192        where ViewMat = Camera space, WorldMat = world space.
1193
1194        In OpenGL, camera and world space is combined into GL_MODELVIEW
1195        matrix.  The Projection matrix stay projection matrix. */
1196
1197     /* After reading through both OpenGL and Direct3D documentations, I
1198        thought that D3D matrices were written in 'line major mode' transposed
1199        from OpenGL's 'column major mode'. But I found out that a simple memcpy
1200        works fine to transfer one matrix format to the other (it did not work
1201        when transposing)....
1202
1203        So :
1204         1) are the documentations wrong
1205         2) does the matrix work even if they are not read correctly
1206         3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1207            loading using glLoadMatrix ?
1208
1209        Anyway, I always use 'conv_mat' to transfer the matrices from one format
1210        to the other so that if I ever find out that I need to transpose them, I
1211        will able to do it quickly, only by changing the macro conv_mat. */
1212
1213     switch (d3dts) {
1214     case D3DTS_WORLDMATRIX(0): {
1215             conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)]);
1216         } break;
1217
1218     case D3DTS_VIEW: {
1219             conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_VIEW]);
1220         } break;
1221
1222     case D3DTS_PROJECTION: {
1223             conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_PROJECTION]);
1224         } break;
1225
1226     default:
1227         break;
1228     }
1229
1230     /*
1231      * Move the GL operation to outside of switch to make it work
1232      * regardless of transform set order. Optimize later.
1233      */
1234     ENTER_GL();
1235     glMatrixMode(GL_PROJECTION);
1236     checkGLcall("glMatrixMode");
1237     glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
1238     checkGLcall("glLoadMatrixf");
1239
1240     glMatrixMode(GL_MODELVIEW);
1241     checkGLcall("glMatrixMode");
1242     glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1243     checkGLcall("glLoadMatrixf");
1244
1245     /* If we are changing the View matrix, reset the light information to the new view */
1246     if (d3dts == D3DTS_VIEW) {
1247         for (k = 0; k < MAX_ACTIVE_LIGHTS; k++) {
1248             glLightfv(GL_LIGHT0 + k, GL_POSITION,       &This->lightPosn[k][0]);
1249             checkGLcall("glLightfv posn");
1250             glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1251             checkGLcall("glLightfv dirn");
1252         }
1253     }
1254
1255     glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1256     checkGLcall("glMultMatrixf");
1257
1258     LEAVE_GL();
1259
1260     return D3D_OK;
1261
1262 }
1263 HRESULT  WINAPI  IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1264     ICOM_THIS(IDirect3DDevice8Impl,iface);
1265     TRACE("(%p) : for State %d\n", This, State);
1266     memcpy(pMatrix, &This->StateBlock.transforms[State], sizeof(D3DMATRIX));
1267     return D3D_OK;
1268 }
1269
1270 HRESULT  WINAPI  IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1271     ICOM_THIS(IDirect3DDevice8Impl,iface);
1272     FIXME("(%p) : stub\n", This);    return D3D_OK;
1273 }
1274 HRESULT  WINAPI  IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1275     ICOM_THIS(IDirect3DDevice8Impl,iface);
1276
1277     TRACE("(%p)\n", This);
1278     This->UpdateStateBlock->Changed.viewport = TRUE;
1279     This->UpdateStateBlock->Set.viewport = TRUE;
1280     memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1281
1282     /* Handle recording of state blocks */
1283     if (This->isRecordingState) {
1284         TRACE("Recording... not performing anything\n");
1285         return D3D_OK;
1286     }
1287
1288     TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1289           pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1290
1291     glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1292     checkGLcall("glDepthRange");
1293     /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1294     glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1295     checkGLcall("glViewport");
1296
1297
1298     return D3D_OK;
1299
1300 }
1301 HRESULT  WINAPI  IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1302     ICOM_THIS(IDirect3DDevice8Impl,iface);
1303     TRACE("(%p)\n", This);
1304     memcpy(pViewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
1305     return D3D_OK;
1306 }
1307
1308 HRESULT  WINAPI  IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1309     ICOM_THIS(IDirect3DDevice8Impl,iface);
1310
1311     This->UpdateStateBlock->Changed.material = TRUE;
1312     This->UpdateStateBlock->Set.material = TRUE;
1313     memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1314
1315     /* Handle recording of state blocks */
1316     if (This->isRecordingState) {
1317         TRACE("Recording... not performing anything\n");
1318         return D3D_OK;
1319     }
1320
1321     ENTER_GL();
1322     TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1323     TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1324     TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1325     TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1326     TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1327
1328     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1329     checkGLcall("glMaterialfv");
1330     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1331     checkGLcall("glMaterialfv");
1332
1333     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1334     checkGLcall("glMaterialfv");
1335     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1336     checkGLcall("glMaterialfv");
1337     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1338     checkGLcall("glMaterialf");
1339
1340     LEAVE_GL();
1341     return D3D_OK;
1342 }
1343 HRESULT  WINAPI  IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1344     ICOM_THIS(IDirect3DDevice8Impl,iface);
1345     memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1346     TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1347     TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1348     TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1349     TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1350     TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1351     return D3D_OK;
1352 }
1353
1354 HRESULT  WINAPI  IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1355     float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1356     float rho;
1357     float quad_att;
1358
1359     ICOM_THIS(IDirect3DDevice8Impl,iface);
1360     TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1361
1362     TRACE("Light %ld setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f)\n", Index, pLight->Type,
1363           pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1364           pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1365           pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1366     TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1367           pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1368     TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1369
1370     This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1371     This->UpdateStateBlock->Set.lights[Index] = TRUE;
1372     memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1373
1374     /* Handle recording of state blocks */
1375     if (This->isRecordingState) {
1376         TRACE("Recording... not performing anything\n");
1377         return D3D_OK;
1378     }
1379
1380     /* Diffuse: */
1381     colRGBA[0] = pLight->Diffuse.r;
1382     colRGBA[1] = pLight->Diffuse.g;
1383     colRGBA[2] = pLight->Diffuse.b;
1384     colRGBA[3] = pLight->Diffuse.a;
1385     glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1386     checkGLcall("glLightfv");
1387
1388     /* Specular */
1389     colRGBA[0] = pLight->Specular.r;
1390     colRGBA[1] = pLight->Specular.g;
1391     colRGBA[2] = pLight->Specular.b;
1392     colRGBA[3] = pLight->Specular.a;
1393     glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1394     checkGLcall("glLightfv");
1395
1396     /* Ambient */
1397     colRGBA[0] = pLight->Ambient.r;
1398     colRGBA[1] = pLight->Ambient.g;
1399     colRGBA[2] = pLight->Ambient.b;
1400     colRGBA[3] = pLight->Ambient.a;
1401     glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1402     checkGLcall("glLightfv");
1403
1404     /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1405         glMatrixMode(GL_MODELVIEW);
1406         glPushMatrix();
1407     glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1408
1409     /* Attenuation - Are these right? guessing... */
1410     glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION,  pLight->Attenuation0);
1411     checkGLcall("glLightf");
1412     glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION,    pLight->Attenuation1);
1413     checkGLcall("glLightf");
1414
1415     quad_att = 1.4/(pLight->Range*pLight->Range);
1416     if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1417     glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1418     checkGLcall("glLightf");
1419
1420     switch (pLight->Type) {
1421     case D3DLIGHT_POINT:
1422         /* Position */
1423         This->lightPosn[Index][0] = pLight->Position.x;
1424         This->lightPosn[Index][1] = pLight->Position.y;
1425         This->lightPosn[Index][2] = pLight->Position.z;
1426         This->lightPosn[Index][3] = 1.0;
1427         glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1428         checkGLcall("glLightfv");
1429
1430         glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1431         checkGLcall("glLightf");
1432
1433         /* FIXME: Range */
1434         break;
1435
1436     case D3DLIGHT_SPOT:
1437         /* Position */
1438         This->lightPosn[Index][0] = pLight->Position.x;
1439         This->lightPosn[Index][1] = pLight->Position.y;
1440         This->lightPosn[Index][2] = pLight->Position.z;
1441         This->lightPosn[Index][3] = 1.0;
1442         glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1443         checkGLcall("glLightfv");
1444
1445         /* Direction */
1446         This->lightDirn[Index][0] = pLight->Direction.x;
1447         This->lightDirn[Index][1] = pLight->Direction.y;
1448         This->lightDirn[Index][2] = pLight->Direction.z;
1449         This->lightDirn[Index][3] = 1.0;
1450         glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1451         checkGLcall("glLightfv");
1452
1453         /*
1454          * opengl-ish and d3d-ish spot lights use too different models for the
1455          * light "intensity" as a function of the angle towards the main light direction,
1456          * so we only can approximate very roughly.
1457          * however spot lights are rather rarely used in games (if ever used at all).
1458          * furthermore if still used, probably nobody pays attention to such details.
1459          */
1460         if (pLight->Falloff == 0) {
1461             rho = 6.28f;
1462         } else {
1463             rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1464         }
1465         if (rho < 0.0001) rho = 0.0001f;
1466         glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
1467         glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
1468
1469         /* FIXME: Range */
1470         break;
1471     case D3DLIGHT_DIRECTIONAL:
1472         /* Direction */
1473         This->lightPosn[Index][0] = -pLight->Direction.x;
1474         This->lightPosn[Index][1] = -pLight->Direction.y;
1475         This->lightPosn[Index][2] = -pLight->Direction.z;
1476         This->lightPosn[Index][3] = 0.0;
1477         glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
1478         checkGLcall("glLightfv");
1479
1480         glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
1481         glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
1482
1483
1484         break;
1485     default:
1486         FIXME("Unrecognized light type %d\n", pLight->Type);
1487     }
1488
1489     /* Restore the modelview matrix */
1490     glPopMatrix();
1491
1492     return D3D_OK;
1493 }
1494 HRESULT  WINAPI  IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1495     ICOM_THIS(IDirect3DDevice8Impl,iface);
1496     TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1497     memcpy(pLight, &This->StateBlock.lights[Index], sizeof(D3DLIGHT8));
1498     return D3D_OK;
1499 }
1500 HRESULT  WINAPI  IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1501     ICOM_THIS(IDirect3DDevice8Impl,iface);
1502     TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
1503
1504     This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
1505     This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
1506     This->UpdateStateBlock->lightEnable[Index] = Enable;
1507
1508     /* Handle recording of state blocks */
1509     if (This->isRecordingState) {
1510         TRACE("Recording... not performing anything\n");
1511         return D3D_OK;
1512     }
1513
1514     if (Enable) {
1515         glEnable(GL_LIGHT0+Index);
1516         checkGLcall("glEnable GL_LIGHT0+Index");
1517     } else {
1518         glDisable(GL_LIGHT0+Index);
1519         checkGLcall("glDisable GL_LIGHT0+Index");
1520     }
1521     return D3D_OK;
1522 }
1523 HRESULT  WINAPI  IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1524     ICOM_THIS(IDirect3DDevice8Impl,iface);
1525     TRACE("(%p) : for idx(%ld)\n", This, Index);
1526     *pEnable = This->StateBlock.lightEnable[Index];
1527     return D3D_OK;
1528 }
1529 HRESULT  WINAPI  IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1530     ICOM_THIS(IDirect3DDevice8Impl,iface);
1531     TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
1532
1533     This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
1534     This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
1535     This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
1536     This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
1537     This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
1538     This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
1539
1540     /* Handle recording of state blocks */
1541     if (This->isRecordingState) {
1542         TRACE("Recording... not performing anything\n");
1543         return D3D_OK;
1544     }
1545
1546     /* Apply it */
1547
1548     /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
1549         glMatrixMode(GL_MODELVIEW);
1550         glPushMatrix();
1551     glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLD].u.m[0][0]);
1552
1553     TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
1554           This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
1555     glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
1556
1557     glPopMatrix();
1558     checkGLcall("glClipPlane");
1559
1560     return D3D_OK;
1561 }
1562 HRESULT  WINAPI  IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1563     ICOM_THIS(IDirect3DDevice8Impl,iface);
1564     TRACE("(%p) : for idx %ld\n", This, Index);
1565     pPlane[0] = This->StateBlock.clipplane[Index][0];
1566     pPlane[1] = This->StateBlock.clipplane[Index][0];
1567     pPlane[2] = This->StateBlock.clipplane[Index][0];
1568     pPlane[3] = This->StateBlock.clipplane[Index][0];
1569     return D3D_OK;
1570 }
1571 HRESULT  WINAPI  IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
1572     ICOM_THIS(IDirect3DDevice8Impl,iface);
1573     DWORD OldValue = This->StateBlock.renderstate[State];
1574         
1575     TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
1576     This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
1577     This->UpdateStateBlock->Set.renderstate[State] = TRUE;
1578     This->UpdateStateBlock->renderstate[State] = Value;
1579
1580     /* Handle recording of state blocks */
1581     if (This->isRecordingState) {
1582         TRACE("Recording... not performing anything\n");
1583         return D3D_OK;
1584     }
1585
1586     switch (State) {
1587     case D3DRS_FILLMODE                  :
1588         switch ((D3DFILLMODE) Value) {
1589         case D3DFILL_POINT               : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
1590         case D3DFILL_WIREFRAME           : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
1591         case D3DFILL_SOLID               : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
1592         default:
1593             FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
1594         }
1595         checkGLcall("glPolygonMode (fillmode)");
1596         break;
1597
1598     case D3DRS_LIGHTING                  :
1599         if (Value) {
1600             glEnable(GL_LIGHTING);
1601             checkGLcall("glEnable GL_LIGHTING");
1602         } else {
1603             glDisable(GL_LIGHTING);
1604             checkGLcall("glDisable GL_LIGHTING");
1605         }
1606         break;
1607
1608     case D3DRS_ZENABLE                   :
1609         switch ((D3DZBUFFERTYPE) Value) {
1610         case D3DZB_FALSE:
1611             glDisable(GL_DEPTH_TEST);
1612             checkGLcall("glDisable GL_DEPTH_TEST");
1613             break;
1614         case D3DZB_TRUE:
1615             glEnable(GL_DEPTH_TEST);
1616             checkGLcall("glEnable GL_DEPTH_TEST");
1617             break;
1618
1619         case D3DZB_USEW:
1620         default:
1621             FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
1622         }
1623         break;
1624
1625     case D3DRS_CULLMODE                  :
1626
1627         /* If we are culling "back faces with clockwise vertices" then
1628            set front faces to be counter clockwise and enable culling  
1629            of back faces                                               */
1630         switch ((D3DCULL) Value) {
1631         case D3DCULL_NONE:
1632             glDisable(GL_CULL_FACE);
1633             checkGLcall("glDisable GL_CULL_FACE");
1634             break;
1635         case D3DCULL_CW:
1636             glEnable(GL_CULL_FACE);
1637             checkGLcall("glEnable GL_CULL_FACE");
1638             glFrontFace(GL_CCW);
1639             checkGLcall("glFrontFace GL_CCW");
1640             glCullFace(GL_BACK);
1641             break;
1642         case D3DCULL_CCW:
1643             glEnable(GL_CULL_FACE);
1644             checkGLcall("glEnable GL_CULL_FACE");
1645             glFrontFace(GL_CW); 
1646             checkGLcall("glFrontFace GL_CW");
1647             glCullFace(GL_BACK);
1648             break;
1649         default:
1650             FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
1651         }
1652         break;
1653
1654     case D3DRS_SHADEMODE                 :
1655         switch ((D3DSHADEMODE) Value) {
1656         case D3DSHADE_FLAT:
1657             glShadeModel(GL_FLAT);
1658             checkGLcall("glShadeModel");
1659             break;
1660         case D3DSHADE_GOURAUD:
1661             glShadeModel(GL_SMOOTH);
1662             checkGLcall("glShadeModel");
1663             break;
1664         case D3DSHADE_PHONG:
1665             FIXME("D3DSHADE_PHONG isnt supported?\n");
1666             return D3DERR_INVALIDCALL;
1667         default:
1668             FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
1669         }
1670         break;
1671
1672     case D3DRS_DITHERENABLE              :
1673         if (Value) {
1674             glEnable(GL_DITHER);
1675             checkGLcall("glEnable GL_DITHER");
1676         } else {
1677             glDisable(GL_DITHER);
1678             checkGLcall("glDisable GL_DITHER");
1679         }
1680         break;
1681
1682     case D3DRS_ZWRITEENABLE              :
1683         if (Value) {
1684             glDepthMask(1);
1685             checkGLcall("glDepthMask");
1686         } else {
1687             glDepthMask(0);
1688             checkGLcall("glDepthMask");
1689         }
1690         break;
1691
1692     case D3DRS_ZFUNC                     :
1693         {
1694             int glParm = GL_LESS;
1695
1696             switch ((D3DCMPFUNC) Value) {
1697             case D3DCMP_NEVER:         glParm=GL_NEVER; break;
1698             case D3DCMP_LESS:          glParm=GL_LESS; break;
1699             case D3DCMP_EQUAL:         glParm=GL_EQUAL; break;
1700             case D3DCMP_LESSEQUAL:     glParm=GL_LEQUAL; break;
1701             case D3DCMP_GREATER:       glParm=GL_GREATER; break;
1702             case D3DCMP_NOTEQUAL:      glParm=GL_NOTEQUAL; break;
1703             case D3DCMP_GREATEREQUAL:  glParm=GL_GEQUAL; break;
1704             case D3DCMP_ALWAYS:        glParm=GL_ALWAYS; break;
1705             default:
1706                 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1707             }
1708             glDepthFunc(glParm);
1709             checkGLcall("glDepthFunc");
1710         }
1711         break;
1712
1713     case D3DRS_AMBIENT                   :
1714         {
1715
1716             float col[4];
1717             col[0] = ((Value >> 16) & 0xFF) / 255.0;
1718             col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1719             col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1720             col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1721             TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
1722             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
1723             checkGLcall("glLightModel for MODEL_AMBIENT");
1724
1725         }
1726         break;
1727
1728     case D3DRS_ALPHABLENDENABLE          :
1729         if (Value) {
1730             glEnable(GL_BLEND);
1731             checkGLcall("glEnable GL_BLEND");
1732         } else {
1733             glDisable(GL_BLEND);
1734             checkGLcall("glDisable GL_BLEND");
1735         };
1736         break;
1737
1738     case D3DRS_SRCBLEND                  :
1739     case D3DRS_DESTBLEND                 :
1740         {
1741             int newVal = GL_ZERO;
1742             switch (Value) {
1743             case D3DBLEND_ZERO               : newVal = GL_ZERO;  break;
1744             case D3DBLEND_ONE                : newVal = GL_ONE;  break;
1745             case D3DBLEND_SRCCOLOR           : newVal = GL_SRC_COLOR;  break;
1746             case D3DBLEND_INVSRCCOLOR        : newVal = GL_ONE_MINUS_SRC_COLOR;  break;
1747             case D3DBLEND_SRCALPHA           : newVal = GL_SRC_ALPHA;  break;
1748             case D3DBLEND_INVSRCALPHA        : newVal = GL_ONE_MINUS_SRC_ALPHA;  break;
1749             case D3DBLEND_DESTALPHA          : newVal = GL_DST_ALPHA;  break;
1750             case D3DBLEND_INVDESTALPHA       : newVal = GL_ONE_MINUS_DST_ALPHA;  break;
1751             case D3DBLEND_DESTCOLOR          : newVal = GL_DST_COLOR;  break;
1752             case D3DBLEND_INVDESTCOLOR       : newVal = GL_ONE_MINUS_DST_COLOR;  break;
1753             case D3DBLEND_SRCALPHASAT        : newVal = GL_SRC_ALPHA_SATURATE;  break;
1754
1755             case D3DBLEND_BOTHSRCALPHA       : newVal = GL_SRC_ALPHA;
1756                 This->srcBlend = newVal;
1757                 This->dstBlend = newVal;
1758                 break;
1759
1760             case D3DBLEND_BOTHINVSRCALPHA    : newVal = GL_ONE_MINUS_SRC_ALPHA;
1761                 This->srcBlend = newVal;
1762                 This->dstBlend = newVal;
1763                 break;
1764             default:
1765                 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
1766             }
1767
1768             if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
1769             if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
1770             TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
1771             glBlendFunc(This->srcBlend, This->dstBlend);
1772
1773             checkGLcall("glBlendFunc");
1774         }
1775         break;
1776
1777     case D3DRS_ALPHATESTENABLE           :
1778         if (Value) {
1779             glEnable(GL_ALPHA_TEST);
1780             checkGLcall("glEnable GL_ALPHA_TEST");
1781         } else {
1782             glDisable(GL_ALPHA_TEST);
1783             checkGLcall("glDisable GL_ALPHA_TEST");
1784         }
1785         break;
1786
1787     case D3DRS_ALPHAFUNC                 :
1788         {
1789             int glParm = GL_LESS;
1790             float ref = 1.0;
1791
1792             glGetFloatv(GL_ALPHA_TEST_REF, &ref);
1793             checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
1794
1795             switch ((D3DCMPFUNC) Value) {
1796             case D3DCMP_NEVER:         glParm=GL_NEVER; break;
1797             case D3DCMP_LESS:          glParm=GL_LESS; break;
1798             case D3DCMP_EQUAL:         glParm=GL_EQUAL; break;
1799             case D3DCMP_LESSEQUAL:     glParm=GL_LEQUAL; break;
1800             case D3DCMP_GREATER:       glParm=GL_GREATER; break;
1801             case D3DCMP_NOTEQUAL:      glParm=GL_NOTEQUAL; break;
1802             case D3DCMP_GREATEREQUAL:  glParm=GL_GEQUAL; break;
1803             case D3DCMP_ALWAYS:        glParm=GL_ALWAYS; break;
1804             default:
1805                 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1806             }
1807             TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1808             glAlphaFunc(glParm, ref);
1809             checkGLcall("glAlphaFunc");
1810         }
1811         break;
1812
1813     case D3DRS_ALPHAREF                  :
1814         {
1815             int glParm = GL_LESS;
1816             float ref = 1.0;
1817
1818             glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
1819             checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
1820
1821             ref = ((float) Value) / 255.0;
1822             TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1823             glAlphaFunc(glParm, ref);
1824             checkGLcall("glAlphaFunc");
1825         }
1826         break;
1827
1828     case D3DRS_CLIPPLANEENABLE           :
1829     case D3DRS_CLIPPING                  :
1830         {
1831             /* Ensure we only do the changed clip planes */
1832             DWORD enable  = 0xFFFFFFFF;
1833             DWORD disable = 0x00000000;
1834             
1835             /* If enabling / disabling all */
1836             if (State == D3DRS_CLIPPING) {
1837                 if (Value) {
1838                     enable  = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1839                     disable = 0x00;
1840                 } else {
1841                     disable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1842                     enable  = 0x00;
1843                 }
1844             } else {
1845                 enable =   Value & ~OldValue;
1846                 disable = ~Value &  OldValue;
1847             }
1848             
1849             if (enable & D3DCLIPPLANE0)  { glEnable(GL_CLIP_PLANE0);  checkGLcall("glEnable(clip plane 0)"); }
1850             if (enable & D3DCLIPPLANE1)  { glEnable(GL_CLIP_PLANE1);  checkGLcall("glEnable(clip plane 1)"); }
1851             if (enable & D3DCLIPPLANE2)  { glEnable(GL_CLIP_PLANE2);  checkGLcall("glEnable(clip plane 2)"); }
1852             if (enable & D3DCLIPPLANE3)  { glEnable(GL_CLIP_PLANE3);  checkGLcall("glEnable(clip plane 3)"); }
1853             if (enable & D3DCLIPPLANE4)  { glEnable(GL_CLIP_PLANE4);  checkGLcall("glEnable(clip plane 4)"); }
1854             if (enable & D3DCLIPPLANE5)  { glEnable(GL_CLIP_PLANE5);  checkGLcall("glEnable(clip plane 5)"); }
1855             
1856             if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
1857             if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
1858             if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
1859             if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
1860             if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
1861             if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
1862         }
1863         break;
1864
1865     case D3DRS_BLENDOP                   :
1866         {
1867             int glParm = GL_FUNC_ADD;
1868
1869             switch ((D3DBLENDOP) Value) {
1870             case D3DBLENDOP_ADD              : glParm = GL_FUNC_ADD;              break;
1871             case D3DBLENDOP_SUBTRACT         : glParm = GL_FUNC_SUBTRACT;         break;
1872             case D3DBLENDOP_REVSUBTRACT      : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
1873             case D3DBLENDOP_MIN              : glParm = GL_MIN;                   break;
1874             case D3DBLENDOP_MAX              : glParm = GL_MAX;                   break;
1875             default:
1876                 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
1877             }
1878             TRACE("glBlendEquation(%x)\n", glParm);
1879             glBlendEquation(glParm);
1880             checkGLcall("glBlendEquation");
1881         }
1882         break;
1883
1884     case D3DRS_TEXTUREFACTOR             :
1885         {
1886             int i;
1887
1888             /* Note the texture color applies to all textures whereas 
1889                GL_TEXTURE_ENV_COLOR applies to active only */
1890             float col[4];
1891             col[0] = ((Value >> 16) & 0xFF) / 255.0;
1892             col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1893             col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1894             col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1895
1896             /* Set the default alpha blend color */
1897             glBlendColor(col[0], col[1], col[2], col[3]);
1898             checkGLcall("glBlendColor");
1899
1900             /* And now the default texture color as well */
1901             for (i=0; i<8; i++) {
1902
1903                 /* Note the D3DRS value applies to all textures, but GL has one
1904                    per texture, so apply it now ready to be used!               */
1905                 checkGLcall("Activate texture.. to update const color");
1906                 glActiveTextureARB(GL_TEXTURE0_ARB + i);
1907
1908                 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1909                 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1910             }
1911         }
1912         break;
1913
1914     case D3DRS_SPECULARENABLE            : 
1915         {
1916             if (Value) {
1917                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
1918                 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
1919             } else {
1920                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
1921                 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
1922             }
1923         }
1924         break;
1925
1926     case D3DRS_STENCILENABLE             :
1927         if (Value) {
1928             glEnable(GL_STENCIL_TEST);
1929             checkGLcall("glEnable GL_STENCIL_TEST");
1930         } else {
1931             glDisable(GL_STENCIL_TEST);
1932             checkGLcall("glDisable GL_STENCIL_TEST");
1933         }
1934         break;
1935
1936     case D3DRS_STENCILFUNC               :
1937         {
1938            int glParm = GL_ALWAYS;
1939            int ref = 0;
1940            GLuint mask = 0xFFFFFFFF;
1941
1942            glGetIntegerv(GL_STENCIL_REF, &ref);
1943            checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1944            glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1945            checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1946
1947            switch ((D3DCMPFUNC) Value) {
1948            case D3DCMP_NEVER:         glParm=GL_NEVER; break;
1949            case D3DCMP_LESS:          glParm=GL_LESS; break;
1950            case D3DCMP_EQUAL:         glParm=GL_EQUAL; break;
1951            case D3DCMP_LESSEQUAL:     glParm=GL_LEQUAL; break;
1952            case D3DCMP_GREATER:       glParm=GL_GREATER; break;
1953            case D3DCMP_NOTEQUAL:      glParm=GL_NOTEQUAL; break;
1954            case D3DCMP_GREATEREQUAL:  glParm=GL_GEQUAL; break;
1955            case D3DCMP_ALWAYS:        glParm=GL_ALWAYS; break;
1956            default:
1957                FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1958            }
1959            TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1960            glStencilFunc(glParm, ref, mask);
1961            checkGLcall("glStencilFunc");
1962         }
1963         break;
1964
1965     case D3DRS_STENCILREF                :
1966         {
1967            int glParm = GL_ALWAYS;
1968            int ref = 0;
1969            GLuint mask = 0xFFFFFFFF;
1970
1971            glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1972            checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1973            glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1974            checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1975
1976            ref = Value;
1977            TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1978            glStencilFunc(glParm, ref, mask);
1979            checkGLcall("glStencilFunc");
1980         }
1981         break;
1982
1983     case D3DRS_STENCILMASK               :
1984         {
1985            int glParm = GL_ALWAYS;
1986            int ref = 0.0;
1987            GLuint mask = Value;
1988
1989            glGetIntegerv(GL_STENCIL_REF, &ref);
1990            checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1991            glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1992            checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1993
1994            TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1995            glStencilFunc(glParm, ref, mask);
1996            checkGLcall("glStencilFunc");
1997         }
1998         break;
1999
2000     case D3DRS_STENCILFAIL               :
2001         {
2002             GLenum fail  ; 
2003             GLenum zpass ; 
2004             GLenum zfail ; 
2005
2006             fail = StencilOp(Value);
2007             glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2008             checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2009             glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2010             checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2011
2012             TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2013             glStencilOp(fail, zfail, zpass);
2014             checkGLcall("glStencilOp(fail, zfail, zpass);");
2015         }
2016         break;
2017     case D3DRS_STENCILZFAIL              :
2018         {
2019             GLenum fail  ; 
2020             GLenum zpass ; 
2021             GLenum zfail ; 
2022
2023             glGetIntegerv(GL_STENCIL_FAIL, &fail);
2024             checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2025             glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2026             checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2027             zfail = StencilOp(Value);
2028
2029             TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2030             glStencilOp(fail, zfail, zpass);
2031             checkGLcall("glStencilOp(fail, zfail, zpass);");
2032         }
2033         break;
2034     case D3DRS_STENCILPASS               :
2035         {
2036             GLenum fail  ; 
2037             GLenum zpass ; 
2038             GLenum zfail ; 
2039
2040             glGetIntegerv(GL_STENCIL_FAIL, &fail);
2041             checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2042             zpass = StencilOp(Value);
2043             glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2044             checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2045
2046             TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2047             glStencilOp(fail, zfail, zpass);
2048             checkGLcall("glStencilOp(fail, zfail, zpass);");
2049         }
2050         break;
2051
2052     case D3DRS_STENCILWRITEMASK          :
2053         {
2054             glStencilMask(Value);
2055             TRACE("glStencilMask(%lu)\n", Value);
2056             checkGLcall("glStencilMask");
2057         }
2058         break;
2059
2060         /* Unhandled yet...! */
2061     case D3DRS_LINEPATTERN               :
2062     case D3DRS_LASTPIXEL                 :
2063     case D3DRS_FOGENABLE                 :
2064     case D3DRS_ZVISIBLE                  :
2065     case D3DRS_FOGCOLOR                  :
2066     case D3DRS_FOGTABLEMODE              :
2067     case D3DRS_FOGSTART                  :
2068     case D3DRS_FOGEND                    :
2069     case D3DRS_FOGDENSITY                :
2070     case D3DRS_EDGEANTIALIAS             :
2071     case D3DRS_ZBIAS                     :
2072     case D3DRS_RANGEFOGENABLE            :
2073     case D3DRS_WRAP0                     :
2074     case D3DRS_WRAP1                     :
2075     case D3DRS_WRAP2                     :
2076     case D3DRS_WRAP3                     :
2077     case D3DRS_WRAP4                     :
2078     case D3DRS_WRAP5                     :
2079     case D3DRS_WRAP6                     :
2080     case D3DRS_WRAP7                     :
2081     case D3DRS_FOGVERTEXMODE             :
2082     case D3DRS_COLORVERTEX               :
2083     case D3DRS_LOCALVIEWER               :
2084     case D3DRS_NORMALIZENORMALS          :
2085     case D3DRS_DIFFUSEMATERIALSOURCE     :
2086     case D3DRS_SPECULARMATERIALSOURCE    :
2087     case D3DRS_AMBIENTMATERIALSOURCE     :
2088     case D3DRS_EMISSIVEMATERIALSOURCE    :
2089     case D3DRS_VERTEXBLEND               :
2090     case D3DRS_SOFTWAREVERTEXPROCESSING  :
2091     case D3DRS_POINTSIZE                 :
2092     case D3DRS_POINTSIZE_MIN             :
2093     case D3DRS_POINTSPRITEENABLE         :
2094     case D3DRS_POINTSCALEENABLE          :
2095     case D3DRS_POINTSCALE_A              :
2096     case D3DRS_POINTSCALE_B              :
2097     case D3DRS_POINTSCALE_C              :
2098     case D3DRS_MULTISAMPLEANTIALIAS      :
2099     case D3DRS_MULTISAMPLEMASK           :
2100     case D3DRS_PATCHEDGESTYLE            :
2101     case D3DRS_PATCHSEGMENTS             :
2102     case D3DRS_DEBUGMONITORTOKEN         :
2103     case D3DRS_POINTSIZE_MAX             :
2104     case D3DRS_INDEXEDVERTEXBLENDENABLE  :
2105     case D3DRS_COLORWRITEENABLE          :
2106     case D3DRS_TWEENFACTOR               :
2107         /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2108         TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2109         break;
2110     default:
2111         FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2112     }
2113
2114     return D3D_OK;
2115 }
2116 HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2117     ICOM_THIS(IDirect3DDevice8Impl,iface);
2118     TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2119     *pValue = This->StateBlock.renderstate[State];
2120     return D3D_OK;
2121 }
2122 HRESULT  WINAPI  IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2123     ICOM_THIS(IDirect3DDevice8Impl,iface);
2124
2125     void *memory;
2126
2127     TRACE("(%p)\n", This);
2128     if (This->isRecordingState) {
2129         TRACE("(%p) already recording! returning error\n", This);
2130         return D3DERR_INVALIDCALL;
2131     }
2132
2133     /* Allocate Storage */
2134     memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2135     This->isRecordingState = TRUE;
2136     This->UpdateStateBlock = memory;
2137
2138     return D3D_OK;
2139 }
2140 HRESULT  WINAPI  IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2141
2142     ICOM_THIS(IDirect3DDevice8Impl,iface);
2143     TRACE("(%p)\n", This);
2144
2145     if (!This->isRecordingState) {
2146         TRACE("(%p) not recording! returning error\n", This);
2147         return D3DERR_INVALIDCALL;
2148     }
2149
2150     This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2151     *pToken = (DWORD) This->UpdateStateBlock;
2152     This->isRecordingState = FALSE;
2153     This->UpdateStateBlock = &This->StateBlock;
2154
2155     TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2156     return D3D_OK;
2157 }
2158
2159 HRESULT  WINAPI  IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2160
2161     STATEBLOCK *pSB = (STATEBLOCK *)Token;
2162     int i,j;
2163
2164     ICOM_THIS(IDirect3DDevice8Impl,iface);
2165     TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2166
2167     /* FIXME: Only apply applicable states not all states */
2168
2169     if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2170
2171         for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2172
2173             if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2174                 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2175             if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2176                 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2177         }
2178
2179         if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2180             IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2181
2182         /* TODO: Vertex Shader Constants */
2183     }
2184
2185     if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2186
2187         if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2188             IDirect3DDevice8Impl_SetVertexShader(iface, pSB->PixelShader);
2189
2190         /* TODO: Pixel Shader Constants */
2191     }
2192
2193     /* Others + Render & Texture */
2194     if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2195         for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2196             if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2197                 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2198         }
2199
2200         if (pSB->Set.Indices && pSB->Changed.Indices)
2201             IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2202
2203         if (pSB->Set.material && pSB->Changed.material)
2204             IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2205
2206         if (pSB->Set.viewport && pSB->Changed.viewport)
2207             IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2208
2209         for (i=0; i<MAX_STREAMS; i++) {
2210             if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2211                 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2212         }
2213
2214         for (i=0; i<MAX_CLIPPLANES; i++) {
2215             if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2216                 float clip[4];
2217
2218                 clip[0] = pSB->clipplane[i][0];
2219                 clip[1] = pSB->clipplane[i][1];
2220                 clip[2] = pSB->clipplane[i][2];
2221                 clip[3] = pSB->clipplane[i][3];
2222                 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2223             }
2224         }
2225
2226         /* Render */
2227         for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2228
2229             if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2230                 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2231
2232         }
2233
2234         /* Texture */
2235         for (j=0; j<8; j++) {
2236             for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2237
2238                 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i])
2239                     IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2240             }
2241
2242         }
2243
2244     } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2245
2246         for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2247             if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2248                 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2249
2250         }
2251
2252         for (j=0; j<8; i++) {
2253             for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2254
2255                 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2256                     pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2257                     IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2258             }
2259         }
2260
2261     } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2262
2263         for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2264             if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2265                 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2266
2267         }
2268
2269         for (j=0; j<8; i++) {
2270             for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2271
2272                 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2273                     pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2274                     IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2275             }
2276         }
2277
2278
2279     } else {
2280         FIXME("Unrecognized state block type %d\n", pSB->blockType);
2281     }
2282     memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2283     TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2284
2285     return D3D_OK;
2286 }
2287 HRESULT  WINAPI  IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2288
2289     STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2290
2291     ICOM_THIS(IDirect3DDevice8Impl,iface);
2292
2293     TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2294
2295     /* If not recorded, then update can just recapture */
2296     if (updateBlock->blockType != D3DSBT_RECORDED) {
2297         DWORD tmpToken;
2298         STATEBLOCK *tmpBlock;
2299         IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2300         tmpBlock = (STATEBLOCK *)tmpToken;
2301         memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2302         IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2303
2304         /* FIXME: This will record states of new lights! May need to have and save set_lights
2305            across this action */
2306
2307     } else {
2308         int i,j;
2309
2310         /* Recorded => Only update 'changed' values */
2311         if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2312             updateBlock->VertexShader = This->StateBlock.VertexShader;
2313             TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2314         }
2315
2316         /* TODO: Vertex Shader Constants */
2317
2318         for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2319           if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2320               TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2321               updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2322           }
2323
2324           if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i], 
2325                                                    &updateBlock->lights[i], 
2326                                                    sizeof(D3DLIGHT8)) != 0) {
2327               TRACE("Updating lights for light %d\n", i);
2328               memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2329           }
2330         }
2331
2332         if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2333             TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2334             updateBlock->lights[i] = This->StateBlock.lights[i];
2335                 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2336         }
2337
2338         /* TODO: Pixel Shader Constants */
2339
2340         /* Others + Render & Texture */
2341        for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2342             if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i], 
2343                                                    &updateBlock->transforms[i], 
2344                                                    sizeof(D3DMATRIX)) != 0) {
2345                 TRACE("Updating transform %d\n", i);
2346                 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2347             }
2348        }
2349
2350        if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2351                                     || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2352            TRACE("Updating pindexData to %p, baseVertexIndex to %d\n", 
2353                        This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2354            updateBlock->pIndexData = This->StateBlock.pIndexData;
2355            updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2356        }
2357
2358        if (updateBlock->Set.material && memcmp(&This->StateBlock.material, 
2359                                                    &updateBlock->material, 
2360                                                    sizeof(D3DMATERIAL8)) != 0) {
2361                 TRACE("Updating material\n");
2362                 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2363        }
2364            
2365        if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport, 
2366                                                    &updateBlock->viewport, 
2367                                                    sizeof(D3DVIEWPORT8)) != 0) {
2368                 TRACE("Updating viewport\n");
2369                 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2370        }
2371
2372        for (i=0; i<MAX_STREAMS; i++) {
2373            if (updateBlock->Set.stream_source[i] && 
2374                            ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2375                            (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2376                TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i], 
2377                                                                         This->StateBlock.stream_stride[i]);
2378                updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2379                updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2380            }
2381        }
2382
2383        for (i=0; i<MAX_CLIPPLANES; i++) {
2384            if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i], 
2385                                                        &updateBlock->clipplane[i], 
2386                                                        sizeof(updateBlock->clipplane)) != 0) {
2387
2388                TRACE("Updating clipplane %d\n", i);
2389                memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i], 
2390                                        sizeof(updateBlock->clipplane));
2391            }
2392        }
2393
2394        /* Render */
2395        for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2396
2397            if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] != 
2398                                                        This->StateBlock.renderstate[i])) {
2399                TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2400                updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2401            }
2402        }
2403
2404        /* Texture */
2405        for (j=0; j<8; j++) {
2406            for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2407
2408                if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] != 
2409                                                                 This->StateBlock.texture_state[j][i])) {
2410                    TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i], 
2411                                updateBlock->texture_state[j][i]);
2412                    updateBlock->texture_state[j][i] =  This->StateBlock.texture_state[j][i];
2413                }
2414            }
2415
2416        }
2417     }
2418
2419     TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2420
2421     return D3D_OK;
2422 }
2423 HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2424     ICOM_THIS(IDirect3DDevice8Impl,iface);
2425     TRACE("(%p) : freeing token %lx\n", This, Token);
2426     HeapFree(GetProcessHeap(), 0, (void *)Token);
2427     return D3D_OK;
2428 }
2429
2430 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type,DWORD* pToken) {
2431     void *memory;
2432     STATEBLOCK *s;
2433     int i,j;
2434
2435     ICOM_THIS(IDirect3DDevice8Impl,iface);
2436     TRACE("(%p) : for type %d\n", This, Type);
2437
2438     /* Allocate Storage */
2439     memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2440     if (memory) memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2441     *pToken = (DWORD) memory;
2442     s = memory;
2443     s->blockType = Type;
2444
2445     TRACE("Updating changed flags appropriate for type %d\n", Type);
2446
2447     if (Type == D3DSBT_ALL) {
2448         TRACE("ALL => Pretend everything has changed\n");
2449         memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2450
2451     } else if (Type == D3DSBT_PIXELSTATE) {
2452
2453         memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2454
2455         /* TODO: Pixel Shader Constants */
2456         s->Changed.pixelShader = TRUE;
2457         for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2458             s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2459         }
2460         for (j=0; j<8; i++) {
2461             for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2462                 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2463             }
2464         }
2465
2466     } else if (Type == D3DSBT_VERTEXSTATE) {
2467
2468         memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2469
2470         /* TODO: Vertex Shader Constants */
2471         s->Changed.vertexShader = TRUE;
2472
2473         for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2474             s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2475         }
2476         for (j=0; j<8; i++) {
2477             for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2478                 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2479             }
2480         }
2481
2482         for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2483             s->Changed.lightEnable[i] = TRUE;
2484             s->Changed.lights[i] = TRUE;
2485         }
2486
2487     } else {
2488         FIXME("Unrecognized state block type %d\n", Type);
2489     }
2490     TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2491     return D3D_OK;
2492 }
2493
2494 HRESULT  WINAPI  IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2495     ICOM_THIS(IDirect3DDevice8Impl,iface);
2496     FIXME("(%p) : stub\n", This);    return D3D_OK;
2497 }
2498 HRESULT  WINAPI  IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2499     ICOM_THIS(IDirect3DDevice8Impl,iface);
2500     FIXME("(%p) : stub\n", This);    return D3D_OK;
2501 }
2502 HRESULT  WINAPI  IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2503     ICOM_THIS(IDirect3DDevice8Impl,iface);
2504     TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2505     *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
2506     IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2507     return D3D_OK;
2508 }
2509 HRESULT  WINAPI  IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2510
2511     IDirect3DBaseTexture8 *oldTxt;
2512
2513     ICOM_THIS(IDirect3DDevice8Impl,iface);
2514     D3DRESOURCETYPE textureType;
2515
2516     oldTxt = This->StateBlock.textures[Stage];
2517     TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2518
2519     This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2520     This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2521     This->UpdateStateBlock->textures[Stage] = pTexture;
2522
2523     /* Handle recording of state blocks */
2524     if (This->isRecordingState) {
2525         TRACE("Recording... not performing anything\n");
2526         return D3D_OK;
2527     }
2528
2529     /* Make appropriate texture active */
2530     glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2531     checkGLcall("glActiveTextureARB");
2532
2533     /* Decrement the count of the previous texture */
2534     /* FIXME PERF: If old == new and not dirty then skip all this */
2535     if (oldTxt != NULL) {
2536         IDirect3DBaseTexture8Impl_Release(oldTxt);
2537     }
2538
2539     if (pTexture) {
2540         IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
2541
2542         /* Now setup the texture appropraitly */
2543         textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2544
2545         if (textureType == D3DRTYPE_TEXTURE) {
2546             IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
2547             int i;
2548
2549             /* Standard 2D texture */
2550             TRACE("Standard 2d texture\n");
2551             This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
2552
2553 /*            for (i=0; i<pTexture2->levels; i++) { */
2554             i=0;
2555             {
2556
2557                 if (pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2558                     glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2559                     checkGLcall("glBindTexture");
2560                     TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2561                 } else {
2562
2563                     if (pTexture2->surfaces[i]->textureName == 0) {
2564                         glGenTextures(1, &pTexture2->surfaces[i]->textureName);
2565                         checkGLcall("glGenTextures");
2566                         TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2567                     }
2568
2569                     glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2570                     checkGLcall("glBindTexture");
2571
2572                     TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2573                           GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
2574                           pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2575                           pTexture2->surfaces[i]->allocatedMemory);
2576                     glTexImage2D(GL_TEXTURE_2D, i,
2577                                  fmt2glintFmt(pTexture2->format),
2578                                  pTexture2->surfaces[i]->myDesc.Width,
2579                                  pTexture2->surfaces[i]->myDesc.Height,
2580                                  0,
2581                                  fmt2glFmt(pTexture2->format),
2582                                  fmt2glType(pTexture2->format),
2583                                  pTexture2->surfaces[i]->allocatedMemory
2584                                 );
2585                     checkGLcall("glTexImage2D");
2586
2587                     /*
2588                      * The following enable things to work but I dont think
2589                      * they all go here - FIXME! @@@
2590                      */
2591                     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2592                     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2593                     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2594                     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2595
2596                     pTexture2->Dirty = FALSE;
2597                 }
2598
2599             }
2600
2601         } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
2602             IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
2603             int i;
2604
2605             /* Standard 3D (volume) texture */
2606             TRACE("Standard 3d texture\n");
2607             This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
2608
2609 /*            for (i=0; i<pTexture2->levels; i++) { */
2610             i=0;
2611             {
2612
2613                 if (pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2614                     glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2615                     checkGLcall("glBindTexture");
2616                     TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2617                 } else {
2618
2619                     if (pTexture2->volumes[i]->textureName == 0) {
2620                         glGenTextures(1, &pTexture2->volumes[i]->textureName);
2621                         checkGLcall("glGenTextures");
2622                         TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2623                     }
2624
2625                     glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2626                     checkGLcall("glBindTexture");
2627
2628                     TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2629                           GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
2630                           pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
2631                           0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2632                           pTexture2->volumes[i]->allocatedMemory);
2633                     glTexImage3D(GL_TEXTURE_3D, i,
2634                                  fmt2glintFmt(pTexture2->format),
2635                                  pTexture2->volumes[i]->myDesc.Width,
2636                                  pTexture2->volumes[i]->myDesc.Height,
2637                                  pTexture2->volumes[i]->myDesc.Depth,
2638                                  0,
2639                                  fmt2glFmt(pTexture2->format),
2640                                  fmt2glType(pTexture2->format),
2641                                  pTexture2->volumes[i]->allocatedMemory
2642                                 );
2643                     checkGLcall("glTexImage3D");
2644
2645                     /*
2646                      * The following enable things to work but I dont think
2647                      * they all go here - FIXME! @@@
2648                      */
2649                     glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2650                     glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2651                     glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
2652                     glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2653                     glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2654
2655                     pTexture2->Dirty = FALSE;
2656                 }
2657             }
2658
2659         } else {
2660             FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
2661         }
2662     } else {
2663         TRACE("Setting to no texture (ie default texture)\n");
2664         This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
2665         glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
2666         checkGLcall("glBindTexture");
2667         TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
2668     }
2669
2670     /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
2671        a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
2672     setupTextureStates (iface, Stage);
2673        
2674     return D3D_OK;
2675 }
2676
2677 HRESULT  WINAPI  IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
2678     ICOM_THIS(IDirect3DDevice8Impl,iface);
2679     TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
2680     *pValue = This->StateBlock.texture_state[Stage][Type];
2681     return D3D_OK;
2682 }
2683
2684 HRESULT  WINAPI  IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
2685     ICOM_THIS(IDirect3DDevice8Impl,iface);
2686
2687     /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2688    
2689     TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
2690
2691     This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
2692     This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
2693     This->UpdateStateBlock->texture_state[Stage][Type] = Value;
2694
2695     /* Handle recording of state blocks */
2696     if (This->isRecordingState) {
2697         TRACE("Recording... not performing anything\n");
2698         return D3D_OK;
2699     }
2700
2701     /* Make appropriate texture active */
2702     TRACE("Activating appropriate texture state %ld\n", Stage);
2703     glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2704     checkGLcall("glActiveTextureARB");
2705
2706     switch (Type) {
2707
2708     case D3DTSS_MINFILTER             :
2709         if (Value == D3DTEXF_POINT) {  
2710             glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2711             checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_NEAREST");
2712         } else if (Value == D3DTEXF_LINEAR) {
2713             glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2714             checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_LINEAR");
2715         } else {
2716             FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", Value);
2717         }
2718         break;
2719
2720
2721     case D3DTSS_MAGFILTER             :
2722         if (Value == D3DTEXF_POINT) {
2723             glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2724             checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
2725         } else if (Value == D3DTEXF_LINEAR) {
2726             glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2727             checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
2728         } else {
2729             FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
2730         }
2731         break;
2732
2733     case D3DTSS_COLORARG0             :
2734     case D3DTSS_ALPHAARG0             :
2735         /* FIXME: Mesa seems to struggle setting these at the moment */
2736         break;
2737
2738     case D3DTSS_COLORARG1             :
2739     case D3DTSS_COLORARG2             :
2740     case D3DTSS_ALPHAARG1             :
2741     case D3DTSS_ALPHAARG2             :
2742         {
2743             BOOL isAlphaReplicate = FALSE;
2744             BOOL isComplement     = FALSE;
2745             BOOL isAlphaArg       = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
2746             int  operand= GL_SRC_COLOR;
2747             int  source = GL_TEXTURE;
2748
2749             /* Catch alpha replicate */
2750             if (Value & D3DTA_ALPHAREPLICATE) {
2751                 Value = Value & ~D3DTA_ALPHAREPLICATE;
2752                 isAlphaReplicate = TRUE;
2753             }
2754
2755             /* Catch Complement */
2756             if (Value & D3DTA_COMPLEMENT) {
2757                 Value = Value & ~D3DTA_COMPLEMENT;
2758                 isComplement = TRUE;
2759             }
2760
2761             /* Calculate the operand */
2762             if (isAlphaReplicate && !isComplement) {
2763                 operand = GL_SRC_ALPHA;
2764             } else if (isAlphaReplicate && isComplement) {
2765                 operand = GL_ONE_MINUS_SRC_ALPHA;
2766             } else if (isComplement) {
2767                 if (isAlphaArg) {
2768                     operand = GL_ONE_MINUS_SRC_COLOR;
2769                 } else {
2770                     operand = GL_ONE_MINUS_SRC_ALPHA;
2771                 }
2772             } else {
2773                 if (isAlphaArg) {
2774                     operand = GL_SRC_ALPHA;
2775                 } else {
2776                     operand = GL_SRC_COLOR;
2777                 }
2778             }
2779
2780             /* Calculate the source */
2781             switch (Value) {
2782             case D3DTA_CURRENT:   source  = GL_PREVIOUS_EXT;
2783                                   break;
2784             case D3DTA_DIFFUSE:   source  = GL_PRIMARY_COLOR_EXT;
2785                                   break;
2786             case D3DTA_TEXTURE:   source  = GL_TEXTURE;
2787                                   break;
2788             case D3DTA_TFACTOR:   source  = GL_CONSTANT_EXT;
2789                                   break;
2790
2791             /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
2792                isnt supported until base GL supports it
2793                There is no concept of temp registers as far as I can tell                          */
2794
2795             default:
2796                 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
2797             }
2798
2799             if (isAlphaArg) {
2800                 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
2801                 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
2802                 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
2803                 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
2804                 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
2805             } else {
2806                 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
2807                 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
2808                 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
2809                 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
2810                 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
2811             }
2812         }
2813         break;
2814
2815     case D3DTSS_ALPHAOP               :
2816     case D3DTSS_COLOROP               :
2817         {
2818
2819             int Scale = 1;
2820             int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
2821
2822             if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
2823                 /* TODO: Disable by making this and all later levels disabled */
2824                 glDisable(GL_TEXTURE_1D);
2825                 checkGLcall("Disable GL_TEXTURE_1D");
2826                 glDisable(GL_TEXTURE_2D);
2827                 checkGLcall("Disable GL_TEXTURE_2D");
2828                 glDisable(GL_TEXTURE_3D);
2829                 checkGLcall("Disable GL_TEXTURE_3D");
2830             } else {
2831
2832                 /* Enable only the appropriate texture dimension */
2833                 if (Type==D3DTSS_COLOROP) {
2834                     if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
2835                         glEnable(GL_TEXTURE_1D);
2836                         checkGLcall("Enable GL_TEXTURE_1D");
2837                     } else {
2838                         glDisable(GL_TEXTURE_1D);
2839                         checkGLcall("Disable GL_TEXTURE_1D");
2840                     } 
2841                     if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
2842                         glEnable(GL_TEXTURE_2D);
2843                         checkGLcall("Enable GL_TEXTURE_2D");
2844                     } else {
2845                         glDisable(GL_TEXTURE_2D);
2846                         checkGLcall("Disable GL_TEXTURE_2D");
2847                     }
2848                     if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
2849                         glEnable(GL_TEXTURE_3D);
2850                         checkGLcall("Enable GL_TEXTURE_3D");
2851                     } else {
2852                         glDisable(GL_TEXTURE_3D);
2853                         checkGLcall("Disable GL_TEXTURE_3D");
2854                     }
2855                 }
2856
2857                 /* Now set up the operand correctly */
2858                 switch (Value) {
2859                 case D3DTOP_DISABLE                   :
2860                     /* Contrary to the docs, alpha can be disabled when colorop is enabled
2861                        and it works, so ignore this op */
2862                     TRACE("Disable ALPHAOP but COLOROP enabled!\n");
2863                     break;
2864
2865                 case D3DTOP_SELECTARG1                :
2866                     glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
2867                     checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
2868                     break;
2869
2870                 case D3DTOP_MODULATE4X                : Scale = Scale * 2;  /* Drop through */
2871                 case D3DTOP_MODULATE2X                : Scale = Scale * 2;  /* Drop through */
2872                 case D3DTOP_MODULATE                  :
2873
2874                     /* Correct scale */
2875                     if (Type == D3DTSS_ALPHAOP) {
2876                         glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
2877                         checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
2878                     } else {
2879                         glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
2880                         checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
2881                     }
2882                     glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
2883                     checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
2884                     break;
2885
2886                 case D3DTOP_ADD                       :
2887                     glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
2888                     checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
2889                     break;
2890
2891                 case D3DTOP_ADDSIGNED2X               : Scale = Scale * 2;  /* Drop through */
2892                 case D3DTOP_ADDSIGNED                 :
2893                     glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
2894                     checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
2895                     break;
2896
2897                 case D3DTOP_DOTPRODUCT3               :
2898                     /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
2899                     checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
2900                     break;*/
2901
2902                 case D3DTOP_SUBTRACT                  :
2903                     /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
2904                 case D3DTOP_SELECTARG2                :
2905                     /* GL_REPLACE, swap args 0 and 1? */
2906                 case D3DTOP_ADDSMOOTH                 :
2907                 case D3DTOP_BLENDDIFFUSEALPHA         :
2908                 case D3DTOP_BLENDTEXTUREALPHA         :
2909                 case D3DTOP_BLENDFACTORALPHA          :
2910                 case D3DTOP_BLENDTEXTUREALPHAPM       :
2911                 case D3DTOP_BLENDCURRENTALPHA         :
2912                 case D3DTOP_PREMODULATE               :
2913                 case D3DTOP_MODULATEALPHA_ADDCOLOR    :
2914                 case D3DTOP_MODULATECOLOR_ADDALPHA    :
2915                 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
2916                 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
2917                 case D3DTOP_BUMPENVMAP                :
2918                 case D3DTOP_BUMPENVMAPLUMINANCE       :
2919                 case D3DTOP_MULTIPLYADD               :
2920                 case D3DTOP_LERP                      :
2921                 default:
2922                     FIXME("Unhandled texture operation %ld\n", Value);
2923                 }
2924             }
2925             break;
2926         }
2927
2928         /* Unhandled */
2929     case D3DTSS_BUMPENVMAT00          :
2930     case D3DTSS_BUMPENVMAT01          :
2931     case D3DTSS_BUMPENVMAT10          :
2932     case D3DTSS_BUMPENVMAT11          :
2933     case D3DTSS_TEXCOORDINDEX         :
2934     case D3DTSS_ADDRESSU              :
2935     case D3DTSS_ADDRESSV              :
2936     case D3DTSS_BORDERCOLOR           :
2937     case D3DTSS_MIPFILTER             :
2938     case D3DTSS_MIPMAPLODBIAS         :
2939     case D3DTSS_MAXMIPLEVEL           :
2940     case D3DTSS_MAXANISOTROPY         :
2941     case D3DTSS_BUMPENVLSCALE         :
2942     case D3DTSS_BUMPENVLOFFSET        :
2943     case D3DTSS_TEXTURETRANSFORMFLAGS :
2944     case D3DTSS_ADDRESSW              :
2945     case D3DTSS_RESULTARG             :
2946     default:
2947         /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
2948         TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
2949     }
2950     return D3D_OK;
2951 }
2952 HRESULT  WINAPI  IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
2953     ICOM_THIS(IDirect3DDevice8Impl,iface);
2954     FIXME("(%p) : stub\n", This);    return D3D_OK;
2955 }
2956 HRESULT  WINAPI  IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
2957     ICOM_THIS(IDirect3DDevice8Impl,iface);
2958     FIXME("(%p) : stub\n", This);    return D3D_OK;
2959 }
2960 HRESULT  WINAPI  IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
2961     ICOM_THIS(IDirect3DDevice8Impl,iface);
2962     FIXME("(%p) : stub\n", This);    return D3D_OK;
2963 }
2964 HRESULT  WINAPI  IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
2965     ICOM_THIS(IDirect3DDevice8Impl,iface);
2966     FIXME("(%p) : stub\n", This);    return D3D_OK;
2967 }
2968 HRESULT  WINAPI  IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
2969     ICOM_THIS(IDirect3DDevice8Impl,iface);
2970     FIXME("(%p) : stub\n", This);    return D3D_OK;
2971 }
2972 HRESULT  WINAPI  IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
2973     ICOM_THIS(IDirect3DDevice8Impl,iface);
2974     FIXME("(%p) : stub\n", This);    return D3D_OK;
2975 }
2976 HRESULT  WINAPI  IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
2977
2978     IDirect3DVertexBuffer8     *pVB;
2979     D3DVERTEXBUFFER_DESC        VtxBufDsc;
2980
2981     ICOM_THIS(IDirect3DDevice8Impl,iface);
2982     pVB = This->StateBlock.stream_source[0];
2983
2984     TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
2985
2986     IDirect3DVertexBuffer8Impl_GetDesc(pVB, &VtxBufDsc);
2987     DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
2988                    VtxBufDsc.FVF, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL);
2989
2990     return D3D_OK;
2991 }
2992 HRESULT  WINAPI  IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
2993                                                            UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
2994     UINT idxStride = 2;
2995     IDirect3DIndexBuffer8      *pIB;
2996     IDirect3DVertexBuffer8     *pVB;
2997     D3DINDEXBUFFER_DESC         IdxBufDsc;
2998     D3DVERTEXBUFFER_DESC        VtxBufDsc;
2999
3000     ICOM_THIS(IDirect3DDevice8Impl,iface);
3001     pIB = This->StateBlock.pIndexData;
3002     pVB = This->StateBlock.stream_source[0];
3003
3004     TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3005           minIndex, NumVertices, startIndex, primCount);
3006
3007     IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3008     if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3009         idxStride = 2;
3010     } else {
3011         idxStride = 4;
3012     }
3013
3014     IDirect3DVertexBuffer8Impl_GetDesc(pVB, &VtxBufDsc);
3015     DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, VtxBufDsc.FVF, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3016                    This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory);
3017
3018     return D3D_OK;
3019 }
3020 HRESULT  WINAPI  IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3021     ICOM_THIS(IDirect3DDevice8Impl,iface);
3022
3023     TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3024
3025     if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3026
3027     This->StateBlock.stream_source[0] = NULL;
3028     This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3029     DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3030                    0, 0, 0, NULL);
3031     This->StateBlock.stream_stride[0] = 0;
3032
3033     /*stream zero settings set to null at end */
3034     return D3D_OK;
3035 }
3036 HRESULT  WINAPI  IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3037                                                              UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3038                                                              D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3039                                                              UINT VertexStreamZeroStride) {
3040     int idxStride;
3041     ICOM_THIS(IDirect3DDevice8Impl,iface);
3042     TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3043           MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData,  IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3044
3045     if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3046     if (IndexDataFormat == D3DFMT_INDEX16) {
3047         idxStride = 2;
3048     } else {
3049         idxStride = 4;
3050     }
3051
3052     This->StateBlock.stream_source[0] = NULL;
3053     This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3054     DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3055                    This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData);
3056
3057     /*stream zero settings set to null at end */
3058     This->StateBlock.stream_stride[0] = 0;
3059     IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3060
3061     return D3D_OK;
3062 }
3063 HRESULT  WINAPI  IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3064     ICOM_THIS(IDirect3DDevice8Impl,iface);
3065     FIXME("(%p) : stub\n", This);    return D3D_OK;
3066 }
3067 HRESULT  WINAPI  IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) {
3068     ICOM_THIS(IDirect3DDevice8Impl,iface);
3069     FIXME("(%p) : stub\n", This);    return D3D_OK;
3070 }
3071 HRESULT  WINAPI  IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3072     ICOM_THIS(IDirect3DDevice8Impl,iface);
3073
3074     This->UpdateStateBlock->VertexShader = Handle;
3075     This->UpdateStateBlock->Changed.vertexShader = TRUE;
3076     This->UpdateStateBlock->Set.vertexShader = TRUE;
3077
3078     /* Handle recording of state blocks */
3079     if (This->isRecordingState) {
3080         TRACE("Recording... not performing anything\n");
3081         return D3D_OK;
3082     }
3083
3084     if (Handle <= VS_HIGHESTFIXEDFXF) {
3085         TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3086         return D3D_OK;
3087     } else {
3088         FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3089         return D3D_OK;
3090     }
3091 }
3092 HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3093     ICOM_THIS(IDirect3DDevice8Impl,iface);
3094     TRACE("(%p) = %ld\n", This, This->StateBlock.VertexShader);
3095     *pHandle = This->StateBlock.VertexShader;
3096     return D3D_OK;
3097 }
3098
3099 HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3100     ICOM_THIS(IDirect3DDevice8Impl,iface);
3101     FIXME("(%p) : stub\n", This);    return D3D_OK;
3102 }
3103 HRESULT  WINAPI  IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3104     ICOM_THIS(IDirect3DDevice8Impl,iface);
3105     FIXME("(%p) : stub\n", This);    return D3D_OK;
3106 }
3107 HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3108     ICOM_THIS(IDirect3DDevice8Impl,iface);
3109     FIXME("(%p) : stub\n", This);    return D3D_OK;
3110 }
3111 HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3112     ICOM_THIS(IDirect3DDevice8Impl,iface);
3113     FIXME("(%p) : stub\n", This);    return D3D_OK;
3114 }
3115 HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3116     ICOM_THIS(IDirect3DDevice8Impl,iface);
3117     FIXME("(%p) : stub\n", This);    return D3D_OK;
3118 }
3119
3120 HRESULT  WINAPI  IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3121
3122     IDirect3DIndexBuffer8 *oldIdxs;
3123
3124     ICOM_THIS(IDirect3DDevice8Impl,iface);
3125     TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3126     oldIdxs = This->StateBlock.pIndexData;
3127
3128     This->UpdateStateBlock->Changed.Indices = TRUE;
3129     This->UpdateStateBlock->Set.Indices = TRUE;
3130     This->UpdateStateBlock->pIndexData = pIndexData;
3131     This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3132
3133     /* Handle recording of state blocks */
3134     if (This->isRecordingState) {
3135         TRACE("Recording... not performing anything\n");
3136         return D3D_OK;
3137     }
3138
3139     if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3140     if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3141     return D3D_OK;
3142 }
3143 HRESULT  WINAPI  IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3144     ICOM_THIS(IDirect3DDevice8Impl,iface);
3145     FIXME("(%p) : stub\n", This);
3146
3147     *ppIndexData = This->StateBlock.pIndexData;
3148     /* up ref count on ppindexdata */
3149     if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3150     *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3151
3152     return D3D_OK;
3153 }
3154 HRESULT  WINAPI  IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction,DWORD* pHandle) {
3155     ICOM_THIS(IDirect3DDevice8Impl,iface);
3156     FIXME("(%p) : stub\n", This);    return D3D_OK;
3157 }
3158 HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3159     ICOM_THIS(IDirect3DDevice8Impl,iface);
3160
3161     This->UpdateStateBlock->PixelShader = Handle;
3162     This->UpdateStateBlock->Changed.pixelShader = TRUE;
3163     This->UpdateStateBlock->Set.pixelShader = TRUE;
3164
3165     /* Handle recording of state blocks */
3166     if (This->isRecordingState) {
3167         TRACE("Recording... not performing anything\n");
3168         return D3D_OK;
3169     }
3170
3171     /* FIXME: Quieten when not being used */
3172     if (Handle != 0) {
3173        FIXME("(%p) : stub %ld\n", This, Handle);
3174     } else {
3175        TRACE("(%p) : stub %ld\n", This, Handle);
3176     }
3177
3178     return D3D_OK;
3179 }
3180 HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3181     ICOM_THIS(IDirect3DDevice8Impl,iface);
3182     TRACE("(%p) : returning %ld\n", This, This->StateBlock.PixelShader);
3183     *pHandle = This->StateBlock.PixelShader;
3184     return D3D_OK;
3185 }
3186
3187 HRESULT  WINAPI  IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3188     ICOM_THIS(IDirect3DDevice8Impl,iface);
3189     FIXME("(%p) : stub\n", This);    return D3D_OK;
3190 }
3191 HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3192     ICOM_THIS(IDirect3DDevice8Impl,iface);
3193     FIXME("(%p) : stub\n", This);    return D3D_OK;
3194 }
3195 HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3196     ICOM_THIS(IDirect3DDevice8Impl,iface);
3197     FIXME("(%p) : stub\n", This);    return D3D_OK;
3198 }
3199 HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3200     ICOM_THIS(IDirect3DDevice8Impl,iface);
3201     FIXME("(%p) : stub\n", This);    return D3D_OK;
3202 }
3203 HRESULT  WINAPI  IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3204     ICOM_THIS(IDirect3DDevice8Impl,iface);
3205     FIXME("(%p) : stub\n", This);    return D3D_OK;
3206 }
3207 HRESULT  WINAPI  IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3208     ICOM_THIS(IDirect3DDevice8Impl,iface);
3209     FIXME("(%p) : stub\n", This);    return D3D_OK;
3210 }
3211 HRESULT  WINAPI  IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3212     ICOM_THIS(IDirect3DDevice8Impl,iface);
3213     FIXME("(%p) : stub\n", This);    return D3D_OK;
3214 }
3215
3216 HRESULT  WINAPI  IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3217     IDirect3DVertexBuffer8 *oldSrc;
3218     ICOM_THIS(IDirect3DDevice8Impl,iface);
3219
3220     oldSrc = This->StateBlock.stream_source[StreamNumber];
3221     TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3222
3223     This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3224     This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3225     This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3226     This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3227
3228     /* Handle recording of state blocks */
3229     if (This->isRecordingState) {
3230         TRACE("Recording... not performing anything\n");
3231         return D3D_OK;
3232     }
3233
3234     if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3235     if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3236     return D3D_OK;
3237 }
3238 HRESULT  WINAPI  IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3239     ICOM_THIS(IDirect3DDevice8Impl,iface);
3240     TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3241     *pStream = This->StateBlock.stream_source[StreamNumber];
3242     *pStride = This->StateBlock.stream_stride[StreamNumber];
3243     IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3244     return D3D_OK;
3245 }
3246
3247
3248 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3249 {
3250     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3251     IDirect3DDevice8Impl_QueryInterface,
3252     IDirect3DDevice8Impl_AddRef,
3253     IDirect3DDevice8Impl_Release,
3254     IDirect3DDevice8Impl_TestCooperativeLevel,
3255     IDirect3DDevice8Impl_GetAvailableTextureMem,
3256     IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3257     IDirect3DDevice8Impl_GetDirect3D,
3258     IDirect3DDevice8Impl_GetDeviceCaps,
3259     IDirect3DDevice8Impl_GetDisplayMode,
3260     IDirect3DDevice8Impl_GetCreationParameters,
3261     IDirect3DDevice8Impl_SetCursorProperties,
3262     IDirect3DDevice8Impl_SetCursorPosition,
3263     IDirect3DDevice8Impl_ShowCursor,
3264     IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3265     IDirect3DDevice8Impl_Reset,
3266     IDirect3DDevice8Impl_Present,
3267     IDirect3DDevice8Impl_GetBackBuffer,
3268     IDirect3DDevice8Impl_GetRasterStatus,
3269     IDirect3DDevice8Impl_SetGammaRamp,
3270     IDirect3DDevice8Impl_GetGammaRamp,
3271     IDirect3DDevice8Impl_CreateTexture,
3272     IDirect3DDevice8Impl_CreateVolumeTexture,
3273     IDirect3DDevice8Impl_CreateCubeTexture,
3274     IDirect3DDevice8Impl_CreateVertexBuffer,
3275     IDirect3DDevice8Impl_CreateIndexBuffer,
3276     IDirect3DDevice8Impl_CreateRenderTarget,
3277     IDirect3DDevice8Impl_CreateDepthStencilSurface,
3278     IDirect3DDevice8Impl_CreateImageSurface,
3279     IDirect3DDevice8Impl_CopyRects,
3280     IDirect3DDevice8Impl_UpdateTexture,
3281     IDirect3DDevice8Impl_GetFrontBuffer,
3282     IDirect3DDevice8Impl_SetRenderTarget,
3283     IDirect3DDevice8Impl_GetRenderTarget,
3284     IDirect3DDevice8Impl_GetDepthStencilSurface,
3285     IDirect3DDevice8Impl_BeginScene,
3286     IDirect3DDevice8Impl_EndScene,
3287     IDirect3DDevice8Impl_Clear,
3288     IDirect3DDevice8Impl_SetTransform,
3289     IDirect3DDevice8Impl_GetTransform,
3290     IDirect3DDevice8Impl_MultiplyTransform,
3291     IDirect3DDevice8Impl_SetViewport,
3292     IDirect3DDevice8Impl_GetViewport,
3293     IDirect3DDevice8Impl_SetMaterial,
3294     IDirect3DDevice8Impl_GetMaterial,
3295     IDirect3DDevice8Impl_SetLight,
3296     IDirect3DDevice8Impl_GetLight,
3297     IDirect3DDevice8Impl_LightEnable,
3298     IDirect3DDevice8Impl_GetLightEnable,
3299     IDirect3DDevice8Impl_SetClipPlane,
3300     IDirect3DDevice8Impl_GetClipPlane,
3301     IDirect3DDevice8Impl_SetRenderState,
3302     IDirect3DDevice8Impl_GetRenderState,
3303     IDirect3DDevice8Impl_BeginStateBlock,
3304     IDirect3DDevice8Impl_EndStateBlock,
3305     IDirect3DDevice8Impl_ApplyStateBlock,
3306     IDirect3DDevice8Impl_CaptureStateBlock,
3307     IDirect3DDevice8Impl_DeleteStateBlock,
3308     IDirect3DDevice8Impl_CreateStateBlock,
3309     IDirect3DDevice8Impl_SetClipStatus,
3310     IDirect3DDevice8Impl_GetClipStatus,
3311     IDirect3DDevice8Impl_GetTexture,
3312     IDirect3DDevice8Impl_SetTexture,
3313     IDirect3DDevice8Impl_GetTextureStageState,
3314     IDirect3DDevice8Impl_SetTextureStageState,
3315     IDirect3DDevice8Impl_ValidateDevice,
3316     IDirect3DDevice8Impl_GetInfo,
3317     IDirect3DDevice8Impl_SetPaletteEntries,
3318     IDirect3DDevice8Impl_GetPaletteEntries,
3319     IDirect3DDevice8Impl_SetCurrentTexturePalette,
3320     IDirect3DDevice8Impl_GetCurrentTexturePalette,
3321     IDirect3DDevice8Impl_DrawPrimitive,
3322     IDirect3DDevice8Impl_DrawIndexedPrimitive,
3323     IDirect3DDevice8Impl_DrawPrimitiveUP,
3324     IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
3325     IDirect3DDevice8Impl_ProcessVertices,
3326     IDirect3DDevice8Impl_CreateVertexShader,
3327     IDirect3DDevice8Impl_SetVertexShader,
3328     IDirect3DDevice8Impl_GetVertexShader,
3329     IDirect3DDevice8Impl_DeleteVertexShader,
3330     IDirect3DDevice8Impl_SetVertexShaderConstant,
3331     IDirect3DDevice8Impl_GetVertexShaderConstant,
3332     IDirect3DDevice8Impl_GetVertexShaderDeclaration,
3333     IDirect3DDevice8Impl_GetVertexShaderFunction,
3334     IDirect3DDevice8Impl_SetStreamSource,
3335     IDirect3DDevice8Impl_GetStreamSource,
3336     IDirect3DDevice8Impl_SetIndices,
3337     IDirect3DDevice8Impl_GetIndices,
3338     IDirect3DDevice8Impl_CreatePixelShader,
3339     IDirect3DDevice8Impl_SetPixelShader,
3340     IDirect3DDevice8Impl_GetPixelShader,
3341     IDirect3DDevice8Impl_DeletePixelShader,
3342     IDirect3DDevice8Impl_SetPixelShaderConstant,
3343     IDirect3DDevice8Impl_GetPixelShaderConstant,
3344     IDirect3DDevice8Impl_GetPixelShaderFunction,
3345     IDirect3DDevice8Impl_DrawRectPatch,
3346     IDirect3DDevice8Impl_DrawTriPatch,
3347     IDirect3DDevice8Impl_DeletePatch
3348 };
3349
3350 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
3351     D3DLINEPATTERN lp;
3352     int i;
3353
3354     ICOM_THIS(IDirect3DDevice8Impl,iface);
3355
3356     /* Note this may have a large overhead but it should only be executed
3357        once, in order to initialize the complete state of the device and 
3358        all opengl equivalents                                            */
3359     TRACE("-----------------------> Setting up device defaults...\n");
3360     This->StateBlock.blockType = D3DSBT_ALL;
3361
3362     /* FIXME: Set some of the defaults for lights, transforms etc */
3363     memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
3364     memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
3365     memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
3366
3367     /* Render states: */
3368     if (This->PresentParms.EnableAutoDepthStencil) {
3369        IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
3370     } else {
3371        IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
3372     }
3373     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
3374     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3375     lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
3376     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
3377     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
3378     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
3379     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
3380     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
3381     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
3382     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3383     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
3384     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
3385     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
3386     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
3387     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
3388     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
3389     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
3390     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
3391     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3392     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
3393     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
3394     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
3395     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
3396     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
3397     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
3398     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
3399     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
3400     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
3401     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
3402     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
3403     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
3404     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
3405     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
3406     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
3407     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
3408     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
3409     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
3410     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
3411     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
3412     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
3413     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
3414     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
3415     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
3416     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
3417     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
3418     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3419     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
3420     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
3421     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
3422     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3423     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
3424     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
3425     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
3426     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
3427     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
3428     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
3429     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
3430     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
3431     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
3432     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
3433     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
3434     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
3435     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
3436     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
3437     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
3438     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
3439     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
3440     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
3441     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
3442     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
3443     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
3444     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
3445     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
3446     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
3447     IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
3448
3449     /* Texture Stage States - Put directly into state block, we will call function below */
3450     for (i=0; i<8;i++) {
3451         This->StateBlock.texture_state[i][D3DTSS_COLOROP               ] = (i==0)? D3DTOP_MODULATE :  D3DTOP_DISABLE;
3452         This->StateBlock.texture_state[i][D3DTSS_COLORARG1             ] = D3DTA_TEXTURE;
3453         This->StateBlock.texture_state[i][D3DTSS_COLORARG2             ] = D3DTA_CURRENT;
3454         This->StateBlock.texture_state[i][D3DTSS_ALPHAOP               ] = (i==0)? D3DTOP_SELECTARG1 :  D3DTOP_DISABLE;
3455         This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1             ] = D3DTA_TEXTURE;
3456         This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2             ] = D3DTA_CURRENT;
3457         This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00          ] = (DWORD) 0.0;
3458         This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01          ] = (DWORD) 0.0;
3459         This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10          ] = (DWORD) 0.0;
3460         This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11          ] = (DWORD) 0.0;
3461         /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX         ] = ?; */
3462         This->StateBlock.texture_state[i][D3DTSS_ADDRESSU              ] = D3DTADDRESS_WRAP;
3463         This->StateBlock.texture_state[i][D3DTSS_ADDRESSV              ] = D3DTADDRESS_WRAP;
3464         This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR           ] = 0x00;
3465         This->StateBlock.texture_state[i][D3DTSS_MAGFILTER             ] = D3DTEXF_POINT;
3466         This->StateBlock.texture_state[i][D3DTSS_MINFILTER             ] = D3DTEXF_POINT;
3467         This->StateBlock.texture_state[i][D3DTSS_MIPFILTER             ] = D3DTEXF_NONE;
3468         This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS         ] = 0;
3469         This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL           ] = 0;
3470         This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY         ] = 1;
3471         This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE         ] = (DWORD) 0.0;
3472         This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET        ] = (DWORD) 0.0;
3473         This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
3474         This->StateBlock.texture_state[i][D3DTSS_ADDRESSW              ] = D3DTADDRESS_WRAP;
3475         This->StateBlock.texture_state[i][D3DTSS_COLORARG0             ] = D3DTA_CURRENT;
3476         This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0             ] = D3DTA_CURRENT;
3477         This->StateBlock.texture_state[i][D3DTSS_RESULTARG             ] = D3DTA_CURRENT;
3478     }
3479
3480     /* Under DirectX you can have texture stage operations even if no texture is
3481        bound, whereas opengl will only do texture operations when a valid texture is
3482        bound. We emulate this by creating 8 dummy textures and binding them to each
3483        texture stage, but disable all stages by default. Hence if a stage is enabled
3484        then the default texture will kick in until replaced by a SetTexture call     */
3485     for (i=0; i<8; i++) {
3486         GLubyte white = 255;
3487
3488         /* Make appropriate texture active */
3489         glActiveTextureARB(GL_TEXTURE0_ARB + i);
3490         checkGLcall("glActiveTextureARB");
3491
3492         /* Generate an opengl texture name */
3493         glGenTextures(1, &This->dummyTextureName[i]);
3494         checkGLcall("glGenTextures");
3495         TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
3496
3497         /* Generate a dummy 1d texture */
3498         This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
3499         glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
3500         checkGLcall("glBindTexture");
3501
3502         glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white); 
3503         checkGLcall("glTexImage1D");
3504
3505         /* Reapply all the texture state information to this texture */
3506         setupTextureStates(iface, i);
3507     }
3508
3509     TRACE("-----------------------> Device defaults now set up...\n");
3510
3511 }
3512
3513
3514 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
3515     D3DRS_ALPHABLENDENABLE   ,
3516     D3DRS_ALPHAFUNC          ,
3517     D3DRS_ALPHAREF           ,
3518     D3DRS_ALPHATESTENABLE    ,
3519     D3DRS_BLENDOP            ,
3520     D3DRS_COLORWRITEENABLE   ,
3521     D3DRS_DESTBLEND          ,
3522     D3DRS_DITHERENABLE       ,
3523     D3DRS_EDGEANTIALIAS      ,
3524     D3DRS_FILLMODE           ,
3525     D3DRS_FOGDENSITY         ,
3526     D3DRS_FOGEND             ,
3527     D3DRS_FOGSTART           ,
3528     D3DRS_LASTPIXEL          ,
3529     D3DRS_LINEPATTERN        ,
3530     D3DRS_SHADEMODE          ,
3531     D3DRS_SRCBLEND           ,
3532     D3DRS_STENCILENABLE      ,
3533     D3DRS_STENCILFAIL        ,
3534     D3DRS_STENCILFUNC        ,
3535     D3DRS_STENCILMASK        ,
3536     D3DRS_STENCILPASS        ,
3537     D3DRS_STENCILREF         ,
3538     D3DRS_STENCILWRITEMASK   ,
3539     D3DRS_STENCILZFAIL       ,
3540     D3DRS_TEXTUREFACTOR      ,
3541     D3DRS_WRAP0              ,
3542     D3DRS_WRAP1              ,
3543     D3DRS_WRAP2              ,
3544     D3DRS_WRAP3              ,
3545     D3DRS_WRAP4              ,
3546     D3DRS_WRAP5              ,
3547     D3DRS_WRAP6              ,
3548     D3DRS_WRAP7              ,
3549     D3DRS_ZBIAS              ,
3550     D3DRS_ZENABLE            ,
3551     D3DRS_ZFUNC              ,
3552     D3DRS_ZWRITEENABLE
3553 };
3554
3555 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
3556     D3DTSS_ADDRESSU              ,
3557     D3DTSS_ADDRESSV              ,
3558     D3DTSS_ADDRESSW              ,
3559     D3DTSS_ALPHAARG0             ,
3560     D3DTSS_ALPHAARG1             ,
3561     D3DTSS_ALPHAARG2             ,
3562     D3DTSS_ALPHAOP               ,
3563     D3DTSS_BORDERCOLOR           ,
3564     D3DTSS_BUMPENVLOFFSET        ,
3565     D3DTSS_BUMPENVLSCALE         ,
3566     D3DTSS_BUMPENVMAT00          ,
3567     D3DTSS_BUMPENVMAT01          ,
3568     D3DTSS_BUMPENVMAT10          ,
3569     D3DTSS_BUMPENVMAT11          ,
3570     D3DTSS_COLORARG0             ,
3571     D3DTSS_COLORARG1             ,
3572     D3DTSS_COLORARG2             ,
3573     D3DTSS_COLOROP               ,
3574     D3DTSS_MAGFILTER             ,
3575     D3DTSS_MAXANISOTROPY         ,
3576     D3DTSS_MAXMIPLEVEL           ,
3577     D3DTSS_MINFILTER             ,
3578     D3DTSS_MIPFILTER             ,
3579     D3DTSS_MIPMAPLODBIAS         ,
3580     D3DTSS_RESULTARG             ,
3581     D3DTSS_TEXCOORDINDEX         ,
3582     D3DTSS_TEXTURETRANSFORMFLAGS
3583 };
3584
3585 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
3586     D3DRS_AMBIENT                       ,
3587     D3DRS_AMBIENTMATERIALSOURCE         ,
3588     D3DRS_CLIPPING                      ,
3589     D3DRS_CLIPPLANEENABLE               ,
3590     D3DRS_COLORVERTEX                   ,
3591     D3DRS_DIFFUSEMATERIALSOURCE         ,
3592     D3DRS_EMISSIVEMATERIALSOURCE        ,
3593     D3DRS_FOGDENSITY                    ,
3594     D3DRS_FOGEND                        ,
3595     D3DRS_FOGSTART                      ,
3596     D3DRS_FOGTABLEMODE                  ,
3597     D3DRS_FOGVERTEXMODE                 ,
3598     D3DRS_INDEXEDVERTEXBLENDENABLE      ,
3599     D3DRS_LIGHTING                      ,
3600     D3DRS_LOCALVIEWER                   ,
3601     D3DRS_MULTISAMPLEANTIALIAS          ,
3602     D3DRS_MULTISAMPLEMASK               ,
3603     D3DRS_NORMALIZENORMALS              ,
3604     D3DRS_PATCHEDGESTYLE                ,
3605     D3DRS_PATCHSEGMENTS                 ,
3606     D3DRS_POINTSCALE_A                  ,
3607     D3DRS_POINTSCALE_B                  ,
3608     D3DRS_POINTSCALE_C                  ,
3609     D3DRS_POINTSCALEENABLE              ,
3610     D3DRS_POINTSIZE                     ,
3611     D3DRS_POINTSIZE_MAX                 ,
3612     D3DRS_POINTSIZE_MIN                 ,
3613     D3DRS_POINTSPRITEENABLE             ,
3614     D3DRS_RANGEFOGENABLE                ,
3615     D3DRS_SOFTWAREVERTEXPROCESSING      ,
3616     D3DRS_SPECULARMATERIALSOURCE        ,
3617     D3DRS_TWEENFACTOR                   ,
3618     D3DRS_VERTEXBLEND
3619 };
3620
3621 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
3622     D3DTSS_TEXCOORDINDEX         ,
3623     D3DTSS_TEXTURETRANSFORMFLAGS
3624 };