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