Enable resolution changes for D3D8 applications.
[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_R5G6B5:           retVal = 2; break;
382     case D3DFMT_X1R5G5B5:         retVal = 2; break;
383     case D3DFMT_A4R4G4B4:         retVal = 2; break;
384     case D3DFMT_X4R4G4B4:         retVal = 2; break;
385     case D3DFMT_A1R5G5B5:         retVal = 2; break;
386     case D3DFMT_R8G8B8:           retVal = 3; break;
387     case D3DFMT_X8R8G8B8:         retVal = 4; break;
388     case D3DFMT_A8R8G8B8:         retVal = 4; break;
389     /* depth/stencil buffer */
390     case D3DFMT_D16_LOCKABLE:     retVal = 2; break;
391     case D3DFMT_D16:              retVal = 2; break;
392     case D3DFMT_D15S1:            retVal = 2; break;
393     case D3DFMT_D24X4S4:          retVal = 4; break;
394     case D3DFMT_D24S8:            retVal = 4; break;
395     case D3DFMT_D24X8:            retVal = 4; break;
396     case D3DFMT_D32:              retVal = 4; break;
397     /* unknown */                                 
398     case D3DFMT_UNKNOWN:
399       /* Guess at the highest value of the above */
400       TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %u\n", fmt);
401       retVal = 4;
402       break;
403
404     default:
405       FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
406       retVal = 4;
407     }
408     TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
409     return retVal;
410 }
411
412 GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
413     GLint retVal = 0;
414
415 #if defined(GL_EXT_texture_compression_s3tc)
416     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
417       switch (fmt) {
418       case D3DFMT_DXT1:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
419       case D3DFMT_DXT3:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
420       case D3DFMT_DXT5:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
421       default:
422         /* stupid compiler */
423         break;
424       }
425     }
426 #endif
427     if (retVal == 0) {
428         switch (fmt) {
429         case D3DFMT_P8:               retVal = GL_COLOR_INDEX8_EXT; break;
430         case D3DFMT_A8P8:             retVal = GL_COLOR_INDEX8_EXT; break;
431
432         case D3DFMT_A4R4G4B4:         retVal = GL_RGBA4; break;
433         case D3DFMT_A8R8G8B8:         retVal = GL_RGBA8; break;
434         case D3DFMT_X8R8G8B8:         retVal = GL_RGB8; break;
435         case D3DFMT_R8G8B8:           retVal = GL_RGB8; break;
436         case D3DFMT_R5G6B5:           retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
437         case D3DFMT_A1R5G5B5:         retVal = GL_RGB5_A1; break;
438         default:
439             FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
440             retVal = GL_RGB8;
441         }
442     }
443     TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
444     return retVal;
445 }
446
447 GLenum D3DFmt2GLFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
448     GLenum retVal;
449
450     switch (fmt) {
451     case D3DFMT_P8:               retVal = GL_COLOR_INDEX; break;
452     case D3DFMT_A8P8:             retVal = GL_COLOR_INDEX; break;
453
454     case D3DFMT_A4R4G4B4:         retVal = GL_BGRA; break;
455     case D3DFMT_A8R8G8B8:         retVal = GL_BGRA; break;
456     case D3DFMT_X8R8G8B8:         retVal = GL_BGRA; break;
457     case D3DFMT_R8G8B8:           retVal = GL_BGR; break;
458     case D3DFMT_R5G6B5:           retVal = GL_RGB; break;
459     case D3DFMT_A1R5G5B5:         retVal = GL_BGRA; break;
460     default:
461         FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
462         retVal = GL_BGR;
463     }
464 #if defined(GL_EXT_texture_compression_s3tc)
465     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
466       switch (fmt) {
467       case D3DFMT_DXT1:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
468       case D3DFMT_DXT3:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
469       case D3DFMT_DXT5:             retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
470       default:
471         /* stupid compiler */
472         break;
473       }
474     }
475 #endif
476     TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
477     return retVal;
478 }
479
480 GLenum D3DFmt2GLType(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
481     GLenum retVal;
482
483     switch (fmt) {
484     case D3DFMT_P8:               retVal = GL_UNSIGNED_BYTE; break;
485     case D3DFMT_A8P8:             retVal = GL_UNSIGNED_BYTE; break;
486
487     case D3DFMT_A4R4G4B4:         retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
488     case D3DFMT_A8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
489     case D3DFMT_X8R8G8B8:         retVal = GL_UNSIGNED_BYTE; break;
490     case D3DFMT_R5G6B5:           retVal = GL_UNSIGNED_SHORT_5_6_5; break;
491     case D3DFMT_R8G8B8:           retVal = GL_UNSIGNED_BYTE; break;
492     case D3DFMT_A1R5G5B5:         retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
493     default:
494         FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
495         retVal = GL_UNSIGNED_BYTE;
496     }
497 #if defined(GL_EXT_texture_compression_s3tc)
498     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
499       switch (fmt) {
500       case D3DFMT_DXT1:             retVal = 0; break;
501       case D3DFMT_DXT3:             retVal = 0; break;
502       case D3DFMT_DXT5:             retVal = 0; break;
503       default:
504         /* stupid compiler */
505         break;
506       }
507     }
508 #endif
509     TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
510     return retVal;
511 }
512
513 int SOURCEx_RGB_EXT(DWORD arg) {
514     switch(arg) {
515     case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
516     case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
517     case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
518     case D3DTSS_ALPHAARG0:
519     case D3DTSS_ALPHAARG1:
520     case D3DTSS_ALPHAARG2:
521     default:
522         FIXME("Invalid arg %ld\n", arg);
523         return GL_SOURCE0_RGB_EXT;
524     }
525 }
526
527 int OPERANDx_RGB_EXT(DWORD arg) {
528     switch(arg) {
529     case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
530     case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
531     case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
532     case D3DTSS_ALPHAARG0:
533     case D3DTSS_ALPHAARG1:
534     case D3DTSS_ALPHAARG2:
535     default:
536         FIXME("Invalid arg %ld\n", arg);
537         return GL_OPERAND0_RGB_EXT;
538     }
539 }
540
541 int SOURCEx_ALPHA_EXT(DWORD arg) {
542     switch(arg) {
543     case D3DTSS_ALPHAARG0:  return GL_SOURCE2_ALPHA_EXT;
544     case D3DTSS_ALPHAARG1:  return GL_SOURCE0_ALPHA_EXT;
545     case D3DTSS_ALPHAARG2:  return GL_SOURCE1_ALPHA_EXT;
546     case D3DTSS_COLORARG0:
547     case D3DTSS_COLORARG1:
548     case D3DTSS_COLORARG2:
549     default:
550         FIXME("Invalid arg %ld\n", arg);
551         return GL_SOURCE0_ALPHA_EXT;
552     }
553 }
554
555 int OPERANDx_ALPHA_EXT(DWORD arg) {
556     switch(arg) {
557     case D3DTSS_ALPHAARG0:  return GL_OPERAND2_ALPHA_EXT;
558     case D3DTSS_ALPHAARG1:  return GL_OPERAND0_ALPHA_EXT;
559     case D3DTSS_ALPHAARG2:  return GL_OPERAND1_ALPHA_EXT;
560     case D3DTSS_COLORARG0:
561     case D3DTSS_COLORARG1:
562     case D3DTSS_COLORARG2:
563     default:
564         FIXME("Invalid arg %ld\n", arg);
565         return GL_OPERAND0_ALPHA_EXT;
566     }
567 }
568
569 GLenum StencilOp(DWORD op) {
570     switch(op) {                
571     case D3DSTENCILOP_KEEP    : return GL_KEEP;
572     case D3DSTENCILOP_ZERO    : return GL_ZERO;
573     case D3DSTENCILOP_REPLACE : return GL_REPLACE;
574     case D3DSTENCILOP_INCRSAT : return GL_INCR;
575     case D3DSTENCILOP_DECRSAT : return GL_DECR;
576     case D3DSTENCILOP_INVERT  : return GL_INVERT; 
577 #if defined(GL_VERSION_1_4)
578     case D3DSTENCILOP_INCR    : return GL_INCR_WRAP;
579     case D3DSTENCILOP_DECR    : return GL_DECR_WRAP;
580 #elif defined(GL_EXT_stencil_wrap)
581     case D3DSTENCILOP_INCR    : return GL_INCR_WRAP_EXT;
582     case D3DSTENCILOP_DECR    : return GL_DECR_WRAP_EXT;
583 #else
584     case D3DSTENCILOP_INCR    : FIXME("Unsupported stencil op D3DSTENCILOP_INCR\n");
585                                 return GL_INCR; /* Fixme - needs to support wrap */
586     case D3DSTENCILOP_DECR    : FIXME("Unsupported stencil op D3DSTENCILOP_DECR\n");
587                                 return GL_DECR; /* Fixme - needs to support wrap */
588 #endif
589     default:
590         FIXME("Invalid stencil op %ld\n", op);
591         return GL_ALWAYS;
592     }
593 }
594
595 /**
596  * @nodoc: todo
597  */
598 void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand) 
599 {
600   BOOL isAlphaReplicate = FALSE;
601   BOOL isComplement     = FALSE;
602   
603   *operand = GL_SRC_COLOR;
604   *source = GL_TEXTURE;
605   
606   /* Catch alpha replicate */
607   if (iValue & D3DTA_ALPHAREPLICATE) {
608     iValue = iValue & ~D3DTA_ALPHAREPLICATE;
609     isAlphaReplicate = TRUE;
610   }
611   
612   /* Catch Complement */
613   if (iValue & D3DTA_COMPLEMENT) {
614     iValue = iValue & ~D3DTA_COMPLEMENT;
615     isComplement = TRUE;
616   }
617   
618   /* Calculate the operand */
619   if (isAlphaReplicate && !isComplement) {
620     *operand = GL_SRC_ALPHA;
621   } else if (isAlphaReplicate && isComplement) {
622     *operand = GL_ONE_MINUS_SRC_ALPHA;
623   } else if (isComplement) {
624     if (isAlphaArg) {
625       *operand = GL_ONE_MINUS_SRC_ALPHA;
626     } else {
627       *operand = GL_ONE_MINUS_SRC_COLOR;
628     }
629   } else {
630     if (isAlphaArg) {
631       *operand = GL_SRC_ALPHA;
632     } else {
633       *operand = GL_SRC_COLOR;
634     }
635   }
636   
637   /* Calculate the source */
638   switch (iValue & D3DTA_SELECTMASK) {
639   case D3DTA_CURRENT:   *source  = GL_PREVIOUS_EXT;
640     break;
641   case D3DTA_DIFFUSE:   *source  = GL_PRIMARY_COLOR_EXT;
642     break;
643   case D3DTA_TEXTURE:   *source  = GL_TEXTURE;
644     break;
645   case D3DTA_TFACTOR:   *source  = GL_CONSTANT_EXT;
646     break;
647   case D3DTA_SPECULAR:
648     /**
649      * According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
650      * isnt supported until base GL supports it
651      * There is no concept of temp registers as far as I can tell
652      */
653
654   default:
655     FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
656     *source = GL_TEXTURE;
657   }
658 }
659
660 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
661 #if defined (GL_VERSION_1_3)
662 # define useext(A) A
663 # define combine_ext 1
664 #elif defined (GL_EXT_texture_env_combine)
665 # define useext(A) A##_EXT
666 # define combine_ext 1
667 #elif defined (GL_ARB_texture_env_combine)
668 # define useext(A) A##_ARB
669 # define combine_ext 1
670 #else
671 # undef combine_ext
672 #endif
673
674 #if !defined(combine_ext)
675 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
676
677         FIXME("Requires opengl combine extensions to work\n");
678         return;
679 }
680 #else
681 /* Setup the texture operations texture stage states */
682 void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
683 {
684         GLenum src1, src2, src3;
685         GLenum opr1, opr2, opr3;
686         GLenum comb_target;
687         GLenum src0_target, src1_target, src2_target;
688         GLenum opr0_target, opr1_target, opr2_target;
689         GLenum scal_target;
690         GLenum opr=0, invopr, src3_target, opr3_target;
691         BOOL Handled = FALSE;
692         ICOM_THIS(IDirect3DDevice8Impl,iface);
693
694         TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
695
696         ENTER_GL();
697
698         /* Note: Operations usually involve two ars, src0 and src1 and are operations of
699            the form (a1 <operation> a2). However, some of the more complex operations
700            take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added  
701            in a third parameter called a0. Therefore these are operations of the form
702            a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
703            
704            However, below we treat the new (a0) parameter as src2/opr2, so in the actual
705            functions below, expect their syntax to differ slightly to those listed in the
706            manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
707            This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP                               */
708            
709         if (isAlpha) {
710                 comb_target = useext(GL_COMBINE_ALPHA);
711                 src0_target = useext(GL_SOURCE0_ALPHA);
712                 src1_target = useext(GL_SOURCE1_ALPHA);
713                 src2_target = useext(GL_SOURCE2_ALPHA);
714                 opr0_target = useext(GL_OPERAND0_ALPHA);
715                 opr1_target = useext(GL_OPERAND1_ALPHA);
716                 opr2_target = useext(GL_OPERAND2_ALPHA);
717                 scal_target = GL_ALPHA_SCALE;
718         }
719         else {
720                 comb_target = useext(GL_COMBINE_RGB);
721                 src0_target = useext(GL_SOURCE0_RGB);
722                 src1_target = useext(GL_SOURCE1_RGB);
723                 src2_target = useext(GL_SOURCE2_RGB);
724                 opr0_target = useext(GL_OPERAND0_RGB);
725                 opr1_target = useext(GL_OPERAND1_RGB);
726                 opr2_target = useext(GL_OPERAND2_RGB);
727                 scal_target = useext(GL_RGB_SCALE);
728         }
729
730         /* From MSDN (D3DTSS_ALPHAARG1) : 
731            The default argument is D3DTA_TEXTURE. If no texture is set for this stage, 
732                    then the default argument is D3DTA_DIFFUSE.
733                    FIXME? If texture added/removed, may need to reset back as well?    */
734         if (isAlpha && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
735             GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);  
736         } else {
737             GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
738         }
739         GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2);
740         GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3);
741         
742         TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
743
744         Handled = TRUE; /* Assume will be handled */
745         switch (op) {
746         case D3DTOP_DISABLE: /* Only for alpha */
747                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
748                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
749                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
750                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
751                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
752                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
753                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
754                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
755                 break;
756         case D3DTOP_SELECTARG1:
757                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
758                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
759                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
760                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
761                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
762                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
763                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
764                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
765                 break;
766         case D3DTOP_SELECTARG2:
767                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
768                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
769                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
770                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
771                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
772                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
773                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
774                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
775                 break;
776         case D3DTOP_MODULATE:
777                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
778                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
779                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
780                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
781                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
782                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
783                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
784                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
785                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
786                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
787                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
788                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
789                 break;
790         case D3DTOP_MODULATE2X:
791                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
792                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
793                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
794                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
795                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
796                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
797                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
798                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
799                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
800                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
801                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
802                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
803                 break;
804         case D3DTOP_MODULATE4X:
805                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
806                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
807                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
808                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
809                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
810                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
811                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
812                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
813                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
814                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
815                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
816                 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
817                 break;
818         case D3DTOP_ADD:
819                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
820                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
821                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
822                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
823                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
824                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
825                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
826                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
827                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
828                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
829                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
830                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
831                 break;
832         case D3DTOP_ADDSIGNED:
833                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
834                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
835                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
836                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
837                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
838                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
839                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
840                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
841                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
842                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
843                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
844                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
845                 break;
846         case D3DTOP_ADDSIGNED2X:
847                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
848                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
849                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
850                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
851                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
852                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
853                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
854                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
855                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
856                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
857                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
858                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
859                 break;
860         case D3DTOP_SUBTRACT:
861           if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
862                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
863                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
864                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
865                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
866                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
867                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
868                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
869                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
870                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
871                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
872                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
873                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
874           } else {
875                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
876           }
877           break;
878
879         case D3DTOP_BLENDDIFFUSEALPHA:
880                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
881                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
882                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
883                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
884                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
885                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
886                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
887                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
888                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
889                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
890                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
891                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
892                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
893                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
894                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
895                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
896                 break;
897         case D3DTOP_BLENDTEXTUREALPHA:
898                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
899                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
900                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
901                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
902                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
903                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
904                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
905                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
906                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
907                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
908                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
909                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
910                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
911                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
912                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
913                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
914                 break;
915         case D3DTOP_BLENDFACTORALPHA:
916                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
917                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
918                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
919                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
920                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
921                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
922                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
923                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
924                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
925                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
926                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
927                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
928                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
929                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
930                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
931                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
932                 break;
933         case D3DTOP_BLENDCURRENTALPHA:
934                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
935                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
936                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
937                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
938                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
939                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
940                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
941                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
942                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
943                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
944                 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
945                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
946                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
947                 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
948                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
949                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
950                 break;
951         case D3DTOP_DOTPRODUCT3: 
952                if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
953                   glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);
954                   checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA");
955                 } else {
956                   FIXME("This version of opengl does not support GL_DOT3\n");
957                 }
958                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
959                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
960                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
961                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
962                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
963                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
964                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
965                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
966                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
967                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
968                 break;
969         case D3DTOP_LERP:
970                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
971                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
972                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
973                 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
974                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
975                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
976                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
977                 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
978                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
979                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
980                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
981                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
982                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, src3);
983                 checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
984                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
985                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
986                 break;
987         default:
988                 Handled = FALSE;
989         }
990
991         if (Handled) {
992             BOOL  combineOK = TRUE;
993 #if defined(GL_NV_texture_env_combine4)
994             DWORD op2;
995
996             if (isAlpha) {
997                 op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP];
998             } else {
999                 op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_ALPHAOP];
1000             }
1001
1002            /* Note: If COMBINE4 in effect cant go back to combine! */
1003            switch (op2)
1004            {
1005            case D3DTOP_ADDSMOOTH:
1006            case D3DTOP_BLENDTEXTUREALPHAPM:
1007            case D3DTOP_MODULATEALPHA_ADDCOLOR:
1008            case D3DTOP_MODULATECOLOR_ADDALPHA:
1009            case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
1010            case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
1011            case D3DTOP_MULTIPLYADD:
1012                /* Ignore those implemented in both cases */
1013                switch (op) {
1014                case D3DTOP_SELECTARG1:
1015                case D3DTOP_SELECTARG2:
1016                    combineOK = FALSE;
1017                    Handled   = FALSE;
1018                    break;
1019                default:
1020                    FIXME("Cant have COMBINE4 and COMBINE in efferct together, thisop=%d, otherop=%ld, isAlpha(%d)\n", 
1021                               op, op2, isAlpha);
1022
1023                    LEAVE_GL();
1024                    return;
1025                }
1026            }
1027 #endif
1028
1029            if (combineOK == TRUE) {
1030                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
1031                checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
1032
1033                LEAVE_GL();
1034                return;
1035            }
1036         }
1037
1038         /* Other texture operations require special extensions: */
1039 #if defined(GL_NV_texture_env_combine4)
1040         if (isAlpha) {
1041                 opr = GL_SRC_ALPHA;
1042                 invopr = GL_ONE_MINUS_SRC_ALPHA;
1043                 src3_target = GL_SOURCE3_ALPHA_NV;
1044                 opr3_target = GL_OPERAND3_ALPHA_NV;
1045         }
1046         else {
1047                 opr = GL_SRC_COLOR;
1048                 invopr = GL_ONE_MINUS_SRC_COLOR;
1049                 src3_target = GL_SOURCE3_RGB_NV;
1050                 opr3_target = GL_OPERAND3_RGB_NV;
1051         }
1052         Handled = TRUE; /* Again, assume handled */
1053         switch (op) {
1054         case D3DTOP_SELECTARG1:                                          /* = a1 * 1 + 0 * 0 */
1055         case D3DTOP_SELECTARG2:                                          /* = a2 * 1 + 0 * 0 */
1056                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1057                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1058                 if (op == D3DTOP_SELECTARG1) {
1059                     glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);                
1060                     checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1061                     glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);        
1062                     checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");  
1063                 } else {
1064                     glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);                
1065                     checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
1066                     glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);        
1067                     checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");  
1068                 }
1069                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);             
1070                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1071                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);              
1072                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");  
1073                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);             
1074                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1075                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1076                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");  
1077                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);             
1078                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1079                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1080                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");  
1081                 break;
1082
1083         case D3DTOP_ADDSMOOTH:
1084                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1085                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1086                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1087                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1088                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1089                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1090                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1091                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1092                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1093                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1094                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1095                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1096                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1097                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1098                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1099                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1100                 switch (opr1) {
1101                 case GL_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_COLOR; break;
1102                 case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_SRC_COLOR; break;
1103                 case GL_SRC_ALPHA: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1104                 case GL_ONE_MINUS_SRC_ALPHA: opr1 = GL_SRC_ALPHA; break;
1105                 }
1106                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
1107                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1108                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1109                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1110                 break;
1111         case D3DTOP_BLENDTEXTUREALPHAPM:
1112                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1113                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1114                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1115                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1116                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1117                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1118                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1119                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1120                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1121                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1122                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1123                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1124                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1125                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1126                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
1127                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
1128                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
1129                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
1130                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1131                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1132                 break;
1133         case D3DTOP_MODULATEALPHA_ADDCOLOR:
1134                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1135                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
1136                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
1137                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1138                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1139                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
1140                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1141                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1142                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);      
1143                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");  
1144                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
1145                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1146                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1147                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
1148                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1149                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1150                 switch (opr1) {
1151                 case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1152                 case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1153                 }
1154                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
1155                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
1156                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1157                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1158                 break;
1159         case D3DTOP_MODULATECOLOR_ADDALPHA:
1160                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1161                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1162                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1163                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1164                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1165                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1166                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1167                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1168                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1169                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1170                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1171                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1172                 switch (opr1) {
1173                 case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1174                 case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1175                 }
1176                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1177                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
1178                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1179                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1180                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1181                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1182                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1183                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1184                 break;
1185         case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
1186                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1187                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1188                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1189                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1190                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
1191                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1192                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1193                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1194                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1195                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1196                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
1197                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1198                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
1199                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1200                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
1201                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
1202                 switch (opr1) {
1203                 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1204                 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
1205                 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1206                 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1207                 }
1208                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1209                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1210                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1211                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1212                 break;
1213         case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
1214                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1215                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1216                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1217                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1218                 switch (opr1) {
1219                 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
1220                 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
1221                 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
1222                 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
1223                 }
1224                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
1225                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
1226                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
1227                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
1228                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
1229                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
1230                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1231                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
1232                 switch (opr1) {
1233                 case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
1234                 case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
1235                 }
1236                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1237                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
1238                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1239                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1240                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
1241                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
1242                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1243                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1244                 break;
1245         case D3DTOP_MULTIPLYADD:
1246                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1247                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1248                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
1249                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1250                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
1251                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1252                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1253                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1254                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1255                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1256                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
1257                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
1258                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
1259                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
1260                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
1261                 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
1262                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
1263                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
1264                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
1265                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
1266                 break;
1267
1268         default:
1269                 Handled = FALSE;
1270         }
1271         if (Handled) {
1272             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
1273             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
1274
1275             LEAVE_GL();
1276             return;
1277         }
1278 #endif /* GL_NV_texture_env_combine4 */
1279
1280         LEAVE_GL();
1281
1282         /* After all the extensions, if still unhandled, report fixme */
1283         FIXME("Unhandled texture operation %d\n", op);
1284 }
1285 #endif