Added a couple of tests for SetActiveWindow.
[wine] / dlls / d3d8 / utils.c
1 /*
2  * D3D8 utils
3  *
4  * Copyright 2002-2003 Jason Edmeades
5  *                     Raphael Junqueira
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <math.h>
25 #include <stdarg.h>
26
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "wingdi.h"
33 #include "wine/debug.h"
34
35 #include "d3d8_private.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
38
39 const char* debug_d3ddevicetype(D3DDEVTYPE devtype) {
40   switch (devtype) {
41 #define DEVTYPE_TO_STR(dev) case dev: return #dev
42     DEVTYPE_TO_STR(D3DDEVTYPE_HAL);
43     DEVTYPE_TO_STR(D3DDEVTYPE_REF);
44     DEVTYPE_TO_STR(D3DDEVTYPE_SW);    
45 #undef DEVTYPE_TO_STR
46   default:
47     FIXME("Unrecognized %u D3DDEVTYPE!\n", devtype);
48     return "unrecognized";
49   }
50 }
51
52 const char* debug_d3dusage(DWORD usage) {
53   switch (usage) {
54 #define D3DUSAGE_TO_STR(u) case u: return #u
55     D3DUSAGE_TO_STR(D3DUSAGE_RENDERTARGET);
56     D3DUSAGE_TO_STR(D3DUSAGE_DEPTHSTENCIL);
57     D3DUSAGE_TO_STR(D3DUSAGE_WRITEONLY);
58     D3DUSAGE_TO_STR(D3DUSAGE_SOFTWAREPROCESSING);
59     D3DUSAGE_TO_STR(D3DUSAGE_DONOTCLIP);
60     D3DUSAGE_TO_STR(D3DUSAGE_POINTS);
61     D3DUSAGE_TO_STR(D3DUSAGE_RTPATCHES);
62     D3DUSAGE_TO_STR(D3DUSAGE_NPATCHES);
63     D3DUSAGE_TO_STR(D3DUSAGE_DYNAMIC);
64 #undef D3DUSAGE_TO_STR
65   case 0: return "none";
66   default:
67     FIXME("Unrecognized %lu Usage!\n", usage);
68     return "unrecognized";
69   }
70 }
71
72 const char* debug_d3dformat(D3DFORMAT fmt) {
73   switch (fmt) {
74 #define FMT_TO_STR(fmt) case fmt: return #fmt
75     FMT_TO_STR(D3DFMT_UNKNOWN);
76     FMT_TO_STR(D3DFMT_R8G8B8);
77     FMT_TO_STR(D3DFMT_A8R8G8B8);
78     FMT_TO_STR(D3DFMT_X8R8G8B8);
79     FMT_TO_STR(D3DFMT_R5G6B5);
80     FMT_TO_STR(D3DFMT_X1R5G5B5);
81     FMT_TO_STR(D3DFMT_A1R5G5B5);
82     FMT_TO_STR(D3DFMT_A4R4G4B4);
83     FMT_TO_STR(D3DFMT_R3G3B2);
84     FMT_TO_STR(D3DFMT_A8);
85     FMT_TO_STR(D3DFMT_A8R3G3B2);
86     FMT_TO_STR(D3DFMT_X4R4G4B4);
87     FMT_TO_STR(D3DFMT_A8P8);
88     FMT_TO_STR(D3DFMT_P8);
89     FMT_TO_STR(D3DFMT_L8);
90     FMT_TO_STR(D3DFMT_A8L8);
91     FMT_TO_STR(D3DFMT_A4L4);
92     FMT_TO_STR(D3DFMT_V8U8);
93     FMT_TO_STR(D3DFMT_L6V5U5);
94     FMT_TO_STR(D3DFMT_X8L8V8U8);
95     FMT_TO_STR(D3DFMT_Q8W8V8U8);
96     FMT_TO_STR(D3DFMT_V16U16);
97     FMT_TO_STR(D3DFMT_W11V11U10);
98     FMT_TO_STR(D3DFMT_UYVY);
99     FMT_TO_STR(D3DFMT_YUY2);
100     FMT_TO_STR(D3DFMT_DXT1);
101     FMT_TO_STR(D3DFMT_DXT2);
102     FMT_TO_STR(D3DFMT_DXT3);
103     FMT_TO_STR(D3DFMT_DXT4);
104     FMT_TO_STR(D3DFMT_DXT5);
105     FMT_TO_STR(D3DFMT_D16_LOCKABLE);
106     FMT_TO_STR(D3DFMT_D32);
107     FMT_TO_STR(D3DFMT_D15S1);
108     FMT_TO_STR(D3DFMT_D24S8);
109     FMT_TO_STR(D3DFMT_D16);
110     FMT_TO_STR(D3DFMT_D24X8);
111     FMT_TO_STR(D3DFMT_D24X4S4);
112     FMT_TO_STR(D3DFMT_VERTEXDATA);
113     FMT_TO_STR(D3DFMT_INDEX16);
114     FMT_TO_STR(D3DFMT_INDEX32);
115 #undef FMT_TO_STR
116   default:
117     FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
118     return "unrecognized";
119   }
120 }
121
122 const char* debug_d3dressourcetype(D3DRESOURCETYPE res) {
123   switch (res) {
124 #define RES_TO_STR(res) case res: return #res;
125     RES_TO_STR(D3DRTYPE_SURFACE);
126     RES_TO_STR(D3DRTYPE_VOLUME);
127     RES_TO_STR(D3DRTYPE_TEXTURE);
128     RES_TO_STR(D3DRTYPE_VOLUMETEXTURE);
129     RES_TO_STR(D3DRTYPE_CUBETEXTURE);
130     RES_TO_STR(D3DRTYPE_VERTEXBUFFER);
131     RES_TO_STR(D3DRTYPE_INDEXBUFFER);
132 #undef  RES_TO_STR
133   default:
134     FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res);
135     return "unrecognized";
136   }
137 }
138
139 const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) {
140   switch (PrimitiveType) {
141 #define PRIM_TO_STR(prim) case prim: return #prim;
142     PRIM_TO_STR(D3DPT_POINTLIST);
143     PRIM_TO_STR(D3DPT_LINELIST);
144     PRIM_TO_STR(D3DPT_LINESTRIP);
145     PRIM_TO_STR(D3DPT_TRIANGLELIST);
146     PRIM_TO_STR(D3DPT_TRIANGLESTRIP);
147     PRIM_TO_STR(D3DPT_TRIANGLEFAN);
148 #undef  PRIM_TO_STR
149   default:
150     FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
151     return "unrecognized";
152   }
153 }
154
155 const char* debug_d3dpool(D3DPOOL Pool) {
156   switch (Pool) {
157 #define POOL_TO_STR(p) case p: return #p;
158     POOL_TO_STR(D3DPOOL_DEFAULT);
159     POOL_TO_STR(D3DPOOL_MANAGED);
160     POOL_TO_STR(D3DPOOL_SYSTEMMEM);
161     POOL_TO_STR(D3DPOOL_SCRATCH);
162 #undef  POOL_TO_STR
163   default:
164     FIXME("Unrecognized %u D3DPOOL!\n", Pool);
165     return "unrecognized";
166   }
167 }
168
169 const char* debug_d3drenderstate(DWORD state) {
170   switch (state) {
171 #define D3DSTATE_TO_STR(u) case u: return #u
172     D3DSTATE_TO_STR(D3DRS_ZENABLE                   );
173     D3DSTATE_TO_STR(D3DRS_FILLMODE                  );
174     D3DSTATE_TO_STR(D3DRS_SHADEMODE                 );
175     D3DSTATE_TO_STR(D3DRS_LINEPATTERN               );
176     D3DSTATE_TO_STR(D3DRS_ZWRITEENABLE              );
177     D3DSTATE_TO_STR(D3DRS_ALPHATESTENABLE           );
178     D3DSTATE_TO_STR(D3DRS_LASTPIXEL                 );
179     D3DSTATE_TO_STR(D3DRS_SRCBLEND                  );
180     D3DSTATE_TO_STR(D3DRS_DESTBLEND                 );
181     D3DSTATE_TO_STR(D3DRS_CULLMODE                  );
182     D3DSTATE_TO_STR(D3DRS_ZFUNC                     );
183     D3DSTATE_TO_STR(D3DRS_ALPHAREF                  );
184     D3DSTATE_TO_STR(D3DRS_ALPHAFUNC                 );
185     D3DSTATE_TO_STR(D3DRS_DITHERENABLE              );
186     D3DSTATE_TO_STR(D3DRS_ALPHABLENDENABLE          );
187     D3DSTATE_TO_STR(D3DRS_FOGENABLE                 );
188     D3DSTATE_TO_STR(D3DRS_SPECULARENABLE            );
189     D3DSTATE_TO_STR(D3DRS_ZVISIBLE                  );
190     D3DSTATE_TO_STR(D3DRS_FOGCOLOR                  );
191     D3DSTATE_TO_STR(D3DRS_FOGTABLEMODE              );
192     D3DSTATE_TO_STR(D3DRS_FOGSTART                  );
193     D3DSTATE_TO_STR(D3DRS_FOGEND                    );
194     D3DSTATE_TO_STR(D3DRS_FOGDENSITY                );
195     D3DSTATE_TO_STR(D3DRS_EDGEANTIALIAS             );
196     D3DSTATE_TO_STR(D3DRS_ZBIAS                     );
197     D3DSTATE_TO_STR(D3DRS_RANGEFOGENABLE            );
198     D3DSTATE_TO_STR(D3DRS_STENCILENABLE             );
199     D3DSTATE_TO_STR(D3DRS_STENCILFAIL               );
200     D3DSTATE_TO_STR(D3DRS_STENCILZFAIL              );
201     D3DSTATE_TO_STR(D3DRS_STENCILPASS               );
202     D3DSTATE_TO_STR(D3DRS_STENCILFUNC               );
203     D3DSTATE_TO_STR(D3DRS_STENCILREF                );
204     D3DSTATE_TO_STR(D3DRS_STENCILMASK               );
205     D3DSTATE_TO_STR(D3DRS_STENCILWRITEMASK          );
206     D3DSTATE_TO_STR(D3DRS_TEXTUREFACTOR             );
207     D3DSTATE_TO_STR(D3DRS_WRAP0                     );
208     D3DSTATE_TO_STR(D3DRS_WRAP1                     );
209     D3DSTATE_TO_STR(D3DRS_WRAP2                     );
210     D3DSTATE_TO_STR(D3DRS_WRAP3                     );
211     D3DSTATE_TO_STR(D3DRS_WRAP4                     );
212     D3DSTATE_TO_STR(D3DRS_WRAP5                     );
213     D3DSTATE_TO_STR(D3DRS_WRAP6                     );
214     D3DSTATE_TO_STR(D3DRS_WRAP7                     );
215     D3DSTATE_TO_STR(D3DRS_CLIPPING                  );
216     D3DSTATE_TO_STR(D3DRS_LIGHTING                  );
217     D3DSTATE_TO_STR(D3DRS_AMBIENT                   );
218     D3DSTATE_TO_STR(D3DRS_FOGVERTEXMODE             );
219     D3DSTATE_TO_STR(D3DRS_COLORVERTEX               );
220     D3DSTATE_TO_STR(D3DRS_LOCALVIEWER               );
221     D3DSTATE_TO_STR(D3DRS_NORMALIZENORMALS          );
222     D3DSTATE_TO_STR(D3DRS_DIFFUSEMATERIALSOURCE     );
223     D3DSTATE_TO_STR(D3DRS_SPECULARMATERIALSOURCE    );
224     D3DSTATE_TO_STR(D3DRS_AMBIENTMATERIALSOURCE     );
225     D3DSTATE_TO_STR(D3DRS_EMISSIVEMATERIALSOURCE    );
226     D3DSTATE_TO_STR(D3DRS_VERTEXBLEND               );
227     D3DSTATE_TO_STR(D3DRS_CLIPPLANEENABLE           );
228     D3DSTATE_TO_STR(D3DRS_SOFTWAREVERTEXPROCESSING  );
229     D3DSTATE_TO_STR(D3DRS_POINTSIZE                 );
230     D3DSTATE_TO_STR(D3DRS_POINTSIZE_MIN             );
231     D3DSTATE_TO_STR(D3DRS_POINTSPRITEENABLE         );
232     D3DSTATE_TO_STR(D3DRS_POINTSCALEENABLE          );
233     D3DSTATE_TO_STR(D3DRS_POINTSCALE_A              );
234     D3DSTATE_TO_STR(D3DRS_POINTSCALE_B              );
235     D3DSTATE_TO_STR(D3DRS_POINTSCALE_C              );
236     D3DSTATE_TO_STR(D3DRS_MULTISAMPLEANTIALIAS      );
237     D3DSTATE_TO_STR(D3DRS_MULTISAMPLEMASK           );
238     D3DSTATE_TO_STR(D3DRS_PATCHEDGESTYLE            );
239     D3DSTATE_TO_STR(D3DRS_PATCHSEGMENTS             );
240     D3DSTATE_TO_STR(D3DRS_DEBUGMONITORTOKEN         );
241     D3DSTATE_TO_STR(D3DRS_POINTSIZE_MAX             );
242     D3DSTATE_TO_STR(D3DRS_INDEXEDVERTEXBLENDENABLE  );
243     D3DSTATE_TO_STR(D3DRS_COLORWRITEENABLE          );
244     D3DSTATE_TO_STR(D3DRS_TWEENFACTOR               );
245     D3DSTATE_TO_STR(D3DRS_BLENDOP                   );
246     D3DSTATE_TO_STR(D3DRS_POSITIONORDER             );
247     D3DSTATE_TO_STR(D3DRS_NORMALORDER               );
248 #undef D3DSTATE_TO_STR
249   default:
250     FIXME("Unrecognized %lu render state!\n", state);
251     return "unrecognized";
252   }
253 }
254
255 const char* debug_d3dtexturestate(DWORD state) {
256   switch (state) {
257 #define D3DSTATE_TO_STR(u) case u: return #u
258     D3DSTATE_TO_STR(D3DTSS_COLOROP               );
259     D3DSTATE_TO_STR(D3DTSS_COLORARG1             );
260     D3DSTATE_TO_STR(D3DTSS_COLORARG2             );
261     D3DSTATE_TO_STR(D3DTSS_ALPHAOP               );
262     D3DSTATE_TO_STR(D3DTSS_ALPHAARG1             );
263     D3DSTATE_TO_STR(D3DTSS_ALPHAARG2             );
264     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT00          );
265     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT01          );
266     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT10          );
267     D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT11          );
268     D3DSTATE_TO_STR(D3DTSS_TEXCOORDINDEX         );
269     D3DSTATE_TO_STR(D3DTSS_ADDRESSU              );
270     D3DSTATE_TO_STR(D3DTSS_ADDRESSV              );
271     D3DSTATE_TO_STR(D3DTSS_BORDERCOLOR           );
272     D3DSTATE_TO_STR(D3DTSS_MAGFILTER             );
273     D3DSTATE_TO_STR(D3DTSS_MINFILTER             );
274     D3DSTATE_TO_STR(D3DTSS_MIPFILTER             );
275     D3DSTATE_TO_STR(D3DTSS_MIPMAPLODBIAS         );
276     D3DSTATE_TO_STR(D3DTSS_MAXMIPLEVEL           );
277     D3DSTATE_TO_STR(D3DTSS_MAXANISOTROPY         );
278     D3DSTATE_TO_STR(D3DTSS_BUMPENVLSCALE         );
279     D3DSTATE_TO_STR(D3DTSS_BUMPENVLOFFSET        );
280     D3DSTATE_TO_STR(D3DTSS_TEXTURETRANSFORMFLAGS );
281     D3DSTATE_TO_STR(D3DTSS_ADDRESSW              );
282     D3DSTATE_TO_STR(D3DTSS_COLORARG0             );
283     D3DSTATE_TO_STR(D3DTSS_ALPHAARG0             );
284     D3DSTATE_TO_STR(D3DTSS_RESULTARG             );
285 #undef D3DSTATE_TO_STR
286   case 12:
287     /* Note D3DTSS are not consecutive, so skip these */
288     return "unused";
289     break;
290   default:
291     FIXME("Unrecognized %lu texture state!\n", state);
292     return "unrecognized";
293   }
294 }
295
296 /*
297  * Simple utility routines used for dx -> gl mapping of byte formats
298  */
299 int D3DPrimitiveListGetVertexSize(D3DPRIMITIVETYPE PrimitiveType, int iNumPrim) {
300   switch (PrimitiveType) {
301   case D3DPT_POINTLIST:     return iNumPrim;
302   case D3DPT_LINELIST:      return iNumPrim * 2;
303   case D3DPT_LINESTRIP:     return iNumPrim + 1;
304   case D3DPT_TRIANGLELIST:  return iNumPrim * 3;
305   case D3DPT_TRIANGLESTRIP: return iNumPrim + 2;
306   case D3DPT_TRIANGLEFAN:   return iNumPrim + 2;
307   default:
308     FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
309     return 0;
310   }
311 }
312
313 int D3DPrimitive2GLenum(D3DPRIMITIVETYPE PrimitiveType) {
314   switch (PrimitiveType) {
315   case D3DPT_POINTLIST:     return GL_POINTS;
316   case D3DPT_LINELIST:      return GL_LINES;
317   case D3DPT_LINESTRIP:     return GL_LINE_STRIP;
318   case D3DPT_TRIANGLELIST:  return GL_TRIANGLES;
319   case D3DPT_TRIANGLESTRIP: return GL_TRIANGLE_STRIP;
320   case D3DPT_TRIANGLEFAN:   return GL_TRIANGLE_FAN;
321   default:
322     FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
323     return GL_POLYGON;
324   }
325 }
326
327 int D3DFVFGetSize(D3DFORMAT fvf) {
328   int ret = 0;
329   if      (fvf & D3DFVF_XYZ)    ret += 3 * sizeof(float);
330   else if (fvf & D3DFVF_XYZRHW) ret += 4 * sizeof(float);
331   if (fvf & D3DFVF_NORMAL)      ret += 3 * sizeof(float);
332   if (fvf & D3DFVF_PSIZE)       ret += sizeof(float);
333   if (fvf & D3DFVF_DIFFUSE)     ret += sizeof(DWORD);
334   if (fvf & D3DFVF_SPECULAR)    ret += sizeof(DWORD);
335   /*if (fvf & D3DFVF_TEX1)        ret += 1;*/
336   return ret;
337 }
338
339 GLenum D3DFmt2GLDepthFmt(D3DFORMAT fmt) {
340   switch (fmt) {
341   /* depth/stencil buffer */
342   case D3DFMT_D16_LOCKABLE:
343   case D3DFMT_D16:
344   case D3DFMT_D15S1:
345   case D3DFMT_D24X4S4:
346   case D3DFMT_D24S8:
347   case D3DFMT_D24X8:
348   case D3DFMT_D32:
349     return GL_DEPTH_COMPONENT;
350   default:
351     FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
352   }
353   return 0;
354 }
355
356 GLenum D3DFmt2GLDepthType(D3DFORMAT fmt) {
357   switch (fmt) {
358   /* depth/stencil buffer */
359   case D3DFMT_D15S1:
360   case D3DFMT_D16_LOCKABLE:     
361   case D3DFMT_D16:              
362     return GL_UNSIGNED_SHORT;
363   case D3DFMT_D24X4S4:          
364   case D3DFMT_D24S8:            
365   case D3DFMT_D24X8:            
366   case D3DFMT_D32:              
367     return GL_UNSIGNED_INT;
368   default:
369     FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
370   }
371   return 0;
372 }
373
374 SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
375     SHORT retVal;
376
377     switch (fmt) {
378     /* color buffer */
379     case D3DFMT_P8:               retVal = 1; break;
380     case D3DFMT_R3G3B2:           retVal = 1; break;
381     case D3DFMT_V8U8:             retVal = 2; break;
382     case D3DFMT_R5G6B5:           retVal = 2; break;
383     case D3DFMT_X1R5G5B5:         retVal = 2; break;
384     case D3DFMT_A4R4G4B4:         retVal = 2; break;
385     case D3DFMT_X4R4G4B4:         retVal = 2; break;
386     case D3DFMT_A1R5G5B5:         retVal = 2; break;
387     case D3DFMT_R8G8B8:           retVal = 3; break;
388     case D3DFMT_X8R8G8B8:         retVal = 4; break;
389     case D3DFMT_A8R8G8B8:         retVal = 4; break;
390     /* depth/stencil buffer */
391     case D3DFMT_D16_LOCKABLE:     retVal = 2; break;
392     case D3DFMT_D16:              retVal = 2; break;
393     case D3DFMT_D15S1:            retVal = 2; break;
394     case D3DFMT_D24X4S4:          retVal = 4; break;
395     case D3DFMT_D24S8:            retVal = 4; break;
396     case D3DFMT_D24X8:            retVal = 4; break;
397     case D3DFMT_D32:              retVal = 4; break;
398     /* Compressed */                              
399     case D3DFMT_DXT1:             retVal = 1; break; /* Actually  8 bytes per 16 pixels - Special cased later */
400     case D3DFMT_DXT3:             retVal = 1; break; /* Actually 16 bytes per 16 pixels */
401     case D3DFMT_DXT5:             retVal = 1; break; /* Actually 16 bytes per 16 pixels */
402
403     /* unknown */                                 
404     case D3DFMT_UNKNOWN:
405       /* Guess at the highest value of the above */
406       TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %u\n", fmt);
407       retVal = 4;
408       break;
409
410     default:
411       FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
412       retVal = 4;
413     }
414     TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
415     return retVal;
416 }
417
418 GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
419     GLint retVal = 0;
420
421     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
422       switch (fmt) {
423       case D3DFMT_DXT1:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
424       case D3DFMT_DXT3:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
425       case D3DFMT_DXT5:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
426       default:
427         /* stupid compiler */
428         break;
429       }
430     }
431
432     if (retVal == 0) {
433         switch (fmt) {
434         case D3DFMT_P8:               retVal = GL_COLOR_INDEX8_EXT; break;
435         case D3DFMT_A8P8:             retVal = GL_COLOR_INDEX8_EXT; break;
436         case D3DFMT_V8U8:             retVal = GL_COLOR_INDEX8_EXT; break;
437
438         case D3DFMT_A4R4G4B4:         retVal = GL_RGBA4; break;
439         case D3DFMT_A8R8G8B8:         retVal = GL_RGBA8; break;
440         case D3DFMT_X8R8G8B8:         retVal = GL_RGB8; break;
441         case D3DFMT_R8G8B8:           retVal = GL_RGB8; break;
442         case D3DFMT_R5G6B5:           retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
443         case D3DFMT_A1R5G5B5:         retVal = GL_RGB5_A1; break;
444         default:
445             FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
446             retVal = GL_RGB8;
447         }
448     }
449     TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
450     return retVal;
451 }
452
453 GLenum D3DFmt2GLFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
454     GLenum retVal = 0;
455
456     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
457       switch (fmt) {
458       case D3DFMT_DXT1:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
459       case D3DFMT_DXT3:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
460       case D3DFMT_DXT5:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
461       default:
462         /* stupid compiler */
463         break;
464       }
465     }
466
467     if (retVal == 0) {
468         switch (fmt) {
469         case D3DFMT_P8:               retVal = GL_COLOR_INDEX; break;
470         case D3DFMT_A8P8:             retVal = GL_COLOR_INDEX; break;
471         case D3DFMT_V8U8:             retVal = GL_COLOR_INDEX; break;
472
473         case D3DFMT_A4R4G4B4:         retVal = GL_BGRA; break;
474         case D3DFMT_A8R8G8B8:         retVal = GL_BGRA; break;
475         case D3DFMT_X8R8G8B8:         retVal = GL_BGRA; break;
476         case D3DFMT_R8G8B8:           retVal = GL_BGR; break;
477         case D3DFMT_R5G6B5:           retVal = GL_RGB; break;
478         case D3DFMT_A1R5G5B5:         retVal = GL_BGRA; break;
479         default:
480             FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
481             retVal = GL_BGR;
482         }
483     }
484
485     TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
486     return retVal;
487 }
488
489 GLenum D3DFmt2GLType(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
490     GLenum retVal = 0;
491
492     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
493       switch (fmt) {
494       case D3DFMT_DXT1:             retVal = 0; break;
495       case D3DFMT_DXT3:             retVal = 0; break;
496       case D3DFMT_DXT5:             retVal = 0; break;
497       default:
498         /* stupid compiler */
499         break;
500       }
501     }
502
503     if (retVal == 0) {
504         switch (fmt) {
505         case D3DFMT_P8:               retVal = GL_UNSIGNED_BYTE; break;
506         case D3DFMT_A8P8:             retVal = GL_UNSIGNED_BYTE; break;        
507         case D3DFMT_V8U8:             retVal = GL_UNSIGNED_BYTE; break;
508
509         case D3DFMT_A4R4G4B4:         retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
510         case D3DFMT_A8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
511         case D3DFMT_X8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
512         case D3DFMT_R5G6B5:           retVal = GL_UNSIGNED_SHORT_5_6_5; break;
513         case D3DFMT_R8G8B8:           retVal = GL_UNSIGNED_BYTE; break;
514         case D3DFMT_A1R5G5B5:         retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
515         default:
516             FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
517             retVal = GL_UNSIGNED_BYTE;
518         }
519     }
520
521     TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
522     return retVal;
523 }
524
525 int SOURCEx_RGB_EXT(DWORD arg) {
526     switch(arg) {
527     case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
528     case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
529     case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
530     case D3DTSS_ALPHAARG0:
531     case D3DTSS_ALPHAARG1:
532     case D3DTSS_ALPHAARG2:
533     default:
534         FIXME("Invalid arg %ld\n", arg);
535         return GL_SOURCE0_RGB_EXT;
536     }
537 }
538
539 int OPERANDx_RGB_EXT(DWORD arg) {
540     switch(arg) {
541     case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
542     case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
543     case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
544     case D3DTSS_ALPHAARG0:
545     case D3DTSS_ALPHAARG1:
546     case D3DTSS_ALPHAARG2:
547     default:
548         FIXME("Invalid arg %ld\n", arg);
549         return GL_OPERAND0_RGB_EXT;
550     }
551 }
552
553 int SOURCEx_ALPHA_EXT(DWORD arg) {
554     switch(arg) {
555     case D3DTSS_ALPHAARG0:  return GL_SOURCE2_ALPHA_EXT;
556     case D3DTSS_ALPHAARG1:  return GL_SOURCE0_ALPHA_EXT;
557     case D3DTSS_ALPHAARG2:  return GL_SOURCE1_ALPHA_EXT;
558     case D3DTSS_COLORARG0:
559     case D3DTSS_COLORARG1:
560     case D3DTSS_COLORARG2:
561     default:
562         FIXME("Invalid arg %ld\n", arg);
563         return GL_SOURCE0_ALPHA_EXT;
564     }
565 }
566
567 int OPERANDx_ALPHA_EXT(DWORD arg) {
568     switch(arg) {
569     case D3DTSS_ALPHAARG0:  return GL_OPERAND2_ALPHA_EXT;
570     case D3DTSS_ALPHAARG1:  return GL_OPERAND0_ALPHA_EXT;
571     case D3DTSS_ALPHAARG2:  return GL_OPERAND1_ALPHA_EXT;
572     case D3DTSS_COLORARG0:
573     case D3DTSS_COLORARG1:
574     case D3DTSS_COLORARG2:
575     default:
576         FIXME("Invalid arg %ld\n", arg);
577         return GL_OPERAND0_ALPHA_EXT;
578     }
579 }
580
581 GLenum StencilOp(DWORD op) {
582     switch(op) {                
583     case D3DSTENCILOP_KEEP    : return GL_KEEP;
584     case D3DSTENCILOP_ZERO    : return GL_ZERO;
585     case D3DSTENCILOP_REPLACE : return GL_REPLACE;
586     case D3DSTENCILOP_INCRSAT : return GL_INCR;
587     case D3DSTENCILOP_DECRSAT : return GL_DECR;
588     case D3DSTENCILOP_INVERT  : return GL_INVERT; 
589     case D3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
590     case D3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
591     default:
592         FIXME("Invalid stencil op %ld\n", op);
593         return GL_ALWAYS;
594     }
595 }
596
597 /**
598  * @nodoc: todo
599  */
600 void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand) 
601 {
602   BOOL isAlphaReplicate = FALSE;
603   BOOL isComplement     = FALSE;
604   
605   *operand = GL_SRC_COLOR;
606   *source = GL_TEXTURE;
607   
608   /* Catch alpha replicate */
609   if (iValue & D3DTA_ALPHAREPLICATE) {
610     iValue = iValue & ~D3DTA_ALPHAREPLICATE;
611     isAlphaReplicate = TRUE;
612   }
613   
614   /* Catch Complement */
615   if (iValue & D3DTA_COMPLEMENT) {
616     iValue = iValue & ~D3DTA_COMPLEMENT;
617     isComplement = TRUE;
618   }
619   
620   /* Calculate the operand */
621   if (isAlphaReplicate && !isComplement) {
622     *operand = GL_SRC_ALPHA;
623   } else if (isAlphaReplicate && isComplement) {
624     *operand = GL_ONE_MINUS_SRC_ALPHA;
625   } else if (isComplement) {
626     if (isAlphaArg) {
627       *operand = GL_ONE_MINUS_SRC_ALPHA;
628     } else {
629       *operand = GL_ONE_MINUS_SRC_COLOR;
630     }
631   } else {
632     if (isAlphaArg) {
633       *operand = GL_SRC_ALPHA;
634     } else {
635       *operand = GL_SRC_COLOR;
636     }
637   }
638   
639   /* Calculate the source */
640   switch (iValue & D3DTA_SELECTMASK) {
641   case D3DTA_CURRENT:   *source  = GL_PREVIOUS_EXT;
642     break;
643   case D3DTA_DIFFUSE:   *source  = GL_PRIMARY_COLOR_EXT;
644     break;
645   case D3DTA_TEXTURE:   *source  = GL_TEXTURE;
646     break;
647   case D3DTA_TFACTOR:   *source  = GL_CONSTANT_EXT;
648     break;
649   case D3DTA_SPECULAR:
650     /*
651      * According to the GL_ARB_texture_env_combine specs, SPECULAR is
652      * 'Secondary color' and isn't supported until base GL supports it
653      * There is no concept of temp registers as far as I can tell
654      */
655     FIXME("Unhandled texture arg D3DTA_SPECULAR\n");
656     *source = GL_TEXTURE;
657     break;
658
659   default:
660     FIXME("Unrecognized texture arg %ld\n", iValue);
661     *source = GL_TEXTURE;
662   }
663 }
664
665
666 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
667 #if defined (GL_VERSION_1_3)
668 # define useext(A) A
669 # define combine_ext 1
670 #elif defined (GL_EXT_texture_env_combine)
671 # define useext(A) A##_EXT
672 # define combine_ext 1
673 #elif defined (GL_ARB_texture_env_combine)
674 # define useext(A) A##_ARB
675 # define combine_ext 1
676 #else
677 # undef combine_ext
678 #endif
679
680 #if !defined(combine_ext)
681 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
682
683         FIXME("Requires opengl combine extensions to work\n");
684         return;
685 }
686 #else
687 /* Setup the texture operations texture stage states */
688 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
689 {
690         GLenum src1, src2, src3;
691         GLenum opr1, opr2, opr3;
692         GLenum comb_target;
693         GLenum src0_target, src1_target, src2_target;
694         GLenum opr0_target, opr1_target, opr2_target;
695         GLenum scal_target;
696         GLenum opr=0, invopr, src3_target, opr3_target;
697         BOOL Handled = FALSE;
698         ICOM_THIS(IDirect3DDevice8Impl,iface);
699
700         TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
701
702         ENTER_GL();
703
704         /* Note: Operations usually involve two ars, src0 and src1 and are operations of
705            the form (a1 <operation> a2). However, some of the more complex operations
706            take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added  
707            in a third parameter called a0. Therefore these are operations of the form
708            a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
709            
710            However, below we treat the new (a0) parameter as src2/opr2, so in the actual
711            functions below, expect their syntax to differ slightly to those listed in the
712            manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
713            This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP                               */
714            
715         if (isAlpha) {
716                 comb_target = useext(GL_COMBINE_ALPHA);
717                 src0_target = useext(GL_SOURCE0_ALPHA);
718                 src1_target = useext(GL_SOURCE1_ALPHA);
719                 src2_target = useext(GL_SOURCE2_ALPHA);
720                 opr0_target = useext(GL_OPERAND0_ALPHA);
721                 opr1_target = useext(GL_OPERAND1_ALPHA);
722                 opr2_target = useext(GL_OPERAND2_ALPHA);
723                 scal_target = GL_ALPHA_SCALE;
724         }
725         else {
726                 comb_target = useext(GL_COMBINE_RGB);
727                 src0_target = useext(GL_SOURCE0_RGB);
728                 src1_target = useext(GL_SOURCE1_RGB);
729                 src2_target = useext(GL_SOURCE2_RGB);
730                 opr0_target = useext(GL_OPERAND0_RGB);
731                 opr1_target = useext(GL_OPERAND1_RGB);
732                 opr2_target = useext(GL_OPERAND2_RGB);
733                 scal_target = useext(GL_RGB_SCALE);
734         }
735
736         /* From MSDN (D3DTSS_ALPHAARG1) : 
737            The default argument is D3DTA_TEXTURE. If no texture is set for this stage, 
738                    then the default argument is D3DTA_DIFFUSE.
739                    FIXME? If texture added/removed, may need to reset back as well?    */
740         if (isAlpha && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
741             GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);  
742         } else {
743             GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
744         }
745         GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2);
746         GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3);
747         
748         TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
749
750         Handled = TRUE; /* Assume will be handled */
751         switch (op) {
752         case D3DTOP_DISABLE: /* Only for alpha */
753                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
754                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
755                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
756                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
757                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
758                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
759                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
760                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
761                 break;
762         case D3DTOP_SELECTARG1:
763                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
764                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
765                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
766                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
767                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
768                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
769                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
770                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
771                 break;
772         case D3DTOP_SELECTARG2:
773                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
774                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
775                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
776                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
777                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
778                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
779                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
780                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
781                 break;
782         case D3DTOP_MODULATE:
783                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
784                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
785                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
786                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
787                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
788                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
789                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
790                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
791                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
792                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
793                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
794                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
795                 break;
796         case D3DTOP_MODULATE2X:
797                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
798                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
799                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
800                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
801                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
802                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
803                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
804                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
805                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
806                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
807                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
808                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
809                 break;
810         case D3DTOP_MODULATE4X:
811                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
812                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
813                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
814                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
815                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
816                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
817                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
818                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
819                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
820                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
821                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
822                 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
823                 break;
824         case D3DTOP_ADD:
825                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
826                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
827                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
828                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
829                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
830                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
831                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
832                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
833                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
834                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
835                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
836                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
837                 break;
838         case D3DTOP_ADDSIGNED:
839                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
840                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
841                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
842                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
843                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
844                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
845                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
846                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
847                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
848                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
849                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
850                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
851                 break;
852         case D3DTOP_ADDSIGNED2X:
853                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
854                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
855                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
856                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
857                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
858                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
859                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
860                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
861                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
862                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
863                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
864                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
865                 break;
866         case D3DTOP_SUBTRACT:
867           if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
868                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
869                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
870                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
871                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
872                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
873                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
874                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
875                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
876                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
877                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
878                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
879                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
880           } else {
881                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
882           }
883           break;
884
885         case D3DTOP_BLENDDIFFUSEALPHA:
886                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
887                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
888                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
889                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
890                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
891                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
892                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
893                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
894                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
895                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
896                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
897                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
898                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
899                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
900                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
901                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
902                 break;
903         case D3DTOP_BLENDTEXTUREALPHA:
904                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
905                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
906                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
907                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
908                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
909                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
910                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
911                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
912                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
913                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
914                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
915                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
916                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
917                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
918                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
919                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
920                 break;
921         case D3DTOP_BLENDFACTORALPHA:
922                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
923                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
924                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
925                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
926                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
927                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
928                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
929                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
930                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
931                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
932                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
933                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
934                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
935                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
936                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
937                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
938                 break;
939         case D3DTOP_BLENDCURRENTALPHA:
940                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
941                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
942                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
943                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
944                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
945                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
946                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
947                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
948                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
949                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
950                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
951                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
952                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
953                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
954                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
955                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
956                 break;
957         case D3DTOP_DOTPRODUCT3: 
958                if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
959                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
960                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
961                } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
962                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
963                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
964                 } else {
965                   FIXME("This version of opengl does not support GL_DOT3\n");
966                 }
967                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
968                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
969                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
970                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
971                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
972                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
973                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
974                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
975                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
976                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
977                 break;
978         case D3DTOP_LERP:
979                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
980                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
981                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
982                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
983                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
984                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
985                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
986                 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
987                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
988                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
989                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
990                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
991                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, src3);
992                 checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
993                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
994                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
995                 break;
996         default:
997                 Handled = FALSE;
998         }
999
1000         if (Handled) {
1001           BOOL  combineOK = TRUE;
1002           if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1003             DWORD op2;
1004             
1005             if (isAlpha) {
1006               op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP];
1007             } else {
1008               op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_ALPHAOP];
1009             }
1010             
1011             /* Note: If COMBINE4 in effect can't go back to combine! */
1012             switch (op2) {
1013             case D3DTOP_ADDSMOOTH:
1014             case D3DTOP_BLENDTEXTUREALPHAPM:
1015             case D3DTOP_MODULATEALPHA_ADDCOLOR:
1016             case D3DTOP_MODULATECOLOR_ADDALPHA:
1017             case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
1018             case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
1019             case D3DTOP_MULTIPLYADD:
1020               /* Ignore those implemented in both cases */
1021               switch (op) {
1022               case D3DTOP_SELECTARG1:
1023               case D3DTOP_SELECTARG2:
1024                 combineOK = FALSE;
1025                 Handled   = FALSE;
1026                 break;
1027               default:
1028                 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%d, otherop=%ld, isAlpha(%d)\n", op, op2, isAlpha);
1029                 LEAVE_GL();
1030                 return;
1031               }
1032             }
1033           }
1034           
1035           if (combineOK == TRUE) {
1036             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
1037             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
1038             
1039             LEAVE_GL();
1040             return;
1041           }
1042         }
1043
1044         /* Other texture operations require special extensions: */
1045         if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1046           if (isAlpha) {
1047             opr = GL_SRC_ALPHA;
1048             invopr = GL_ONE_MINUS_SRC_ALPHA;
1049             src3_target = GL_SOURCE3_ALPHA_NV;
1050             opr3_target = GL_OPERAND3_ALPHA_NV;
1051           } else {
1052             opr = GL_SRC_COLOR;
1053             invopr = GL_ONE_MINUS_SRC_COLOR;
1054             src3_target = GL_SOURCE3_RGB_NV;
1055             opr3_target = GL_OPERAND3_RGB_NV;
1056           }
1057           Handled = TRUE; /* Again, assume handled */
1058           switch (op) {
1059           case D3DTOP_SELECTARG1:                                          /* = a1 * 1 + 0 * 0 */
1060           case D3DTOP_SELECTARG2:                                          /* = a2 * 1 + 0 * 0 */
1061             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1062             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1063             if (op == D3DTOP_SELECTARG1) {
1064               glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);                
1065               checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1066               glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);        
1067               checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");  
1068             } else {
1069               glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);                
1070               checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1071               glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);        
1072               checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");  
1073             }
1074             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);             
1075             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1076             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);              
1077             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");  
1078             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);             
1079             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1080             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1081             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");  
1082             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);             
1083             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1084             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1085             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");  
1086             break;
1087             
1088           case D3DTOP_ADDSMOOTH:
1089             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1090             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1091             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1092             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1093             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1094             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1095             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1096             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1097             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1098             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1099             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1100             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1101             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1102             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1103             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1104             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1105             switch (opr1) {
1106             case GL_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_COLOR; break;
1107             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_SRC_COLOR; break;
1108             case GL_SRC_ALPHA: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1109             case GL_ONE_MINUS_SRC_ALPHA: opr1 = GL_SRC_ALPHA; break;
1110             }
1111             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
1112             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1113             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1114             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1115             break;
1116           case D3DTOP_BLENDTEXTUREALPHAPM:
1117             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1118             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1119             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1120             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1121             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1122             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1123             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1124             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1125             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1126             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1127             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1128             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1129             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1130             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1131             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1132             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1133             glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1134             checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1135             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1136             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1137             break;
1138           case D3DTOP_MODULATEALPHA_ADDCOLOR:
1139             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1140             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
1141             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
1142             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1143             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1144             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
1145             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1146             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1147             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);      
1148             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");  
1149             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
1150             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1151             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1152             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
1153             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1154             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1155             switch (opr1) {
1156             case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1157             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1158             }
1159             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
1160             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1161             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1162             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1163             break;
1164           case D3DTOP_MODULATECOLOR_ADDALPHA:
1165             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1166             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1167             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1168             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1169             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1170             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1171             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1172             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1173             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1174             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1175             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1176             checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1177             switch (opr1) {
1178             case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1179             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1180             }
1181             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1182             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
1183             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1184             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1185             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1186             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1187             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1188             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1189             break;
1190           case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
1191             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1192             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1193             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1194             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1195             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1196             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1197             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1198             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1199             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1200             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1201             glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1202             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1203             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1204             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1205             glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1206             checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1207             switch (opr1) {
1208             case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1209             case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1210             case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1211             case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1212             }
1213             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1214             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1215             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1216             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1217             break;
1218           case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
1219             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1220             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1221             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1222             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1223             switch (opr1) {
1224             case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1225             case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1226             case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1227             case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1228             }
1229             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1230             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1231             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1232             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1233             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1234             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1235             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1236             checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1237             switch (opr1) {
1238             case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1239             case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1240             }
1241             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1242             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
1243             glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1244             checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1245             glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1246             checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1247             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1248             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1249             break;
1250           case D3DTOP_MULTIPLYADD:
1251             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1252             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1253             glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1254             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1255             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1256             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1257             glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1258             checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1259             glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1260             checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1261             glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1262             checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1263             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1264             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1265             glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1266             checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1267             glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1268             checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1269             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1270             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1271             break;
1272             
1273           case D3DTOP_BUMPENVMAP:
1274             {
1275               if (GL_SUPPORT(NV_TEXTURE_SHADER)) {
1276                 /*
1277                   texture unit 0: GL_TEXTURE_2D
1278                   texture unit 1: GL_DOT_PRODUCT_NV
1279                   texture unit 2: GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV
1280                   texture unit 3: GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV
1281                 */
1282                 float m[2][2];
1283                 
1284                 union {
1285                   float f;
1286                   DWORD d;
1287                 } tmpvalue;
1288                 
1289                 tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT00];
1290                 m[0][0] = tmpvalue.f;
1291                 tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT01];
1292                 m[0][1] = tmpvalue.f;
1293                 tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT10];
1294                 m[1][0] = tmpvalue.f;
1295                 tmpvalue.d = This->StateBlock->texture_state[Stage][D3DTSS_BUMPENVMAT11];
1296                 m[1][1] = tmpvalue.f;
1297                 
1298                 if (FALSE == This->texture_shader_active) {
1299                   This->texture_shader_active = TRUE;
1300                   glEnable(GL_TEXTURE_SHADER_NV);
1301                 }
1302                 /*
1303                   glActiveTextureARB(GL_TEXTURE0_ARB + Stage - 1);
1304                   glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
1305                 */
1306                 glActiveTextureARB(GL_TEXTURE1_ARB + Stage);
1307                 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
1308                 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + Stage - 1);
1309                 glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, (float*)&m[0]);
1310                 break;      
1311               }
1312             }
1313
1314           case D3DTOP_BUMPENVMAPLUMINANCE:
1315
1316           default:
1317             Handled = FALSE;
1318           }
1319           if (Handled) {
1320             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1321             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1322             
1323             LEAVE_GL();
1324             return;
1325           }
1326         } /* GL_NV_texture_env_combine4 */
1327         
1328         LEAVE_GL();
1329         
1330         /* After all the extensions, if still unhandled, report fixme */
1331         FIXME("Unhandled texture operation %d\n", op);
1332 }
1333 #endif