VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/state.c@ 41283

Last change on this file since 41283 was 38438, checked in by vboxsync, 13 years ago

wddm/wine: disable extra warnings

  • Property svn:eol-style set to native
File size: 341.4 KB
Line 
1/*
2 * Direct3D state management
3 *
4 * Copyright 2002 Lionel Ulmer
5 * Copyright 2002-2005 Jason Edmeades
6 * Copyright 2003-2004 Raphael Junqueira
7 * Copyright 2004 Christian Costa
8 * Copyright 2005 Oliver Stieber
9 * Copyright 2006 Henri Verbeet
10 * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
11 * Copyright 2009 Henri Verbeet for CodeWeavers
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 */
27
28/*
29 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
30 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
31 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
32 * a choice of LGPL license versions is made available with the language indicating
33 * that LGPLv2 or any later version may be used, or where a choice of which version
34 * of the LGPL is applied is otherwise unspecified.
35 */
36
37#include "config.h"
38#include <stdio.h>
39#ifdef HAVE_FLOAT_H
40# include <float.h>
41#endif
42#include "wined3d_private.h"
43
44WINE_DEFAULT_DEBUG_CHANNEL(d3d);
45WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
46
47#define GLINFO_LOCATION (*context->gl_info)
48
49/* GL locking for state handlers is done by the caller. */
50
51static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
52
53static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
54{
55#ifdef DEBUG_misha
56 WARN("Undefined state.\n");
57#elif !defined(VBOX_WITH_WDDM)
58 ERR("Undefined state.\n");
59#endif
60}
61
62static void state_nop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
63{
64 TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state));
65}
66
67static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
68{
69 WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
70
71 switch(Value) {
72 case WINED3DFILL_POINT:
73 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
74 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
75 break;
76 case WINED3DFILL_WIREFRAME:
77 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
78 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
79 break;
80 case WINED3DFILL_SOLID:
81 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
82 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
83 break;
84 default:
85 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
86 }
87}
88
89static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
90{
91 /* Lighting is not enabled if transformed vertices are drawn
92 * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
93 * This state reads the decoded vertex declaration, so if it is dirty don't do anything. The
94 * vertex declaration applying function calls this function for updating
95 */
96
97 if(isStateDirty(context, STATE_VDECL)) {
98 return;
99 }
100
101 if (stateblock->renderState[WINED3DRS_LIGHTING]
102 && !stateblock->device->strided_streams.position_transformed)
103 {
104 glEnable(GL_LIGHTING);
105 checkGLcall("glEnable GL_LIGHTING");
106 } else {
107 glDisable(GL_LIGHTING);
108 checkGLcall("glDisable GL_LIGHTING");
109 }
110}
111
112static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
113{
114 /* No z test without depth stencil buffers */
115 if (!stateblock->device->stencilBufferTarget)
116 {
117 TRACE("No Z buffer - disabling depth test\n");
118 glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
119 checkGLcall("glDisable GL_DEPTH_TEST");
120 return;
121 }
122
123 switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
124 case WINED3DZB_FALSE:
125 glDisable(GL_DEPTH_TEST);
126 checkGLcall("glDisable GL_DEPTH_TEST");
127 break;
128 case WINED3DZB_TRUE:
129 glEnable(GL_DEPTH_TEST);
130 checkGLcall("glEnable GL_DEPTH_TEST");
131 break;
132 case WINED3DZB_USEW:
133 glEnable(GL_DEPTH_TEST);
134 checkGLcall("glEnable GL_DEPTH_TEST");
135 FIXME("W buffer is not well handled\n");
136 break;
137 default:
138 FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]);
139 }
140}
141
142static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
143{
144 /* glFrontFace() is set in context.c at context init and on an offscreen / onscreen rendering
145 * switch
146 */
147 switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
148 case WINED3DCULL_NONE:
149 glDisable(GL_CULL_FACE);
150 checkGLcall("glDisable GL_CULL_FACE");
151 break;
152 case WINED3DCULL_CW:
153 glEnable(GL_CULL_FACE);
154 checkGLcall("glEnable GL_CULL_FACE");
155 glCullFace(GL_FRONT);
156 checkGLcall("glCullFace(GL_FRONT)");
157 break;
158 case WINED3DCULL_CCW:
159 glEnable(GL_CULL_FACE);
160 checkGLcall("glEnable GL_CULL_FACE");
161 glCullFace(GL_BACK);
162 checkGLcall("glCullFace(GL_BACK)");
163 break;
164 default:
165 FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
166 }
167}
168
169static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
170{
171 switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
172 case WINED3DSHADE_FLAT:
173 glShadeModel(GL_FLAT);
174 checkGLcall("glShadeModel(GL_FLAT)");
175 break;
176 case WINED3DSHADE_GOURAUD:
177 glShadeModel(GL_SMOOTH);
178 checkGLcall("glShadeModel(GL_SMOOTH)");
179 break;
180 case WINED3DSHADE_PHONG:
181 FIXME("WINED3DSHADE_PHONG isn't supported\n");
182 break;
183 default:
184 FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]);
185 }
186}
187
188static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
189{
190 if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
191 glEnable(GL_DITHER);
192 checkGLcall("glEnable GL_DITHER");
193 } else {
194 glDisable(GL_DITHER);
195 checkGLcall("glDisable GL_DITHER");
196 }
197}
198
199static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
200{
201 /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
202 * this has to be merged with ZENABLE and ZFUNC
203 */
204 if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) {
205 glDepthMask(1);
206 checkGLcall("glDepthMask(1)");
207 } else {
208 glDepthMask(0);
209 checkGLcall("glDepthMask(0)");
210 }
211}
212
213static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
214{
215 int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
216
217 if(glParm) {
218 if(glParm == GL_EQUAL || glParm == GL_NOTEQUAL) {
219 static BOOL once = FALSE;
220 /* There are a few issues with this: First, our inability to
221 * select a proper Z depth, most of the time we're stuck with
222 * D24S8, even if the app selects D32 or D16. There seem to be
223 * some other precision problems which have to be debugged to
224 * make NOTEQUAL and EQUAL work properly
225 */
226 if(!once) {
227 once = TRUE;
228 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet\n");
229 }
230 }
231
232 glDepthFunc(glParm);
233 checkGLcall("glDepthFunc");
234 }
235}
236
237static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
238{
239 float col[4];
240 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
241
242 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
243 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
244 checkGLcall("glLightModel for MODEL_AMBIENT");
245}
246
247static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
248{
249 IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0];
250 int srcBlend = GL_ZERO;
251 int dstBlend = GL_ZERO;
252
253 /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */
254 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE] ||
255 stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
256 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
257
258 /* Disable blending in all cases even without pixelshaders. With blending on we could face a big performance penalty.
259 * The d3d9 visual test confirms the behavior. */
260 if (context->render_offscreen
261 && !(target->resource.format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
262 {
263 glDisable(GL_BLEND);
264 checkGLcall("glDisable GL_BLEND");
265 return;
266 } else {
267 glEnable(GL_BLEND);
268 checkGLcall("glEnable GL_BLEND");
269 }
270 } else {
271 glDisable(GL_BLEND);
272 checkGLcall("glDisable GL_BLEND");
273 /* Nothing more to do - get out */
274 return;
275 };
276
277 switch (stateblock->renderState[WINED3DRS_DESTBLEND]) {
278 case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break;
279 case WINED3DBLEND_ONE : dstBlend = GL_ONE; break;
280 case WINED3DBLEND_SRCCOLOR : dstBlend = GL_SRC_COLOR; break;
281 case WINED3DBLEND_INVSRCCOLOR : dstBlend = GL_ONE_MINUS_SRC_COLOR; break;
282 case WINED3DBLEND_SRCALPHA : dstBlend = GL_SRC_ALPHA; break;
283 case WINED3DBLEND_INVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA; break;
284 case WINED3DBLEND_DESTCOLOR : dstBlend = GL_DST_COLOR; break;
285 case WINED3DBLEND_INVDESTCOLOR : dstBlend = GL_ONE_MINUS_DST_COLOR; break;
286
287 /* To compensate the lack of format switching with backbuffer offscreen rendering,
288 * and with onscreen rendering, we modify the alpha test parameters for (INV)DESTALPHA
289 * if the render target doesn't support alpha blending. A nonexistent alpha channel
290 * returns 1.0, so D3DBLEND_DESTALPHA is GL_ONE, and D3DBLEND_INVDESTALPHA is GL_ZERO
291 */
292 case WINED3DBLEND_DESTALPHA :
293 dstBlend = target->resource.format_desc->alpha_mask ? GL_DST_ALPHA : GL_ONE;
294 break;
295 case WINED3DBLEND_INVDESTALPHA :
296 dstBlend = target->resource.format_desc->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
297 break;
298
299 case WINED3DBLEND_SRCALPHASAT :
300 dstBlend = GL_SRC_ALPHA_SATURATE;
301 WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
302 break;
303
304 /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
305 * values which are still valid up to d3d9. They should not occur as dest blend values
306 */
307 case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA;
308 srcBlend = GL_SRC_ALPHA;
309 FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
310 break;
311
312 case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
313 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
314 FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
315 break;
316
317 case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
318 case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
319 default:
320 FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
321 }
322
323 switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
324 case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
325 case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
326 case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
327 case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
328 case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
329 case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
330 case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
331 case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
332 case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
333
334 case WINED3DBLEND_DESTALPHA :
335 srcBlend = target->resource.format_desc->alpha_mask ? GL_DST_ALPHA : GL_ONE;
336 break;
337 case WINED3DBLEND_INVDESTALPHA :
338 srcBlend = target->resource.format_desc->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
339 break;
340
341 case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
342 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
343 break;
344
345 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
346 dstBlend = GL_SRC_ALPHA;
347 break;
348
349 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
350 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
351 default:
352 FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
353 }
354
355 if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
356 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
357 glEnable(GL_LINE_SMOOTH);
358 checkGLcall("glEnable(GL_LINE_SMOOTH)");
359 if(srcBlend != GL_SRC_ALPHA) {
360 WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
361 }
362 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
363 WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
364 }
365 } else {
366 glDisable(GL_LINE_SMOOTH);
367 checkGLcall("glDisable(GL_LINE_SMOOTH)");
368 }
369
370 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
371 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_BLENDOP))) {
372 state_blendop(STATE_RENDER(WINED3DRS_BLENDOPALPHA), stateblock, context);
373 }
374
375 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]) {
376 int srcBlendAlpha = GL_ZERO;
377 int dstBlendAlpha = GL_ZERO;
378
379 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
380 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
381 {
382 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
383 return;
384 }
385
386 switch (stateblock->renderState[WINED3DRS_DESTBLENDALPHA]) {
387 case WINED3DBLEND_ZERO : dstBlendAlpha = GL_ZERO; break;
388 case WINED3DBLEND_ONE : dstBlendAlpha = GL_ONE; break;
389 case WINED3DBLEND_SRCCOLOR : dstBlendAlpha = GL_SRC_COLOR; break;
390 case WINED3DBLEND_INVSRCCOLOR : dstBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break;
391 case WINED3DBLEND_SRCALPHA : dstBlendAlpha = GL_SRC_ALPHA; break;
392 case WINED3DBLEND_INVSRCALPHA : dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break;
393 case WINED3DBLEND_DESTCOLOR : dstBlendAlpha = GL_DST_COLOR; break;
394 case WINED3DBLEND_INVDESTCOLOR : dstBlendAlpha = GL_ONE_MINUS_DST_COLOR; break;
395 case WINED3DBLEND_DESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break;
396 case WINED3DBLEND_INVDESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break;
397 case WINED3DBLEND_SRCALPHASAT :
398 dstBlend = GL_SRC_ALPHA_SATURATE;
399 WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
400 break;
401 /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
402 * values which are still valid up to d3d9. They should not occur as dest blend values
403 */
404 case WINED3DBLEND_BOTHSRCALPHA :
405 dstBlendAlpha = GL_SRC_ALPHA;
406 srcBlendAlpha = GL_SRC_ALPHA;
407 FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
408 break;
409 case WINED3DBLEND_BOTHINVSRCALPHA :
410 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
411 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
412 FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
413 break;
414 case WINED3DBLEND_BLENDFACTOR : dstBlendAlpha = GL_CONSTANT_COLOR; break;
415 case WINED3DBLEND_INVBLENDFACTOR : dstBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break;
416 default:
417 FIXME("Unrecognized dst blend alpha value %d\n", stateblock->renderState[WINED3DRS_DESTBLENDALPHA]);
418 }
419
420 switch (stateblock->renderState[WINED3DRS_SRCBLENDALPHA]) {
421 case WINED3DBLEND_ZERO : srcBlendAlpha = GL_ZERO; break;
422 case WINED3DBLEND_ONE : srcBlendAlpha = GL_ONE; break;
423 case WINED3DBLEND_SRCCOLOR : srcBlendAlpha = GL_SRC_COLOR; break;
424 case WINED3DBLEND_INVSRCCOLOR : srcBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break;
425 case WINED3DBLEND_SRCALPHA : srcBlendAlpha = GL_SRC_ALPHA; break;
426 case WINED3DBLEND_INVSRCALPHA : srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break;
427 case WINED3DBLEND_DESTCOLOR : srcBlendAlpha = GL_DST_COLOR; break;
428 case WINED3DBLEND_INVDESTCOLOR : srcBlendAlpha = GL_ONE_MINUS_DST_COLOR; break;
429 case WINED3DBLEND_SRCALPHASAT : srcBlendAlpha = GL_SRC_ALPHA_SATURATE; break;
430 case WINED3DBLEND_DESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break;
431 case WINED3DBLEND_INVDESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break;
432 case WINED3DBLEND_BOTHSRCALPHA :
433 srcBlendAlpha = GL_SRC_ALPHA;
434 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
435 break;
436 case WINED3DBLEND_BOTHINVSRCALPHA :
437 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
438 dstBlendAlpha = GL_SRC_ALPHA;
439 break;
440 case WINED3DBLEND_BLENDFACTOR : srcBlendAlpha = GL_CONSTANT_COLOR; break;
441 case WINED3DBLEND_INVBLENDFACTOR : srcBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break;
442 default:
443 FIXME("Unrecognized src blend alpha value %d\n", stateblock->renderState[WINED3DRS_SRCBLENDALPHA]);
444 }
445
446 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
447 checkGLcall("glBlendFuncSeparateEXT");
448 } else {
449 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
450 glBlendFunc(srcBlend, dstBlend);
451 checkGLcall("glBlendFunc");
452 }
453
454 /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state,
455 so it may need updating */
456 if (stateblock->renderState[WINED3DRS_COLORKEYENABLE])
457 stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
458}
459
460static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
461{
462 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
463}
464
465static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
466{
467 float col[4];
468
469 TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
470 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
471 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
472 checkGLcall("glBlendColor");
473}
474
475static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
476{
477 int glParm = 0;
478 float ref;
479 BOOL enable_ckey = FALSE;
480
481 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
482
483 /* Find out if the texture on the first stage has a ckey set
484 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
485 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
486 * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
487 * in case it finds some texture+colorkeyenable combination which needs extra care.
488 */
489 if (stateblock->textures[0])
490 {
491 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
492
493 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
494 {
495 IWineD3DSurfaceImpl *surf;
496
497 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
498
499 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
500 {
501 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
502 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
503 * surface has alpha bits */
504 if (!surf->resource.format_desc->alpha_mask) enable_ckey = TRUE;
505 }
506 }
507 }
508
509 if (enable_ckey || context->last_was_ckey)
510 stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
511 context->last_was_ckey = enable_ckey;
512
513 if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
514 (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
515 glEnable(GL_ALPHA_TEST);
516 checkGLcall("glEnable GL_ALPHA_TEST");
517 } else {
518 glDisable(GL_ALPHA_TEST);
519 checkGLcall("glDisable GL_ALPHA_TEST");
520 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
521 * enable call
522 */
523 return;
524 }
525
526 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
527 glParm = GL_NOTEQUAL;
528 ref = 0.0f;
529 } else {
530 ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
531 glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
532 }
533 if(glParm) {
534 glAlphaFunc(glParm, ref);
535 checkGLcall("glAlphaFunc");
536 }
537}
538
539static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
540{
541 const struct wined3d_gl_info *gl_info = context->gl_info;
542 DWORD enable = 0xFFFFFFFF;
543 DWORD disable = 0x00000000;
544
545 if (!stateblock->device->vs_clipping && use_vs(stateblock))
546 {
547 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
548 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
549 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
550 * of that - don't do anything here and keep them disabled
551 */
552 if(stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
553 static BOOL warned = FALSE;
554 if(!warned) {
555 FIXME("Clipping not supported with vertex shaders\n");
556 warned = TRUE;
557 }
558 }
559 return;
560 }
561
562 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
563 * of already set values
564 */
565
566 /* If enabling / disabling all
567 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
568 */
569 if (stateblock->renderState[WINED3DRS_CLIPPING]) {
570 enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
571 disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
572 if (gl_info->supported[ARB_DEPTH_CLAMP])
573 {
574 glDisable(GL_DEPTH_CLAMP);
575 checkGLcall("glDisable(GL_DEPTH_CLAMP)");
576 }
577 } else {
578 disable = 0xffffffff;
579 enable = 0x00;
580 if (gl_info->supported[ARB_DEPTH_CLAMP])
581 {
582 glEnable(GL_DEPTH_CLAMP);
583 checkGLcall("glEnable(GL_DEPTH_CLAMP)");
584 }
585 else
586 {
587 FIXME("Clipping disabled, but ARB_depth_clamp isn't supported.\n");
588 }
589 }
590
591 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
592 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
593 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
594 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
595 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
596 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
597
598 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
599 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
600 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
601 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
602 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
603 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
604
605 /** update clipping status */
606 if (enable) {
607 stateblock->clip_status.ClipUnion = 0;
608 stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
609 } else {
610 stateblock->clip_status.ClipUnion = 0;
611 stateblock->clip_status.ClipIntersection = 0;
612 }
613}
614
615static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
616{
617 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
618}
619
620static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
621{
622 int blendEquation = GL_FUNC_ADD;
623 int blendEquationAlpha = GL_FUNC_ADD;
624
625 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
626 if (stateblock->renderState[WINED3DRS_BLENDOPALPHA]
627 && !context->gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
628 {
629 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
630 return;
631 }
632
633 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
634 case WINED3DBLENDOP_ADD : blendEquation = GL_FUNC_ADD; break;
635 case WINED3DBLENDOP_SUBTRACT : blendEquation = GL_FUNC_SUBTRACT; break;
636 case WINED3DBLENDOP_REVSUBTRACT : blendEquation = GL_FUNC_REVERSE_SUBTRACT; break;
637 case WINED3DBLENDOP_MIN : blendEquation = GL_MIN; break;
638 case WINED3DBLENDOP_MAX : blendEquation = GL_MAX; break;
639 default:
640 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
641 }
642
643 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOPALPHA]) {
644 case WINED3DBLENDOP_ADD : blendEquationAlpha = GL_FUNC_ADD; break;
645 case WINED3DBLENDOP_SUBTRACT : blendEquationAlpha = GL_FUNC_SUBTRACT; break;
646 case WINED3DBLENDOP_REVSUBTRACT : blendEquationAlpha = GL_FUNC_REVERSE_SUBTRACT; break;
647 case WINED3DBLENDOP_MIN : blendEquationAlpha = GL_MIN; break;
648 case WINED3DBLENDOP_MAX : blendEquationAlpha = GL_MAX; break;
649 default:
650 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOPALPHA]);
651 }
652
653 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]) {
654 TRACE("glBlendEquationSeparateEXT(%x, %x)\n", blendEquation, blendEquationAlpha);
655 GL_EXTCALL(glBlendEquationSeparateEXT(blendEquation, blendEquationAlpha));
656 checkGLcall("glBlendEquationSeparateEXT");
657 } else {
658 TRACE("glBlendEquation(%x)\n", blendEquation);
659 GL_EXTCALL(glBlendEquationEXT(blendEquation));
660 checkGLcall("glBlendEquation");
661 }
662}
663
664static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
665{
666 const struct wined3d_gl_info *gl_info = context->gl_info;
667 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
668 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
669 * specular color. This is wrong:
670 * Separate specular color means the specular colour is maintained separately, whereas
671 * single color means it is merged in. However in both cases they are being used to
672 * some extent.
673 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
674 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
675 * running 1.4 yet!
676 *
677 *
678 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
679 * Instead, we need to setup the FinalCombiner properly.
680 *
681 * The default setup for the FinalCombiner is:
682 *
683 * <variable> <input> <mapping> <usage>
684 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
685 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
686 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
687 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
688 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
689 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
690 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
691 *
692 * That's pretty much fine as it is, except for variable B, which needs to take
693 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
694 * whether WINED3DRS_SPECULARENABLE is enabled or not.
695 */
696
697 TRACE("Setting specular enable state and materials\n");
698 if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
699 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
700 checkGLcall("glMaterialfv");
701
702 if (stateblock->material.Power > gl_info->limits.shininess)
703 {
704 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
705 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
706 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
707 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
708 * them, it should be safe to do so without major visual distortions.
709 */
710 WARN("Material power = %f, limit %f\n", stateblock->material.Power, gl_info->limits.shininess);
711 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
712 } else {
713 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stateblock->material.Power);
714 }
715 checkGLcall("glMaterialf(GL_SHININESS)");
716
717 if (gl_info->supported[EXT_SECONDARY_COLOR])
718 {
719 glEnable(GL_COLOR_SUM_EXT);
720 }
721 else
722 {
723 TRACE("Specular colors cannot be enabled in this version of opengl\n");
724 }
725 checkGLcall("glEnable(GL_COLOR_SUM)");
726
727 if (gl_info->supported[NV_REGISTER_COMBINERS])
728 {
729 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
730 checkGLcall("glFinalCombinerInputNV()");
731 }
732 } else {
733 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
734
735 /* for the case of enabled lighting: */
736 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
737 checkGLcall("glMaterialfv");
738
739 /* for the case of disabled lighting: */
740 if (gl_info->supported[EXT_SECONDARY_COLOR])
741 {
742 glDisable(GL_COLOR_SUM_EXT);
743 }
744 else
745 {
746 TRACE("Specular colors cannot be disabled in this version of opengl\n");
747 }
748 checkGLcall("glDisable(GL_COLOR_SUM)");
749
750 if (gl_info->supported[NV_REGISTER_COMBINERS])
751 {
752 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
753 checkGLcall("glFinalCombinerInputNV()");
754 }
755 }
756
757 TRACE("(%p) : Diffuse {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
758 stateblock->material.Diffuse.r, stateblock->material.Diffuse.g,
759 stateblock->material.Diffuse.b, stateblock->material.Diffuse.a);
760 TRACE("(%p) : Ambient {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
761 stateblock->material.Ambient.r, stateblock->material.Ambient.g,
762 stateblock->material.Ambient.b, stateblock->material.Ambient.a);
763 TRACE("(%p) : Specular {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
764 stateblock->material.Specular.r, stateblock->material.Specular.g,
765 stateblock->material.Specular.b, stateblock->material.Specular.a);
766 TRACE("(%p) : Emissive {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
767 stateblock->material.Emissive.r, stateblock->material.Emissive.g,
768 stateblock->material.Emissive.b, stateblock->material.Emissive.a);
769
770 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &stateblock->material.Ambient);
771 checkGLcall("glMaterialfv(GL_AMBIENT)");
772 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &stateblock->material.Diffuse);
773 checkGLcall("glMaterialfv(GL_DIFFUSE)");
774 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &stateblock->material.Emissive);
775 checkGLcall("glMaterialfv(GL_EMISSION)");
776}
777
778static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
779{
780 unsigned int i;
781
782 /* Note the texture color applies to all textures whereas
783 * GL_TEXTURE_ENV_COLOR applies to active only
784 */
785 float col[4];
786 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
787
788 /* And now the default texture color as well */
789 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
790 {
791 /* Note the WINED3DRS value applies to all textures, but GL has one
792 * per texture, so apply it now ready to be used!
793 */
794 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
795 checkGLcall("glActiveTextureARB");
796
797 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
798 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
799 }
800}
801
802static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
803 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
804{
805 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
806 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
807 GL_EXTCALL(glActiveStencilFaceEXT(face));
808 checkGLcall("glActiveStencilFaceEXT(...)");
809 glStencilFunc(func, ref, mask);
810 checkGLcall("glStencilFunc(...)");
811 glStencilOp(stencilFail, depthFail, stencilPass);
812 checkGLcall("glStencilOp(...)");
813}
814
815static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
816{
817 const struct wined3d_gl_info *gl_info = context->gl_info;
818 DWORD onesided_enable = FALSE;
819 DWORD twosided_enable = FALSE;
820 GLint func = GL_ALWAYS;
821 GLint func_ccw = GL_ALWAYS;
822 GLint ref = 0;
823 GLuint mask = 0;
824 GLint stencilFail = GL_KEEP;
825 GLint depthFail = GL_KEEP;
826 GLint stencilPass = GL_KEEP;
827 GLint stencilFail_ccw = GL_KEEP;
828 GLint depthFail_ccw = GL_KEEP;
829 GLint stencilPass_ccw = GL_KEEP;
830
831 /* No stencil test without a stencil buffer. */
832 if (!stateblock->device->stencilBufferTarget)
833 {
834 glDisable(GL_STENCIL_TEST);
835 checkGLcall("glDisable GL_STENCIL_TEST");
836 return;
837 }
838
839 onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
840 twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
841 if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
842 func = GL_ALWAYS;
843 if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
844 func_ccw = GL_ALWAYS;
845 ref = stateblock->renderState[WINED3DRS_STENCILREF];
846 mask = stateblock->renderState[WINED3DRS_STENCILMASK];
847 stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
848 depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
849 stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
850 stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
851 depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
852 stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
853
854 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
855 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
856 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
857 onesided_enable, twosided_enable, ref, mask,
858 func, stencilFail, depthFail, stencilPass,
859 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
860
861 if (twosided_enable && onesided_enable) {
862 glEnable(GL_STENCIL_TEST);
863 checkGLcall("glEnable GL_STENCIL_TEST");
864
865 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
866 {
867 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
868 * which has an effect on the code below too. If we apply the front face
869 * afterwards, we are sure that the active stencil face is set to front,
870 * and other stencil functions which do not use two sided stencil do not have
871 * to set it back
872 */
873 renderstate_stencil_twosided(context, GL_BACK,
874 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
875 renderstate_stencil_twosided(context, GL_FRONT,
876 func, ref, mask, stencilFail, depthFail, stencilPass);
877 }
878 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
879 {
880 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
881 checkGLcall("glStencilFuncSeparateATI(...)");
882 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
883 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
884 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
885 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
886 } else {
887 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
888 }
889 }
890 else if(onesided_enable)
891 {
892 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
893 {
894 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
895 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
896 }
897
898 /* This code disables the ATI extension as well, since the standard stencil functions are equal
899 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
900 */
901 glEnable(GL_STENCIL_TEST);
902 checkGLcall("glEnable GL_STENCIL_TEST");
903 glStencilFunc(func, ref, mask);
904 checkGLcall("glStencilFunc(...)");
905 glStencilOp(stencilFail, depthFail, stencilPass);
906 checkGLcall("glStencilOp(...)");
907 } else {
908 glDisable(GL_STENCIL_TEST);
909 checkGLcall("glDisable GL_STENCIL_TEST");
910 }
911}
912
913static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
914{
915 DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0;
916
917 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
918 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
919 glStencilMask(mask);
920 checkGLcall("glStencilMask");
921 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
922 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
923 glStencilMask(mask);
924}
925
926static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
927{
928 DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0;
929
930 glStencilMask(mask);
931 checkGLcall("glStencilMask");
932}
933
934static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
935{
936
937 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
938
939 if (!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
940
941 /* Table fog on: Never use fog coords, and use per-fragment fog */
942 if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE) {
943 glHint(GL_FOG_HINT, GL_NICEST);
944 if(context->fog_coord) {
945 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
946 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
947 context->fog_coord = FALSE;
948 }
949 return;
950 }
951
952 /* Otherwise use per-vertex fog in any case */
953 glHint(GL_FOG_HINT, GL_FASTEST);
954
955 if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
956 /* No fog at all, or transformed vertices: Use fog coord */
957 if(!context->fog_coord) {
958 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
959 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
960 context->fog_coord = TRUE;
961 }
962 } else {
963 /* Otherwise, use the fragment depth */
964 if(context->fog_coord) {
965 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
966 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
967 context->fog_coord = FALSE;
968 }
969 }
970}
971
972void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
973{
974 float fogstart, fogend;
975 union {
976 DWORD d;
977 float f;
978 } tmpvalue;
979
980 switch(context->fog_source) {
981 case FOGSOURCE_VS:
982 fogstart = 1.0f;
983 fogend = 0.0f;
984 break;
985
986 case FOGSOURCE_COORD:
987 fogstart = 255.0f;
988 fogend = 0.0f;
989 break;
990
991 case FOGSOURCE_FFP:
992 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
993 fogstart = tmpvalue.f;
994 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
995 fogend = tmpvalue.f;
996 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
997 if(fogstart == fogend) {
998 unsigned long fNegInf = 0xff800000;
999 fogstart = *(float*)(&fNegInf); /* -1.0/0.0 */
1000 fogend = 0.0f;
1001 }
1002 break;
1003
1004 default:
1005 /* This should not happen.context->fog_source is set in wined3d, not the app.
1006 * Still this is needed to make the compiler happy
1007 */
1008 ERR("Unexpected fog coordinate source\n");
1009 fogstart = 0.0f;
1010 fogend = 0.0f;
1011 }
1012
1013 glFogf(GL_FOG_START, fogstart);
1014 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1015 TRACE("Fog Start == %f\n", fogstart);
1016
1017 glFogf(GL_FOG_END, fogend);
1018 checkGLcall("glFogf(GL_FOG_END, fogend)");
1019 TRACE("Fog End == %f\n", fogend);
1020}
1021
1022void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1023{
1024 enum fogsource new_source;
1025
1026 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
1027
1028 if (!stateblock->renderState[WINED3DRS_FOGENABLE]) {
1029 /* No fog? Disable it, and we're done :-) */
1030 glDisableWINE(GL_FOG);
1031 checkGLcall("glDisable GL_FOG");
1032 return;
1033 }
1034
1035 /* Fog Rules:
1036 *
1037 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1038 * It can use the Z value of the vertex, or the alpha component of the specular color.
1039 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1040 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1041 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1042 *
1043 * FOGTABLEMODE != NONE:
1044 * The Z value is used, with the equation specified, no matter what vertex type.
1045 *
1046 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1047 * Per vertex fog is calculated using the specified fog equation and the parameters
1048 *
1049 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1050 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1051 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1052 *
1053 *
1054 * Rules for vertex fog with shaders:
1055 *
1056 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1057 * the fog computation to happen during transformation while openGL expects it to happen
1058 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1059 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1060 * To solve this problem, WineD3D does:
1061 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1062 * shader,
1063 * and 2) disables the fog computation (in either the fixed function or programmable
1064 * rasterizer) if using a vertex program.
1065 *
1066 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1067 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1068 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1069 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1070 * There are some GL differences between specular fog coords and vertex shaders though.
1071 *
1072 * With table fog the vertex shader fog coordinate is ignored.
1073 *
1074 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1075 * without shaders).
1076 */
1077
1078 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1079 * the system will apply only pixel(=table) fog effects."
1080 */
1081 if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
1082 if(use_vs(stateblock)) {
1083 glFogi(GL_FOG_MODE, GL_LINEAR);
1084 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1085 new_source = FOGSOURCE_VS;
1086 } else {
1087 switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
1088 /* If processed vertices are used, fall through to the NONE case */
1089 case WINED3DFOG_EXP:
1090 if(!context->last_was_rhw) {
1091 glFogi(GL_FOG_MODE, GL_EXP);
1092 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1093 new_source = FOGSOURCE_FFP;
1094 break;
1095 }
1096 /* drop through */
1097
1098 case WINED3DFOG_EXP2:
1099 if(!context->last_was_rhw) {
1100 glFogi(GL_FOG_MODE, GL_EXP2);
1101 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1102 new_source = FOGSOURCE_FFP;
1103 break;
1104 }
1105 /* drop through */
1106
1107 case WINED3DFOG_LINEAR:
1108 if(!context->last_was_rhw) {
1109 glFogi(GL_FOG_MODE, GL_LINEAR);
1110 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1111 new_source = FOGSOURCE_FFP;
1112 break;
1113 }
1114 /* drop through */
1115
1116 case WINED3DFOG_NONE:
1117 /* Both are none? According to msdn the alpha channel of the specular
1118 * color contains a fog factor. Set it in drawStridedSlow.
1119 * Same happens with Vertexfog on transformed vertices
1120 */
1121 new_source = FOGSOURCE_COORD;
1122 glFogi(GL_FOG_MODE, GL_LINEAR);
1123 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1124 break;
1125
1126 default:
1127 FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
1128 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1129 }
1130 }
1131 } else {
1132 new_source = FOGSOURCE_FFP;
1133
1134 switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
1135 case WINED3DFOG_EXP:
1136 glFogi(GL_FOG_MODE, GL_EXP);
1137 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1138 break;
1139
1140 case WINED3DFOG_EXP2:
1141 glFogi(GL_FOG_MODE, GL_EXP2);
1142 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1143 break;
1144
1145 case WINED3DFOG_LINEAR:
1146 glFogi(GL_FOG_MODE, GL_LINEAR);
1147 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1148 break;
1149
1150 case WINED3DFOG_NONE: /* Won't happen */
1151 default:
1152 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
1153 }
1154 }
1155
1156 glEnableWINE(GL_FOG);
1157 checkGLcall("glEnable GL_FOG");
1158 if(new_source != context->fog_source) {
1159 context->fog_source = new_source;
1160 state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, context);
1161 }
1162}
1163
1164static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1165{
1166 if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
1167 WARN("Range fog enabled, but not supported by this opengl implementation\n");
1168 }
1169}
1170
1171static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1172{
1173 if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
1174 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1175 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1176 } else {
1177 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1178 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1179 }
1180}
1181
1182void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1183{
1184 float col[4];
1185 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
1186 glFogfv(GL_FOG_COLOR, &col[0]);
1187 checkGLcall("glFog GL_FOG_COLOR");
1188}
1189
1190void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1191{
1192 union {
1193 DWORD d;
1194 float f;
1195 } tmpvalue;
1196 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
1197 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1198 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1199}
1200
1201static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1202{
1203 IWineD3DDeviceImpl *device = stateblock->device;
1204 GLenum Parm = 0;
1205
1206 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1207 * The vertex declaration will call this function if the fixed function pipeline is used.
1208 */
1209
1210 if(isStateDirty(context, STATE_VDECL)) {
1211 return;
1212 }
1213
1214 context->num_untracked_materials = 0;
1215 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1216 && stateblock->renderState[WINED3DRS_COLORVERTEX])
1217 {
1218 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1219 stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
1220 stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
1221 stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
1222 stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
1223
1224 if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1225 if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1226 Parm = GL_AMBIENT_AND_DIFFUSE;
1227 } else {
1228 Parm = GL_DIFFUSE;
1229 }
1230 if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1231 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1232 context->num_untracked_materials++;
1233 }
1234 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1235 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1236 context->num_untracked_materials++;
1237 }
1238 } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1239 Parm = GL_AMBIENT;
1240 if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1241 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1242 context->num_untracked_materials++;
1243 }
1244 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1245 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1246 context->num_untracked_materials++;
1247 }
1248 } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1249 Parm = GL_EMISSION;
1250 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1251 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1252 context->num_untracked_materials++;
1253 }
1254 } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1255 Parm = GL_SPECULAR;
1256 }
1257 }
1258
1259 /* Nothing changed, return. */
1260 if (Parm == context->tracking_parm) return;
1261
1262 if(!Parm) {
1263 glDisable(GL_COLOR_MATERIAL);
1264 checkGLcall("glDisable GL_COLOR_MATERIAL");
1265 } else {
1266 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1267 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1268 glEnable(GL_COLOR_MATERIAL);
1269 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1270 }
1271
1272 /* Apparently calls to glMaterialfv are ignored for properties we're
1273 * tracking with glColorMaterial, so apply those here. */
1274 switch (context->tracking_parm) {
1275 case GL_AMBIENT_AND_DIFFUSE:
1276 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1277 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1278 checkGLcall("glMaterialfv");
1279 break;
1280
1281 case GL_DIFFUSE:
1282 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1283 checkGLcall("glMaterialfv");
1284 break;
1285
1286 case GL_AMBIENT:
1287 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1288 checkGLcall("glMaterialfv");
1289 break;
1290
1291 case GL_EMISSION:
1292 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
1293 checkGLcall("glMaterialfv");
1294 break;
1295
1296 case GL_SPECULAR:
1297 /* Only change material color if specular is enabled, otherwise it is set to black */
1298 if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
1299 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
1300 checkGLcall("glMaterialfv");
1301 } else {
1302 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1303 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1304 checkGLcall("glMaterialfv");
1305 }
1306 break;
1307 }
1308
1309 context->tracking_parm = Parm;
1310}
1311
1312static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1313{
1314 union {
1315 DWORD d;
1316 WINED3DLINEPATTERN lp;
1317 } tmppattern;
1318 tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
1319
1320 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1321
1322 if (tmppattern.lp.wRepeatFactor) {
1323 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1324 checkGLcall("glLineStipple(repeat, linepattern)");
1325 glEnable(GL_LINE_STIPPLE);
1326 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1327 } else {
1328 glDisable(GL_LINE_STIPPLE);
1329 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1330 }
1331}
1332
1333static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1334{
1335 union {
1336 DWORD d;
1337 float f;
1338 } tmpvalue;
1339
1340 if (stateblock->renderState[WINED3DRS_ZBIAS]) {
1341 tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
1342 TRACE("ZBias value %f\n", tmpvalue.f);
1343 glPolygonOffset(0, -tmpvalue.f);
1344 checkGLcall("glPolygonOffset(0, -Value)");
1345 glEnable(GL_POLYGON_OFFSET_FILL);
1346 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
1347 glEnable(GL_POLYGON_OFFSET_LINE);
1348 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
1349 glEnable(GL_POLYGON_OFFSET_POINT);
1350 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
1351 } else {
1352 glDisable(GL_POLYGON_OFFSET_FILL);
1353 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
1354 glDisable(GL_POLYGON_OFFSET_LINE);
1355 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
1356 glDisable(GL_POLYGON_OFFSET_POINT);
1357 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
1358 }
1359}
1360
1361
1362static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1363{
1364 if(isStateDirty(context, STATE_VDECL)) {
1365 return;
1366 }
1367 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1368 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1369 * by zero and is not properly defined in opengl, so avoid it
1370 */
1371 if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]
1372 && (stateblock->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1373 {
1374 glEnable(GL_NORMALIZE);
1375 checkGLcall("glEnable(GL_NORMALIZE);");
1376 } else {
1377 glDisable(GL_NORMALIZE);
1378 checkGLcall("glDisable(GL_NORMALIZE);");
1379 }
1380}
1381
1382static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1383{
1384 union {
1385 DWORD d;
1386 float f;
1387 } tmpvalue;
1388
1389 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1390 if (tmpvalue.f != 1.0f)
1391 {
1392 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1393 }
1394 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1395 if (tmpvalue.f != 64.0f)
1396 {
1397 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1398 }
1399
1400}
1401
1402static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1403{
1404 union {
1405 DWORD d;
1406 float f;
1407 } min, max;
1408
1409 min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1410 max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1411
1412 /* Max point size trumps min point size */
1413 if(min.f > max.f) {
1414 min.f = max.f;
1415 }
1416
1417 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1418 checkGLcall("glPointParameterfEXT(...)");
1419 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1420 checkGLcall("glPointParameterfEXT(...)");
1421}
1422
1423static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1424{
1425 union {
1426 DWORD d;
1427 float f;
1428 } min, max;
1429
1430 min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1431 max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1432
1433 /* Max point size trumps min point size */
1434 if(min.f > max.f) {
1435 min.f = max.f;
1436 }
1437
1438 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1439 checkGLcall("glPointParameterfARB(...)");
1440 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1441 checkGLcall("glPointParameterfARB(...)");
1442}
1443
1444static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1445{
1446 const struct wined3d_gl_info *gl_info = context->gl_info;
1447 /* TODO: Group this with the viewport */
1448 /*
1449 * POINTSCALEENABLE controls how point size value is treated. If set to
1450 * true, the point size is scaled with respect to height of viewport.
1451 * When set to false point size is in pixels.
1452 */
1453
1454 /* Default values */
1455 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1456 union {
1457 DWORD d;
1458 float f;
1459 } pointSize, A, B, C;
1460
1461 pointSize.d = stateblock->renderState[WINED3DRS_POINTSIZE];
1462 A.d = stateblock->renderState[WINED3DRS_POINTSCALE_A];
1463 B.d = stateblock->renderState[WINED3DRS_POINTSCALE_B];
1464 C.d = stateblock->renderState[WINED3DRS_POINTSCALE_C];
1465
1466 if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1467 GLfloat scaleFactor;
1468 float h = stateblock->viewport.Height;
1469
1470 if (pointSize.f < gl_info->limits.pointsize_min)
1471 {
1472 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1473 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1474 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1475 * are less than 1.0f. scale_factor = 1.0f / point_size.
1476 */
1477 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1478 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1479 * is 1.0, but then accepts points below that and draws too small points
1480 */
1481 pointSize.f = gl_info->limits.pointsize_min;
1482 }
1483 else if(pointSize.f > gl_info->limits.pointsize_max)
1484 {
1485 /* gl already scales the input to glPointSize,
1486 * d3d scales the result after the point size scale.
1487 * If the point size is bigger than the max size, use the
1488 * scaling to scale it bigger, and set the gl point size to max
1489 */
1490 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1491 TRACE("scale: %f\n", scaleFactor);
1492 pointSize.f = gl_info->limits.pointsize_max;
1493 } else {
1494 scaleFactor = 1.0f;
1495 }
1496 scaleFactor = pow(h * scaleFactor, 2);
1497
1498 att[0] = A.f / scaleFactor;
1499 att[1] = B.f / scaleFactor;
1500 att[2] = C.f / scaleFactor;
1501 }
1502
1503 if (gl_info->supported[ARB_POINT_PARAMETERS])
1504 {
1505 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1506 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1507 }
1508 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1509 {
1510 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1511 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1512 } else if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1513 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1514 }
1515
1516 glPointSize(pointSize.f);
1517 checkGLcall("glPointSize(...);");
1518}
1519
1520static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1521{
1522 WARN("token: %#x\n", stateblock->renderState[WINED3DRS_DEBUGMONITORTOKEN]);
1523}
1524
1525static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1526{
1527 DWORD mask0 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1528 DWORD mask1 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE1];
1529 DWORD mask2 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE2];
1530 DWORD mask3 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE3];
1531
1532 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1533 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1534 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1535 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1536 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1537 glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1538 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1539 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1540 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1541 checkGLcall("glColorMask(...)");
1542
1543 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1544 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1545 {
1546 FIXME("WINED3DRS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1547 mask0, mask1, mask2, mask3);
1548 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1549 }
1550}
1551
1552static void set_color_mask(struct wined3d_context *context, UINT index, DWORD mask)
1553{
1554 GL_EXTCALL(glColorMaskIndexedEXT(index,
1555 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1556 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1557 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1558 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1559}
1560
1561static void state_colorwrite0(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1562{
1563 set_color_mask(context, 0, stateblock->renderState[WINED3DRS_COLORWRITEENABLE]);
1564}
1565
1566static void state_colorwrite1(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1567{
1568 set_color_mask(context, 1, stateblock->renderState[WINED3DRS_COLORWRITEENABLE1]);
1569}
1570
1571static void state_colorwrite2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1572{
1573 set_color_mask(context, 2, stateblock->renderState[WINED3DRS_COLORWRITEENABLE2]);
1574}
1575
1576static void state_colorwrite3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1577{
1578 set_color_mask(context, 3, stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1579}
1580
1581static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1582{
1583 if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1584 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1585 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1586 } else {
1587 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1588 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1589 }
1590}
1591
1592static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1593{
1594 if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1595 TRACE("Last Pixel Drawing Enabled\n");
1596 } else {
1597 static BOOL warned;
1598 if (!warned) {
1599 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1600 warned = TRUE;
1601 } else {
1602 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1603 }
1604 }
1605}
1606
1607static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1608{
1609 static BOOL warned;
1610
1611 /* TODO: NV_POINT_SPRITE */
1612 if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1613 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1614 FIXME("Point sprites not supported\n");
1615 warned = TRUE;
1616 }
1617}
1618
1619static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1620{
1621 const struct wined3d_gl_info *gl_info = context->gl_info;
1622
1623 if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE])
1624 {
1625 static BOOL warned;
1626
1627 if (gl_info->limits.point_sprite_units < gl_info->limits.textures && !warned)
1628 {
1629 if (use_ps(stateblock) || stateblock->lowest_disabled_stage > gl_info->limits.point_sprite_units)
1630 {
1631 FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n");
1632 warned = TRUE;
1633 }
1634 }
1635
1636 glEnable(GL_POINT_SPRITE_ARB);
1637 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1638 } else {
1639 glDisable(GL_POINT_SPRITE_ARB);
1640 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1641 }
1642}
1643
1644static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1645{
1646 /**
1647 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1648 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1649 Discussion on the ways to turn on WRAPing to solve an OpenGL conversion problem.
1650 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1651
1652 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1653 */
1654 TRACE("Stub\n");
1655 if(stateblock->renderState[WINED3DRS_WRAP0] ||
1656 stateblock->renderState[WINED3DRS_WRAP1] ||
1657 stateblock->renderState[WINED3DRS_WRAP2] ||
1658 stateblock->renderState[WINED3DRS_WRAP3] ||
1659 stateblock->renderState[WINED3DRS_WRAP4] ||
1660 stateblock->renderState[WINED3DRS_WRAP5] ||
1661 stateblock->renderState[WINED3DRS_WRAP6] ||
1662 stateblock->renderState[WINED3DRS_WRAP7] ||
1663 stateblock->renderState[WINED3DRS_WRAP8] ||
1664 stateblock->renderState[WINED3DRS_WRAP9] ||
1665 stateblock->renderState[WINED3DRS_WRAP10] ||
1666 stateblock->renderState[WINED3DRS_WRAP11] ||
1667 stateblock->renderState[WINED3DRS_WRAP12] ||
1668 stateblock->renderState[WINED3DRS_WRAP13] ||
1669 stateblock->renderState[WINED3DRS_WRAP14] ||
1670 stateblock->renderState[WINED3DRS_WRAP15] ) {
1671 FIXME("(WINED3DRS_WRAP0) Texture wrapping not yet supported\n");
1672 }
1673}
1674
1675static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1676{
1677 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1678 WARN("Multisample antialiasing not supported by gl\n");
1679 }
1680}
1681
1682static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1683{
1684 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1685 glEnable(GL_MULTISAMPLE_ARB);
1686 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1687 } else {
1688 glDisable(GL_MULTISAMPLE_ARB);
1689 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1690 }
1691}
1692
1693static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1694{
1695 if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1696 glEnable(GL_SCISSOR_TEST);
1697 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1698 } else {
1699 glDisable(GL_SCISSOR_TEST);
1700 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1701 }
1702}
1703
1704/* The Direct3D depth bias is specified in normalized depth coordinates. In
1705 * OpenGL the bias is specified in units of "the smallest value that is
1706 * guaranteed to produce a resolvable offset for a given implementation". To
1707 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1708 * There's no practical way to retrieve that value from a given GL
1709 * implementation, but the D3D application has essentially the same problem,
1710 * which makes a guess of 1e-6f seem reasonable here. Note that
1711 * SLOPESCALEDEPTHBIAS is a scaling factor for the depth slope, and doesn't
1712 * need to be scaled. */
1713static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1714{
1715 if (stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS]
1716 || stateblock->renderState[WINED3DRS_DEPTHBIAS])
1717 {
1718 union
1719 {
1720 DWORD d;
1721 float f;
1722 } scale_bias, const_bias;
1723
1724 scale_bias.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1725 const_bias.d = stateblock->renderState[WINED3DRS_DEPTHBIAS];
1726
1727 glEnable(GL_POLYGON_OFFSET_FILL);
1728 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1729
1730 glPolygonOffset(scale_bias.f, const_bias.f * 1e6f);
1731 checkGLcall("glPolygonOffset(...)");
1732 } else {
1733 glDisable(GL_POLYGON_OFFSET_FILL);
1734 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1735 }
1736}
1737
1738static void state_zvisible(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1739{
1740 if (stateblock->renderState[WINED3DRS_ZVISIBLE])
1741 FIXME("WINED3DRS_ZVISIBLE not implemented.\n");
1742}
1743
1744static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1745{
1746 if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1747 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1748 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1749 } else {
1750 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1751 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1752 }
1753}
1754
1755static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1756{
1757 TRACE("Stub\n");
1758 if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1759 FIXME(" Stippled Alpha not supported yet.\n");
1760}
1761
1762static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1763{
1764 TRACE("Stub\n");
1765 if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1766 FIXME(" Antialias not supported yet.\n");
1767}
1768
1769static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1770{
1771 TRACE("Stub\n");
1772 if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1773 FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1774}
1775
1776static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1777{
1778 TRACE("Stub\n");
1779 if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1780 FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1781}
1782
1783static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1784{
1785 union {
1786 DWORD d;
1787 float f;
1788 } tmpvalue;
1789 tmpvalue.f = 1.0f;
1790
1791 TRACE("Stub\n");
1792 if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1793 {
1794 static BOOL displayed = FALSE;
1795
1796 tmpvalue.d = stateblock->renderState[WINED3DRS_PATCHSEGMENTS];
1797 if(!displayed)
1798 FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1799
1800 displayed = TRUE;
1801 }
1802}
1803
1804static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1805{
1806 TRACE("Stub\n");
1807 if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1808 FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1809}
1810
1811static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1812{
1813 TRACE("Stub\n");
1814 if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1815 FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1816}
1817
1818static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1819{
1820 TRACE("Stub\n");
1821 if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1822 FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1823}
1824
1825static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1826{
1827 if(stateblock->renderState[WINED3DRS_WRAPU]) {
1828 FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1829 }
1830}
1831
1832static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1833{
1834 if(stateblock->renderState[WINED3DRS_WRAPV]) {
1835 FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1836 }
1837}
1838
1839static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1840{
1841 if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1842 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1843 }
1844}
1845
1846static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1847{
1848 if(stateblock->renderState[WINED3DRS_ROP2]) {
1849 FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1850 }
1851}
1852
1853static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1854{
1855 if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1856 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1857 }
1858}
1859
1860static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1861{
1862 if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1863 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1864 }
1865}
1866
1867static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1868{
1869 if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1870 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1871 }
1872}
1873
1874static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1875{
1876 if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1877 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1878 }
1879}
1880
1881static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1882{
1883 if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1884 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1885 }
1886}
1887
1888static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1889{
1890 if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1891 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1892 }
1893}
1894
1895static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1896{
1897 if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1898 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1899 }
1900}
1901
1902static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1903{
1904 if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1905 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1906 }
1907}
1908
1909static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1910{
1911 if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1912 FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1913 }
1914}
1915
1916static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1917{
1918 if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1919 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1920 }
1921}
1922
1923static void state_swvp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1924{
1925 if (stateblock->renderState[WINED3DRS_SOFTWAREVERTEXPROCESSING])
1926 {
1927 FIXME("Software vertex processing not implemented.\n");
1928 }
1929}
1930
1931/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1932#if defined (GL_VERSION_1_3)
1933# define useext(A) A
1934#elif defined (GL_EXT_texture_env_combine)
1935# define useext(A) A##_EXT
1936#elif defined (GL_ARB_texture_env_combine)
1937# define useext(A) A##_ARB
1938#endif
1939
1940static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1941 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1942 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1943 * flag specifies the complement of the input should be used. */
1944 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1945 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1946
1947 /* Calculate the operand */
1948 if (complement) {
1949 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1950 else *operand = GL_ONE_MINUS_SRC_COLOR;
1951 } else {
1952 if (from_alpha) *operand = GL_SRC_ALPHA;
1953 else *operand = GL_SRC_COLOR;
1954 }
1955
1956 /* Calculate the source */
1957 switch (arg & WINED3DTA_SELECTMASK) {
1958 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1959 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1960 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1961 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1962 case WINED3DTA_SPECULAR:
1963 /*
1964 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1965 * 'Secondary color' and isn't supported until base GL supports it
1966 * There is no concept of temp registers as far as I can tell
1967 */
1968 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1969 *source = GL_TEXTURE;
1970 break;
1971 default:
1972 FIXME("Unrecognized texture arg %#x\n", arg);
1973 *source = GL_TEXTURE;
1974 break;
1975 }
1976}
1977
1978/* Setup the texture operations texture stage states */
1979static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *iface,
1980 BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1981{
1982 const struct wined3d_gl_info *gl_info = context->gl_info;
1983 GLenum src1, src2, src3;
1984 GLenum opr1, opr2, opr3;
1985 GLenum comb_target;
1986 GLenum src0_target, src1_target, src2_target;
1987 GLenum opr0_target, opr1_target, opr2_target;
1988 GLenum scal_target;
1989 GLenum opr=0, invopr, src3_target, opr3_target;
1990 BOOL Handled = FALSE;
1991 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1992
1993 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1994
1995 /* This is called by a state handler which has the gl lock held and a context for the thread */
1996
1997 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1998 the form (a1 <operation> a2). However, some of the more complex operations
1999 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2000 in a third parameter called a0. Therefore these are operations of the form
2001 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2002
2003 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2004 functions below, expect their syntax to differ slightly to those listed in the
2005 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2006 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2007
2008 if (isAlpha) {
2009 comb_target = useext(GL_COMBINE_ALPHA);
2010 src0_target = useext(GL_SOURCE0_ALPHA);
2011 src1_target = useext(GL_SOURCE1_ALPHA);
2012 src2_target = useext(GL_SOURCE2_ALPHA);
2013 opr0_target = useext(GL_OPERAND0_ALPHA);
2014 opr1_target = useext(GL_OPERAND1_ALPHA);
2015 opr2_target = useext(GL_OPERAND2_ALPHA);
2016 scal_target = GL_ALPHA_SCALE;
2017 }
2018 else {
2019 comb_target = useext(GL_COMBINE_RGB);
2020 src0_target = useext(GL_SOURCE0_RGB);
2021 src1_target = useext(GL_SOURCE1_RGB);
2022 src2_target = useext(GL_SOURCE2_RGB);
2023 opr0_target = useext(GL_OPERAND0_RGB);
2024 opr1_target = useext(GL_OPERAND1_RGB);
2025 opr2_target = useext(GL_OPERAND2_RGB);
2026 scal_target = useext(GL_RGB_SCALE);
2027 }
2028
2029 /* If a texture stage references an invalid texture unit the stage just
2030 * passes through the result from the previous stage */
2031 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
2032 arg1 = WINED3DTA_CURRENT;
2033 op = WINED3DTOP_SELECTARG1;
2034 }
2035
2036 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
2037 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2038 } else {
2039 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2040 }
2041 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2042 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2043
2044 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2045
2046 Handled = TRUE; /* Assume will be handled */
2047
2048 /* Other texture operations require special extensions: */
2049 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2050 {
2051 if (isAlpha) {
2052 opr = GL_SRC_ALPHA;
2053 invopr = GL_ONE_MINUS_SRC_ALPHA;
2054 src3_target = GL_SOURCE3_ALPHA_NV;
2055 opr3_target = GL_OPERAND3_ALPHA_NV;
2056 } else {
2057 opr = GL_SRC_COLOR;
2058 invopr = GL_ONE_MINUS_SRC_COLOR;
2059 src3_target = GL_SOURCE3_RGB_NV;
2060 opr3_target = GL_OPERAND3_RGB_NV;
2061 }
2062 switch (op) {
2063 case WINED3DTOP_DISABLE: /* Only for alpha */
2064 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2065 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2066 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2067 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2068 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2069 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2070 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2071 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2072 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2073 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2074 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2075 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2076 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2077 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2078 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2079 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2080 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2081 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2082 break;
2083 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
2084 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
2085 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2086 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2087 if (op == WINED3DTOP_SELECTARG1) {
2088 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2089 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2090 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2091 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2092 } else {
2093 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2094 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2095 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2096 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2097 }
2098 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2099 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2100 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2101 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2102 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2103 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2104 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2105 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2106 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2107 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2108 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2109 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2110 break;
2111
2112 case WINED3DTOP_MODULATE:
2113 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2114 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2115 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2116 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2117 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2118 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2119 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2120 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2121 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2122 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2123 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2124 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2125 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2126 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2127 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2128 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2129 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2130 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2131 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2132 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2133 break;
2134 case WINED3DTOP_MODULATE2X:
2135 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2136 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2137 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2138 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2139 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2140 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2141 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2142 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2143 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2144 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2145 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2146 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2147 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2148 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2149 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2150 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2151 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2152 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2153 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2154 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2155 break;
2156 case WINED3DTOP_MODULATE4X:
2157 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2158 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2159 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2160 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2161 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2162 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2163 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2164 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2165 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2166 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2167 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2168 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2169 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2170 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2171 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2172 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2173 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2174 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2175 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2176 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2177 break;
2178
2179 case WINED3DTOP_ADD:
2180 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2181 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2182 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2183 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2184 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2185 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2186 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2187 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2188 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2189 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2190 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2191 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2192 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2193 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2194 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2195 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2196 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2197 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2198 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2199 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2200 break;
2201
2202 case WINED3DTOP_ADDSIGNED:
2203 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2204 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2205 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2206 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2207 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2208 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2209 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2210 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2211 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2212 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2213 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2214 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2215 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2216 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2217 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2218 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2219 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2220 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2221 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2222 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2223 break;
2224
2225 case WINED3DTOP_ADDSIGNED2X:
2226 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2227 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2228 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2229 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2230 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2231 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2232 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2233 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2234 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2235 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2236 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2237 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2238 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2239 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2240 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2241 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2242 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2243 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2244 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2245 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2246 break;
2247
2248 case WINED3DTOP_ADDSMOOTH:
2249 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2250 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2251 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2252 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2253 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2254 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2255 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2256 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2257 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2258 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2259 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2260 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2261 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2262 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2263 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2264 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2265 switch (opr1) {
2266 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2267 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2268 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2269 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2270 }
2271 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2272 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2273 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2274 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2275 break;
2276
2277 case WINED3DTOP_BLENDDIFFUSEALPHA:
2278 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2279 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2280 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2281 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2282 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2283 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2284 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
2285 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
2286 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2287 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2288 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2289 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2290 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2291 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2292 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
2293 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
2294 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2295 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2296 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2297 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2298 break;
2299 case WINED3DTOP_BLENDTEXTUREALPHA:
2300 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2301 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2302 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2303 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2304 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2305 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2306 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2307 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2308 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2309 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2310 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2311 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2312 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2313 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2314 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2315 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2316 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2317 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2318 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2319 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2320 break;
2321 case WINED3DTOP_BLENDFACTORALPHA:
2322 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2323 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2324 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2325 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2326 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2327 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2328 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
2329 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
2330 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2331 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2332 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2333 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2334 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2335 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2336 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
2337 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
2338 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2339 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2340 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2341 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2342 break;
2343 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2344 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2345 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2346 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2347 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2348 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2349 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2350 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2351 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2352 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2353 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2354 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2355 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2356 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2357 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2358 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2359 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2360 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2361 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2362 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2363 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2364 break;
2365 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2366 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2367 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2368 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2369 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2370 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2371 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2372 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2373 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2374 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2375 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2376 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2377 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2378 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2379 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2380 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2381 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2382 switch (opr) {
2383 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2384 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2385 }
2386 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2387 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2388 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2389 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2390 break;
2391 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2392 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2393 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2394 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2395 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2396 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2397 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2398 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2399 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2400 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2401 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2402 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2403 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2404 switch (opr1) {
2405 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2406 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2407 }
2408 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2409 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2410 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2411 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2412 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2413 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2414 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2415 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2416 break;
2417 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2418 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2419 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2420 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2421 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2422 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2423 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2424 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2425 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2426 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2427 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2428 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2429 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2430 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2431 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2432 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2433 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2434 switch (opr1) {
2435 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2436 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2437 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2438 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2439 }
2440 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2441 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2442 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2443 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2444 break;
2445 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2446 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2447 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2448 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2449 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2450 switch (opr1) {
2451 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2452 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2453 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2454 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2455 }
2456 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2457 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2458 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2459 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2460 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2461 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2462 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2463 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2464 switch (opr1) {
2465 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2466 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2467 }
2468 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2469 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2470 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2471 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2472 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2473 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2474 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2475 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2476 break;
2477 case WINED3DTOP_MULTIPLYADD:
2478 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2479 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2480 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2481 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2482 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2483 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2484 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2485 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2486 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2487 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2488 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2489 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2490 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2491 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2492 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2493 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2494 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2495 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2496 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2497 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2498 break;
2499
2500 case WINED3DTOP_BUMPENVMAP:
2501 {
2502 }
2503
2504 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2505 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2506
2507 default:
2508 Handled = FALSE;
2509 }
2510 if (Handled) {
2511 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2512 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2513
2514 return;
2515 }
2516 } /* GL_NV_texture_env_combine4 */
2517
2518 Handled = TRUE; /* Again, assume handled */
2519 switch (op) {
2520 case WINED3DTOP_DISABLE: /* Only for alpha */
2521 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2522 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2523 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2524 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2525 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2526 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2527 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2528 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2529 break;
2530 case WINED3DTOP_SELECTARG1:
2531 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2532 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2533 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2534 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2535 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2536 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2537 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2538 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2539 break;
2540 case WINED3DTOP_SELECTARG2:
2541 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2542 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2543 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2544 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2545 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2546 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2547 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2548 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2549 break;
2550 case WINED3DTOP_MODULATE:
2551 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2552 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2553 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2554 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2555 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2556 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2557 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2558 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2559 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2560 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2561 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2562 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2563 break;
2564 case WINED3DTOP_MODULATE2X:
2565 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2566 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2567 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2568 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2569 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2570 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2571 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2572 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2573 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2574 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2575 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2576 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2577 break;
2578 case WINED3DTOP_MODULATE4X:
2579 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2580 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2581 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2582 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2583 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2584 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2585 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2586 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2587 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2588 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2589 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2590 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2591 break;
2592 case WINED3DTOP_ADD:
2593 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2594 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2595 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2596 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2597 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2598 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2599 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2600 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2601 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2602 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2603 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2604 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2605 break;
2606 case WINED3DTOP_ADDSIGNED:
2607 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2608 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2609 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2610 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2611 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2612 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2613 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2614 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2615 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2616 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2617 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2618 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2619 break;
2620 case WINED3DTOP_ADDSIGNED2X:
2621 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2622 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2623 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2624 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2625 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2626 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2627 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2628 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2629 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2630 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2631 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2632 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2633 break;
2634 case WINED3DTOP_SUBTRACT:
2635 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2636 {
2637 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2638 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2639 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2640 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2641 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2642 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2643 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2644 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2645 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2646 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2647 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2648 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2649 } else {
2650 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2651 }
2652 break;
2653
2654 case WINED3DTOP_BLENDDIFFUSEALPHA:
2655 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2656 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2657 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2658 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2659 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2660 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2661 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2662 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2663 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2664 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2665 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2666 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2667 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2668 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2669 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2670 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2671 break;
2672 case WINED3DTOP_BLENDTEXTUREALPHA:
2673 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2674 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2675 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2676 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2677 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2678 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2679 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2680 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2681 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2682 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2683 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2684 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2685 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2686 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2687 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2688 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2689 break;
2690 case WINED3DTOP_BLENDFACTORALPHA:
2691 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2692 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2693 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2694 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2695 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2696 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2697 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2698 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2699 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2700 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2701 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2702 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2703 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2704 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2705 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2706 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2707 break;
2708 case WINED3DTOP_BLENDCURRENTALPHA:
2709 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2710 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2711 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2712 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2713 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2714 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2715 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2716 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2717 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2718 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2719 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2720 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2721 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2722 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2723 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2724 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2725 break;
2726 case WINED3DTOP_DOTPRODUCT3:
2727 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2728 {
2729 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2730 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2731 }
2732 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2733 {
2734 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2735 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2736 } else {
2737 FIXME("This version of opengl does not support GL_DOT3\n");
2738 }
2739 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2740 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2741 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2742 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2743 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2744 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2745 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2746 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2747 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2748 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2749 break;
2750 case WINED3DTOP_LERP:
2751 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2752 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2753 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2754 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2755 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2756 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2757 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2758 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2759 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2760 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2761 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2762 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2763 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2764 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2765 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2766 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2767 break;
2768 case WINED3DTOP_ADDSMOOTH:
2769 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2770 {
2771 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2772 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2773 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2774 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2775 switch (opr1) {
2776 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2777 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2778 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2779 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2780 }
2781 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2782 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2783 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2784 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2785 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2786 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2787 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2788 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2789 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2790 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2791 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2792 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2793 } else
2794 Handled = FALSE;
2795 break;
2796 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2797 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2798 {
2799 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2800 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2801 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2802 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2803 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2804 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2805 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2806 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2807 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2808 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2809 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2810 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2811 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2812 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2813 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2814 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2815 } else
2816 Handled = FALSE;
2817 break;
2818 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2819 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2820 {
2821 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2822 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2823 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2824 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2825 switch (opr1) {
2826 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2827 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2828 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2829 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2830 }
2831 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2832 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2833 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2834 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2835 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2836 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2837 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2838 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2839 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2840 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2841 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2842 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2843 } else
2844 Handled = FALSE;
2845 break;
2846 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2847 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2848 {
2849 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2850 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2851 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2852 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2853 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2854 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2855 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2856 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2857 switch (opr1) {
2858 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2859 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2860 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2861 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2862 }
2863 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2864 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2865 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2866 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2867 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2868 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2869 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2870 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2871 } else
2872 Handled = FALSE;
2873 break;
2874 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2875 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2876 {
2877 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2878 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2879 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2880 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2881 switch (opr1) {
2882 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2883 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2884 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2885 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2886 }
2887 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2888 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2889 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2890 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2891 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2892 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2893 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2894 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2895 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2896 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2897 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2898 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2899 } else
2900 Handled = FALSE;
2901 break;
2902 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2903 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2904 {
2905 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2906 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2907 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2908 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2909 switch (opr1) {
2910 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2911 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2912 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2913 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2914 }
2915 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2916 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2917 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2918 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2919 switch (opr1) {
2920 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2921 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2922 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2923 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2924 }
2925 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2926 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2927 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2928 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2929 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2930 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2931 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2932 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2933 } else
2934 Handled = FALSE;
2935 break;
2936 case WINED3DTOP_MULTIPLYADD:
2937 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2938 {
2939 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2940 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2941 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2942 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2943 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2944 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2945 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
2946 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
2947 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
2948 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
2949 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2950 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2951 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2952 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2953 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2954 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2955 } else
2956 Handled = FALSE;
2957 break;
2958 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2959 case WINED3DTOP_BUMPENVMAP:
2960 if (gl_info->supported[NV_TEXTURE_SHADER2])
2961 {
2962 /* Technically texture shader support without register combiners is possible, but not expected to occur
2963 * on real world cards, so for now a fixme should be enough
2964 */
2965 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2966 }
2967 default:
2968 Handled = FALSE;
2969 }
2970
2971 if (Handled) {
2972 BOOL combineOK = TRUE;
2973 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2974 {
2975 DWORD op2;
2976
2977 if (isAlpha) {
2978 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2979 } else {
2980 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2981 }
2982
2983 /* Note: If COMBINE4 in effect can't go back to combine! */
2984 switch (op2) {
2985 case WINED3DTOP_ADDSMOOTH:
2986 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2987 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2988 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2989 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2990 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2991 case WINED3DTOP_MULTIPLYADD:
2992 /* Ignore those implemented in both cases */
2993 switch (op) {
2994 case WINED3DTOP_SELECTARG1:
2995 case WINED3DTOP_SELECTARG2:
2996 combineOK = FALSE;
2997 Handled = FALSE;
2998 break;
2999 default:
3000 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3001 return;
3002 }
3003 }
3004 }
3005
3006 if (combineOK) {
3007 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
3008 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
3009
3010 return;
3011 }
3012 }
3013
3014 /* After all the extensions, if still unhandled, report fixme */
3015 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3016}
3017
3018
3019static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3020{
3021 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3022 BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
3023 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3024 const struct wined3d_gl_info *gl_info = context->gl_info;
3025
3026 TRACE("Setting color op for stage %d\n", stage);
3027
3028 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3029 if (use_ps(stateblock)) return;
3030
3031 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3032
3033 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3034 {
3035 if (tex_used && mapped_stage >= gl_info->limits.textures)
3036 {
3037 FIXME("Attempt to enable unsupported stage!\n");
3038 return;
3039 }
3040 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3041 checkGLcall("glActiveTextureARB");
3042 }
3043
3044 if(stage >= stateblock->lowest_disabled_stage) {
3045 TRACE("Stage disabled\n");
3046 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3047 {
3048 /* Disable everything here */
3049 glDisable(GL_TEXTURE_2D);
3050 checkGLcall("glDisable(GL_TEXTURE_2D)");
3051 glDisable(GL_TEXTURE_3D);
3052 checkGLcall("glDisable(GL_TEXTURE_3D)");
3053 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3054 {
3055 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3056 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3057 }
3058 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3059 {
3060 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3061 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3062 }
3063 }
3064 /* All done */
3065 return;
3066 }
3067
3068 /* The sampler will also activate the correct texture dimensions, so no need to do it here
3069 * if the sampler for this stage is dirty
3070 */
3071 if(!isStateDirty(context, STATE_SAMPLER(stage))) {
3072 if (tex_used) texture_activate_dimensions(stage, stateblock, context);
3073 }
3074
3075 set_tex_op(context, (IWineD3DDevice *)stateblock->device, FALSE, stage,
3076 stateblock->textureState[stage][WINED3DTSS_COLOROP],
3077 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
3078 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
3079 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
3080}
3081
3082void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3083{
3084 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3085 BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
3086 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3087 const struct wined3d_gl_info *gl_info = context->gl_info;
3088 DWORD op, arg1, arg2, arg0;
3089
3090 TRACE("Setting alpha op for stage %d\n", stage);
3091 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3092 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3093 {
3094 if (tex_used && mapped_stage >= gl_info->limits.textures)
3095 {
3096 FIXME("Attempt to enable unsupported stage!\n");
3097 return;
3098 }
3099 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3100 checkGLcall("glActiveTextureARB");
3101 }
3102
3103 op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
3104 arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
3105 arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
3106 arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
3107
3108 if (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 && stateblock->textures[0])
3109 {
3110 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
3111
3112 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3113 {
3114 IWineD3DSurfaceImpl *surf;
3115
3116 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
3117
3118 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
3119 {
3120 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3121 * properly. On the other hand applications can still use texture combiners apparently. This code
3122 * takes care that apps cannot remove the texture's alpha channel entirely.
3123 *
3124 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3125 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3126 * and alpha component of diffuse color to draw things like translucent text and perform other
3127 * blending effects.
3128 *
3129 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3130 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3131 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3132 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3133 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3134 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3135 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3136 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3137 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3138 * alpha.
3139 *
3140 * What to do with multitexturing? So far no app has been found that uses color keying with
3141 * multitexturing */
3142 if (op == WINED3DTOP_DISABLE)
3143 {
3144 arg1 = WINED3DTA_TEXTURE;
3145 op = WINED3DTOP_SELECTARG1;
3146 }
3147 else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE)
3148 {
3149 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
3150 {
3151 arg2 = WINED3DTA_TEXTURE;
3152 op = WINED3DTOP_MODULATE;
3153 }
3154 else arg1 = WINED3DTA_TEXTURE;
3155 }
3156 else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE)
3157 {
3158 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
3159 {
3160 arg1 = WINED3DTA_TEXTURE;
3161 op = WINED3DTOP_MODULATE;
3162 }
3163 else arg2 = WINED3DTA_TEXTURE;
3164 }
3165 }
3166 }
3167 }
3168
3169 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3170 * this if block here, and the other code(color keying, texture unit selection) are the same
3171 */
3172 TRACE("Setting alpha op for stage %d\n", stage);
3173 if (gl_info->supported[NV_REGISTER_COMBINERS])
3174 {
3175 set_tex_op_nvrc((IWineD3DDevice *)stateblock->device, TRUE, stage, op, arg1, arg2, arg0,
3176 mapped_stage, stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
3177 }
3178 else
3179 {
3180 set_tex_op(context, (IWineD3DDevice *)stateblock->device, TRUE, stage, op, arg1, arg2, arg0);
3181 }
3182}
3183
3184static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3185{
3186 DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3187 DWORD mapped_stage = stateblock->device->texUnitMap[texUnit];
3188 BOOL generated;
3189 int coordIdx;
3190
3191 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3192 if (use_vs(stateblock) || isStateDirty(context, STATE_VDECL))
3193 {
3194 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3195 return;
3196 }
3197
3198 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3199 if (mapped_stage >= context->gl_info->limits.textures) return;
3200
3201 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3202 checkGLcall("glActiveTextureARB");
3203 generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU;
3204 coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1);
3205
3206 set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
3207 stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw,
3208 stateblock->device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3209 ? stateblock->device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format_desc->format
3210 : WINED3DFMT_UNKNOWN,
3211 stateblock->device->frag_pipe->ffp_proj_control);
3212
3213 /* The sampler applying function calls us if this changes */
3214 if ((context->lastWasPow2Texture & (1 << texUnit)) && stateblock->textures[texUnit])
3215 {
3216 if(generated) {
3217 FIXME("Non-power2 texture being used with generated texture coords\n");
3218 }
3219 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3220 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3221 if (!use_ps(stateblock)) {
3222 TRACE("Non power two matrix multiply fixup\n");
3223 glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
3224 }
3225 }
3226}
3227
3228static void unloadTexCoords(const struct wined3d_context *context)
3229{
3230 unsigned int texture_idx;
3231
3232 for (texture_idx = 0; texture_idx < context->gl_info->limits.texture_stages; ++texture_idx)
3233 {
3234 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3235 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3236 }
3237}
3238
3239static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
3240 const struct wined3d_stream_info *si, GLuint *curVBO)
3241{
3242 const struct wined3d_gl_info *gl_info = context->gl_info;
3243 const UINT *offset = stateblock->streamOffset;
3244 unsigned int mapped_stage = 0;
3245 unsigned int textureNo = 0;
3246
3247 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3248 {
3249 int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
3250
3251 mapped_stage = stateblock->device->texUnitMap[textureNo];
3252 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3253
3254 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3255 {
3256 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3257
3258 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
3259 textureNo, mapped_stage, coordIdx, e->data);
3260
3261 if (*curVBO != e->buffer_object)
3262 {
3263 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
3264 checkGLcall("glBindBufferARB");
3265 *curVBO = e->buffer_object;
3266 }
3267
3268 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3269 checkGLcall("glClientActiveTextureARB");
3270
3271 /* The coords to supply depend completely on the fvf / vertex shader */
3272 glTexCoordPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
3273 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
3274 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3275 } else {
3276 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3277 }
3278 }
3279 if (gl_info->supported[NV_REGISTER_COMBINERS])
3280 {
3281 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3282 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3283 {
3284 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3285 }
3286 }
3287
3288 checkGLcall("loadTexCoords");
3289}
3290
3291static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3292{
3293 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3294 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3295 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3296 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3297 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3298 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3299 const struct wined3d_gl_info *gl_info = context->gl_info;
3300
3301 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3302 {
3303 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3304 return;
3305 }
3306
3307 if (mapped_stage >= gl_info->limits.fragment_samplers)
3308 {
3309 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3310 return;
3311 }
3312 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3313 checkGLcall("glActiveTextureARB");
3314
3315 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3316 *
3317 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3318 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3319 * means use the vertex position (camera-space) as the input texture coordinates
3320 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
3321 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3322 * to the TEXCOORDINDEX value
3323 */
3324 switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000)
3325 {
3326 case WINED3DTSS_TCI_PASSTHRU:
3327 /* Use the specified texture coordinates contained within the
3328 * vertex format. This value resolves to zero. */
3329 glDisable(GL_TEXTURE_GEN_S);
3330 glDisable(GL_TEXTURE_GEN_T);
3331 glDisable(GL_TEXTURE_GEN_R);
3332 glDisable(GL_TEXTURE_GEN_Q);
3333 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3334 break;
3335
3336 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3337 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3338 * as the input texture coordinates for this stage's texture transformation. This
3339 * equates roughly to EYE_LINEAR */
3340
3341 glMatrixMode(GL_MODELVIEW);
3342 glPushMatrix();
3343 glLoadIdentity();
3344 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3345 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3346 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3347 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3348 glPopMatrix();
3349 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3350
3351 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3352 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3353 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3354 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3355
3356 glEnable(GL_TEXTURE_GEN_S);
3357 glEnable(GL_TEXTURE_GEN_T);
3358 glEnable(GL_TEXTURE_GEN_R);
3359 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3360
3361 break;
3362
3363 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3364 /* Note that NV_TEXGEN_REFLECTION support is implied when
3365 * ARB_TEXTURE_CUBE_MAP is supported */
3366 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3367 {
3368 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3369 break;
3370 }
3371
3372 glMatrixMode(GL_MODELVIEW);
3373 glPushMatrix();
3374 glLoadIdentity();
3375 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3376 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3377 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3378 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3379 glPopMatrix();
3380 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3381
3382 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3383 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3384 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3385 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3386
3387 glEnable(GL_TEXTURE_GEN_S);
3388 glEnable(GL_TEXTURE_GEN_T);
3389 glEnable(GL_TEXTURE_GEN_R);
3390 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3391
3392 break;
3393
3394 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3395 /* Note that NV_TEXGEN_REFLECTION support is implied when
3396 * ARB_TEXTURE_CUBE_MAP is supported */
3397 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3398 {
3399 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3400 break;
3401 }
3402
3403 glMatrixMode(GL_MODELVIEW);
3404 glPushMatrix();
3405 glLoadIdentity();
3406 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3407 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3408 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3409 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3410 glPopMatrix();
3411 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3412
3413 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3414 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3415 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3416 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3417
3418 glEnable(GL_TEXTURE_GEN_S);
3419 glEnable(GL_TEXTURE_GEN_T);
3420 glEnable(GL_TEXTURE_GEN_R);
3421 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3422
3423 break;
3424
3425 case WINED3DTSS_TCI_SPHEREMAP:
3426 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3427 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3428 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3429
3430 glEnable(GL_TEXTURE_GEN_S);
3431 glEnable(GL_TEXTURE_GEN_T);
3432 glDisable(GL_TEXTURE_GEN_R);
3433 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3434
3435 break;
3436
3437 default:
3438 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %#x\n",
3439 stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
3440 glDisable(GL_TEXTURE_GEN_S);
3441 glDisable(GL_TEXTURE_GEN_T);
3442 glDisable(GL_TEXTURE_GEN_R);
3443 glDisable(GL_TEXTURE_GEN_Q);
3444 checkGLcall("Disable texgen.");
3445
3446 break;
3447 }
3448
3449 /* Update the texture matrix */
3450 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
3451 transform_texture(STATE_TEXTURESTAGE(stage, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3452 }
3453
3454 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
3455 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3456 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3457 * and do all the things linked to it
3458 * TODO: Tidy that up to reload only the arrays of the changed unit
3459 */
3460 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3461
3462 unloadTexCoords(context);
3463 loadTexCoords(context, stateblock, &stateblock->device->strided_streams, &curVBO);
3464 }
3465}
3466
3467static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3468{
3469 IWineD3DDeviceImpl *device = stateblock->device;
3470
3471 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
3472 * has an update pending
3473 */
3474 if(isStateDirty(context, STATE_VDECL) ||
3475 isStateDirty(context, STATE_PIXELSHADER)) {
3476 return;
3477 }
3478
3479 device->shader_backend->shader_load_constants(context, use_ps(stateblock), use_vs(stateblock));
3480}
3481
3482static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3483{
3484 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3485
3486 if (stateblock->pixelShader && stage != 0
3487 && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.luminanceparams & (1 << stage)))
3488 {
3489 /* The pixel shader has to know the luminance scale. Do a constants update if it
3490 * isn't scheduled anyway
3491 */
3492 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3493 !isStateDirty(context, STATE_PIXELSHADER)) {
3494 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3495 }
3496 }
3497}
3498
3499static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3500{
3501 const DWORD sampler = state - STATE_SAMPLER(0);
3502 IWineD3DBaseTexture *texture = stateblock->textures[sampler];
3503
3504 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
3505
3506 if(!texture) return;
3507 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3508 * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3509 * scaling is reapplied or removed, the texture matrix has to be reapplied
3510 *
3511 * The mapped stage is already active because the sampler() function below, which is part of the
3512 * misc pipeline
3513 */
3514 if(sampler < MAX_TEXTURES) {
3515 const BOOL texIsPow2 = !((IWineD3DBaseTextureImpl *)texture)->baseTexture.pow2Matrix_identity;
3516
3517 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3518 {
3519 if (texIsPow2) context->lastWasPow2Texture |= 1 << sampler;
3520 else context->lastWasPow2Texture &= ~(1 << sampler);
3521 transform_texture(STATE_TEXTURESTAGE(stateblock->device->texUnitMap[sampler],
3522 WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3523 }
3524 }
3525}
3526
3527static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3528{
3529 DWORD sampler = state - STATE_SAMPLER(0);
3530 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3531 const struct wined3d_gl_info *gl_info = context->gl_info;
3532 union {
3533 float f;
3534 DWORD d;
3535 } tmpvalue;
3536
3537 TRACE("Sampler: %d\n", sampler);
3538 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3539 * only has to bind textures and set the per texture states
3540 */
3541
3542 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3543 {
3544 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3545 return;
3546 }
3547
3548 if (mapped_stage >= gl_info->limits.combined_samplers)
3549 {
3550 return;
3551 }
3552 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3553 checkGLcall("glActiveTextureARB");
3554
3555 if(stateblock->textures[sampler]) {
3556 BOOL srgb = stateblock->samplerState[sampler][WINED3DSAMP_SRGBTEXTURE];
3557 IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
3558 IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb);
3559 basetexture_apply_state_changes(stateblock->textures[sampler],
3560 stateblock->textureState[sampler], stateblock->samplerState[sampler], gl_info);
3561
3562 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3563 {
3564 tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
3565 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3566 GL_TEXTURE_LOD_BIAS_EXT,
3567 tmpvalue.f);
3568 checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3569 }
3570
3571 if (!use_ps(stateblock) && sampler < stateblock->lowest_disabled_stage)
3572 {
3573 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
3574 /* If color keying is enabled update the alpha test, it depends on the existence
3575 * of a color key in stage 0
3576 */
3577 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3578 }
3579 }
3580
3581 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3582 if (!tex_impl->baseTexture.pow2Matrix_identity)
3583 {
3584 IWineD3DDeviceImpl *d3ddevice = stateblock->device;
3585 d3ddevice->shader_backend->shader_load_np2fixup_constants(
3586 (IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock));
3587 }
3588 }
3589 else if (mapped_stage < gl_info->limits.textures)
3590 {
3591 if(sampler < stateblock->lowest_disabled_stage) {
3592 /* TODO: What should I do with pixel shaders here ??? */
3593 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
3594 /* If color keying is enabled update the alpha test, it depends on the existence
3595 * of a color key in stage 0
3596 */
3597 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3598 }
3599 } /* Otherwise tex_colorop disables the stage */
3600 glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler]);
3601 checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler])");
3602 }
3603}
3604
3605void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3606{
3607 IWineD3DDeviceImpl *device = stateblock->device;
3608 BOOL use_pshader = use_ps(stateblock);
3609 BOOL use_vshader = use_vs(stateblock);
3610 int i;
3611
3612 if (use_pshader) {
3613 if(!context->last_was_pshader) {
3614 /* Former draw without a pixel shader, some samplers
3615 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
3616 * make sure to enable them
3617 */
3618 for(i=0; i < MAX_FRAGMENT_SAMPLERS; i++) {
3619 if(!isStateDirty(context, STATE_SAMPLER(i))) {
3620 sampler(STATE_SAMPLER(i), stateblock, context);
3621 }
3622 }
3623 context->last_was_pshader = TRUE;
3624 } else {
3625 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
3626 * if a different texture was bound. I don't have to do anything.
3627 */
3628 }
3629 } else {
3630 /* Disabled the pixel shader - color ops weren't applied
3631 * while it was enabled, so re-apply them. */
3632 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3633 {
3634 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)))
3635 stateblock_apply_state(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
3636 }
3637 context->last_was_pshader = FALSE;
3638 }
3639
3640 if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
3641 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3642
3643 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
3644 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3645 }
3646 }
3647}
3648
3649static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3650{
3651 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3652 if (stateblock->pixelShader && stage != 0
3653 && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.bumpmat & (1 << stage)))
3654 {
3655 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
3656 * anyway
3657 */
3658 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3659 !isStateDirty(context, STATE_PIXELSHADER)) {
3660 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3661 }
3662 }
3663}
3664
3665static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3666{
3667 /* This function is called by transform_view below if the view matrix was changed too
3668 *
3669 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3670 * does not always update the world matrix, only on a switch between transformed
3671 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3672 * draw, but that should be rather rare and cheaper in total.
3673 */
3674 glMatrixMode(GL_MODELVIEW);
3675 checkGLcall("glMatrixMode");
3676
3677 if(context->last_was_rhw) {
3678 glLoadIdentity();
3679 checkGLcall("glLoadIdentity()");
3680 } else {
3681 /* In the general case, the view matrix is the identity matrix */
3682 if (stateblock->device->view_ident)
3683 {
3684 glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3685 checkGLcall("glLoadMatrixf");
3686 }
3687 else
3688 {
3689 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3690 checkGLcall("glLoadMatrixf");
3691 glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3692 checkGLcall("glMultMatrixf");
3693 }
3694 }
3695}
3696
3697static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3698{
3699 UINT index = state - STATE_CLIPPLANE(0);
3700
3701 if (isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= context->gl_info->limits.clipplanes)
3702 {
3703 return;
3704 }
3705
3706 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3707 if(!use_vs(stateblock)) {
3708 glMatrixMode(GL_MODELVIEW);
3709 glPushMatrix();
3710 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3711 } else {
3712 /* with vertex shaders, clip planes are not transformed in direct3d,
3713 * in OpenGL they are still transformed by the model view.
3714 * Use this to swap the y coordinate if necessary
3715 */
3716 glMatrixMode(GL_MODELVIEW);
3717 glPushMatrix();
3718 glLoadIdentity();
3719 if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f);
3720 }
3721
3722 TRACE("Clipplane [%f,%f,%f,%f]\n",
3723 stateblock->clipplane[index][0],
3724 stateblock->clipplane[index][1],
3725 stateblock->clipplane[index][2],
3726 stateblock->clipplane[index][3]);
3727 glClipPlane(GL_CLIP_PLANE0 + index, stateblock->clipplane[index]);
3728 checkGLcall("glClipPlane");
3729
3730 glPopMatrix();
3731}
3732
3733static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3734{
3735 UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
3736 GLenum glMat;
3737 TRACE("Setting world matrix %d\n", matrix);
3738
3739 if (matrix >= context->gl_info->limits.blends)
3740 {
3741 WARN("Unsupported blend matrix set\n");
3742 return;
3743 } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3744 return;
3745 }
3746
3747 /* GL_MODELVIEW0_ARB: 0x1700
3748 * GL_MODELVIEW1_ARB: 0x850a
3749 * GL_MODELVIEW2_ARB: 0x8722
3750 * GL_MODELVIEW3_ARB: 0x8723
3751 * etc
3752 * GL_MODELVIEW31_ARB: 0x873F
3753 */
3754 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3755 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3756
3757 glMatrixMode(glMat);
3758 checkGLcall("glMatrixMode(glMat)");
3759
3760 /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
3761 * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
3762 */
3763 if (stateblock->device->view_ident)
3764 {
3765 glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3766 checkGLcall("glLoadMatrixf");
3767 }
3768 else
3769 {
3770 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3771 checkGLcall("glLoadMatrixf");
3772 glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3773 checkGLcall("glMultMatrixf");
3774 }
3775}
3776
3777static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3778{
3779 WINED3DVERTEXBLENDFLAGS f = stateblock->renderState[WINED3DRS_VERTEXBLEND];
3780 static unsigned int once;
3781
3782 if (f == WINED3DVBF_DISABLE) return;
3783
3784 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3785 else WARN("Vertex blend flags %#x not supported.\n", f);
3786}
3787
3788static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3789{
3790 WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
3791 static unsigned int once;
3792
3793 switch(val) {
3794 case WINED3DVBF_1WEIGHTS:
3795 case WINED3DVBF_2WEIGHTS:
3796 case WINED3DVBF_3WEIGHTS:
3797 glEnable(GL_VERTEX_BLEND_ARB);
3798 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3799
3800 /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
3801 * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
3802 */
3803 GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1));
3804
3805 if (!stateblock->device->vertexBlendUsed)
3806 {
3807 unsigned int i;
3808 for (i = 1; i < context->gl_info->limits.blends; ++i)
3809 {
3810 if (!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i))))
3811 {
3812 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
3813 }
3814 }
3815 stateblock->device->vertexBlendUsed = TRUE;
3816 }
3817 break;
3818
3819 case WINED3DVBF_TWEENING:
3820 case WINED3DVBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3821 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3822 else WARN("Vertex blend flags %#x not supported.\n", val);
3823 /* Fall through. */
3824 case WINED3DVBF_DISABLE:
3825 glDisable(GL_VERTEX_BLEND_ARB);
3826 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3827 break;
3828 }
3829}
3830
3831static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3832{
3833 const struct wined3d_gl_info *gl_info = context->gl_info;
3834 const struct wined3d_light_info *light = NULL;
3835 unsigned int k;
3836
3837 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3838 * NOTE: We have to reset the positions even if the light/plane is not currently
3839 * enabled, since the call to enable it will not reset the position.
3840 * NOTE2: Apparently texture transforms do NOT need reapplying
3841 */
3842
3843 glMatrixMode(GL_MODELVIEW);
3844 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3845 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3846 checkGLcall("glLoadMatrixf(...)");
3847
3848 /* Reset lights. TODO: Call light apply func */
3849 for (k = 0; k < stateblock->device->maxConcurrentLights; ++k)
3850 {
3851 light = stateblock->activeLights[k];
3852 if(!light) continue;
3853 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3854 checkGLcall("glLightfv posn");
3855 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3856 checkGLcall("glLightfv dirn");
3857 }
3858
3859 /* Reset Clipping Planes */
3860 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3861 {
3862 if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
3863 clipplane(STATE_CLIPPLANE(k), stateblock, context);
3864 }
3865 }
3866
3867 if(context->last_was_rhw) {
3868 glLoadIdentity();
3869 checkGLcall("glLoadIdentity()");
3870 /* No need to update the world matrix, the identity is fine */
3871 return;
3872 }
3873
3874 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3875 * No need to do it here if the state is scheduled for update.
3876 */
3877 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
3878 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3879 }
3880
3881 /* Avoid looping over a number of matrices if the app never used the functionality */
3882 if (stateblock->device->vertexBlendUsed)
3883 {
3884 for (k = 1; k < gl_info->limits.blends; ++k)
3885 {
3886 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
3887 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
3888 }
3889 }
3890 }
3891}
3892
3893static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3894{
3895 glMatrixMode(GL_PROJECTION);
3896 checkGLcall("glMatrixMode(GL_PROJECTION)");
3897 glLoadIdentity();
3898 checkGLcall("glLoadIdentity");
3899
3900 if (context->last_was_rhw)
3901 {
3902 double x = stateblock->viewport.X;
3903 double y = stateblock->viewport.Y;
3904 double w = stateblock->viewport.Width;
3905 double h = stateblock->viewport.Height;
3906
3907 TRACE("Calling glOrtho with x %.8e, y %.8e, w %.8e, h %.8e.\n", x, y, w, h);
3908 if (context->render_offscreen)
3909 glOrtho(x, x + w, -y, -y - h, 0.0, -1.0);
3910 else
3911 glOrtho(x, x + w, y + h, y, 0.0, -1.0);
3912 checkGLcall("glOrtho");
3913
3914 /* D3D texture coordinates are flipped compared to OpenGL ones, so
3915 * render everything upside down when rendering offscreen. */
3916 if (context->render_offscreen)
3917 {
3918 /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
3919 glTranslatef(63.0f / 128.0f, -63.0f / 128.0f, 0.0f);
3920 checkGLcall("glTranslatef(63.0f / 128.0f, -63.0f / 128.0f, 0.0f)");
3921 glScalef(1.0f, -1.0f, 1.0f);
3922 checkGLcall("glScalef");
3923 }
3924 else
3925 {
3926 /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
3927 glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f);
3928 checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)");
3929 }
3930 } else {
3931 /* The rule is that the window coordinate 0 does not correspond to the
3932 beginning of the first pixel, but the center of the first pixel.
3933 As a consequence if you want to correctly draw one line exactly from
3934 the left to the right end of the viewport (with all matrices set to
3935 be identity), the x coords of both ends of the line would be not
3936 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
3937 instead.
3938
3939 1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
3940 divide by the Width/Height, so we need the half range(1.0) to translate by
3941 half a pixel.
3942
3943 The other fun is that d3d's output z range after the transformation is [0;1],
3944 but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
3945 scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
3946 of Z buffer precision and the clear values do not match in the z test. Thus scale
3947 [0;1] to [-1;1], so when gl undoes that we utilize the full z range
3948 */
3949
3950 /*
3951 * Careful with the order of operations here, we're essentially working backwards:
3952 * x = x + 1/w;
3953 * y = (y - 1/h) * flip;
3954 * z = z * 2 - 1;
3955 *
3956 * Becomes:
3957 * glTranslatef(0.0, 0.0, -1.0);
3958 * glScalef(1.0, 1.0, 2.0);
3959 *
3960 * glScalef(1.0, flip, 1.0);
3961 * glTranslatef(1/w, -1/h, 0.0);
3962 *
3963 * This is equivalent to:
3964 * glTranslatef(1/w, -flip/h, -1.0)
3965 * glScalef(1.0, flip, 2.0);
3966 */
3967
3968 /* Translate by slightly less than a half pixel to force a top-left
3969 * filling convention. We want the difference to be large enough that
3970 * it doesn't get lost due to rounding inside the driver, but small
3971 * enough to prevent it from interfering with any anti-aliasing. */
3972 GLfloat xoffset = (63.0f / 64.0f) / stateblock->viewport.Width;
3973 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
3974
3975 if (context->render_offscreen)
3976 {
3977 /* D3D texture coordinates are flipped compared to OpenGL ones, so
3978 * render everything upside down when rendering offscreen. */
3979 glTranslatef(xoffset, -yoffset, -1.0f);
3980 checkGLcall("glTranslatef(xoffset, -yoffset, -1.0f)");
3981 glScalef(1.0f, -1.0f, 2.0f);
3982 } else {
3983 glTranslatef(xoffset, yoffset, -1.0f);
3984 checkGLcall("glTranslatef(xoffset, yoffset, -1.0f)");
3985 glScalef(1.0f, 1.0f, 2.0f);
3986 }
3987 checkGLcall("glScalef");
3988
3989 glMultMatrixf(&stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
3990 checkGLcall("glLoadMatrixf");
3991 }
3992}
3993
3994/* This should match any arrays loaded in loadVertexData.
3995 * TODO: Only load / unload arrays if we have to.
3996 */
3997static inline void unloadVertexData(const struct wined3d_context *context)
3998{
3999 const struct wined3d_gl_info *gl_info = context->gl_info;
4000
4001 glDisableClientState(GL_VERTEX_ARRAY);
4002 glDisableClientState(GL_NORMAL_ARRAY);
4003 glDisableClientState(GL_COLOR_ARRAY);
4004 if (gl_info->supported[EXT_SECONDARY_COLOR])
4005 {
4006 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4007 }
4008 if (gl_info->supported[ARB_VERTEX_BLEND])
4009 {
4010 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4011 }
4012 unloadTexCoords(context);
4013}
4014
4015static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i)
4016{
4017 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4018 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4019
4020 context->numbered_array_mask &= ~(1 << i);
4021}
4022
4023/* This should match any arrays loaded in loadNumberedArrays
4024 * TODO: Only load / unload arrays if we have to.
4025 */
4026static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4027{
4028 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4029 GLint maxAttribs = 16;
4030 int i;
4031
4032 /* Leave all the attribs disabled */
4033 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
4034 /* MESA does not support it right not */
4035 if (glGetError() != GL_NO_ERROR)
4036 maxAttribs = 16;
4037 for (i = 0; i < maxAttribs; ++i) {
4038 unload_numbered_array(stateblock, context, i);
4039 }
4040}
4041
4042static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
4043 const struct wined3d_stream_info *stream_info, struct wined3d_context *context)
4044{
4045 const struct wined3d_gl_info *gl_info = context->gl_info;
4046 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4047 int i;
4048 const UINT *offset = stateblock->streamOffset;
4049 struct wined3d_buffer *vb;
4050 DWORD_PTR shift_index;
4051
4052 /* Default to no instancing */
4053 stateblock->device->instancedDraw = FALSE;
4054
4055 for (i = 0; i < MAX_ATTRIBS; i++) {
4056 if (!(stream_info->use_map & (1 << i)))
4057 {
4058 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
4059 continue;
4060 }
4061
4062 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4063 if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA)
4064 {
4065 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
4066 stateblock->device->instancedDraw = TRUE;
4067 continue;
4068 }
4069
4070 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].buffer_object);
4071
4072 if (stream_info->elements[i].stride)
4073 {
4074 if (curVBO != stream_info->elements[i].buffer_object)
4075 {
4076 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].buffer_object));
4077 checkGLcall("glBindBufferARB");
4078 curVBO = stream_info->elements[i].buffer_object;
4079 }
4080 vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
4081 /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a
4082 * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no
4083 * vbo we won't be load converted attributes anyway
4084 */
4085 if (curVBO && vb->conversion_shift)
4086 {
4087 TRACE("Loading attribute from shifted buffer\n");
4088 TRACE("Attrib %d has original stride %d, new stride %d\n",
4089 i, stream_info->elements[i].stride, vb->conversion_stride);
4090 TRACE("Original offset %p, additional offset 0x%08x\n",
4091 stream_info->elements[i].data, vb->conversion_shift[(DWORD_PTR)stream_info->elements[i].data]);
4092 TRACE("Opengl type %#x\n", stream_info->elements[i].format_desc->gl_vtx_type);
4093 shift_index = ((DWORD_PTR)stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx]);
4094 shift_index = shift_index % stream_info->elements[i].stride;
4095 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format_desc->gl_vtx_format,
4096 stream_info->elements[i].format_desc->gl_vtx_type,
4097 stream_info->elements[i].format_desc->gl_normalized,
4098 vb->conversion_stride, stream_info->elements[i].data + vb->conversion_shift[shift_index]
4099 + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride
4100 + offset[stream_info->elements[i].stream_idx]));
4101
4102 } else {
4103 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format_desc->gl_vtx_format,
4104 stream_info->elements[i].format_desc->gl_vtx_type,
4105 stream_info->elements[i].format_desc->gl_normalized,
4106 stream_info->elements[i].stride, stream_info->elements[i].data
4107 + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride
4108 + offset[stream_info->elements[i].stream_idx]));
4109 }
4110
4111 if (!(context->numbered_array_mask & (1 << i)))
4112 {
4113 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4114 context->numbered_array_mask |= (1 << i);
4115 }
4116 } else {
4117 /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
4118 * set up the attribute statically. But we have to figure out the system memory address.
4119 */
4120 const BYTE *ptr = stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx];
4121 if (stream_info->elements[i].buffer_object)
4122 {
4123 vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
4124 ptr += (long) buffer_get_sysmem(vb);
4125 }
4126
4127 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
4128
4129 switch (stream_info->elements[i].format_desc->format)
4130 {
4131 case WINED3DFMT_R32_FLOAT:
4132 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4133 break;
4134 case WINED3DFMT_R32G32_FLOAT:
4135 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4136 break;
4137 case WINED3DFMT_R32G32B32_FLOAT:
4138 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4139 break;
4140 case WINED3DFMT_R32G32B32A32_FLOAT:
4141 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4142 break;
4143
4144 case WINED3DFMT_R8G8B8A8_UINT:
4145 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4146 break;
4147 case WINED3DFMT_B8G8R8A8_UNORM:
4148 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4149 {
4150 const DWORD *src = (const DWORD *)ptr;
4151 DWORD c = *src & 0xff00ff00;
4152 c |= (*src & 0xff0000) >> 16;
4153 c |= (*src & 0xff) << 16;
4154 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4155 break;
4156 }
4157 /* else fallthrough */
4158 case WINED3DFMT_R8G8B8A8_UNORM:
4159 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4160 break;
4161
4162 case WINED3DFMT_R16G16_SINT:
4163 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4164 break;
4165 case WINED3DFMT_R16G16B16A16_SINT:
4166 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4167 break;
4168
4169 case WINED3DFMT_R16G16_SNORM:
4170 {
4171 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4172 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4173 break;
4174 }
4175 case WINED3DFMT_R16G16_UNORM:
4176 {
4177 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4178 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4179 break;
4180 }
4181 case WINED3DFMT_R16G16B16A16_SNORM:
4182 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4183 break;
4184 case WINED3DFMT_R16G16B16A16_UNORM:
4185 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4186 break;
4187
4188 case WINED3DFMT_R10G10B10A2_UINT:
4189 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4190 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4191 break;
4192 case WINED3DFMT_R10G10B10A2_SNORM:
4193 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4194 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4195 break;
4196
4197 case WINED3DFMT_R16G16_FLOAT:
4198 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4199 * byte float according to the IEEE standard
4200 */
4201 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4202 break;
4203 case WINED3DFMT_R16G16B16A16_FLOAT:
4204 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4205 break;
4206
4207 default:
4208 ERR("Unexpected declaration in stride 0 attributes\n");
4209 break;
4210
4211 }
4212 }
4213 }
4214 checkGLcall("Loading numbered arrays");
4215}
4216
4217/* Used from 2 different functions, and too big to justify making it inlined */
4218static void loadVertexData(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
4219 const struct wined3d_stream_info *si)
4220{
4221 const struct wined3d_gl_info *gl_info = context->gl_info;
4222 const UINT *offset = stateblock->streamOffset;
4223 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4224 const struct wined3d_stream_info_element *e;
4225
4226 TRACE("Using fast vertex array code\n");
4227
4228 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4229 stateblock->device->instancedDraw = FALSE;
4230
4231 /* Blend Data ---------------------------------------------- */
4232 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4233 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4234 {
4235 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4236
4237 if (gl_info->supported[ARB_VERTEX_BLEND])
4238 {
4239 TRACE("Blend %d %p %d\n", e->format_desc->component_count,
4240 e->data + stateblock->loadBaseVertexIndex * e->stride, e->stride + offset[e->stream_idx]);
4241
4242 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4243 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4244
4245 GL_EXTCALL(glVertexBlendARB(e->format_desc->component_count + 1));
4246
4247 if (curVBO != e->buffer_object)
4248 {
4249 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4250 checkGLcall("glBindBufferARB");
4251 curVBO = e->buffer_object;
4252 }
4253
4254 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4255 e->format_desc->gl_vtx_format,
4256 e->format_desc->gl_vtx_type,
4257 e->stride,
4258 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4259 GL_EXTCALL(glWeightPointerARB(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4260 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
4261
4262 checkGLcall("glWeightPointerARB");
4263
4264 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4265 {
4266 static BOOL warned;
4267 if (!warned)
4268 {
4269 FIXME("blendMatrixIndices support\n");
4270 warned = TRUE;
4271 }
4272 }
4273 } else {
4274 /* TODO: support blends in drawStridedSlow
4275 * No need to write a FIXME here, this is done after the general vertex decl decoding
4276 */
4277 WARN("unsupported blending in openGl\n");
4278 }
4279 }
4280 else
4281 {
4282 if (gl_info->supported[ARB_VERTEX_BLEND])
4283 {
4284 static const GLbyte one = 1;
4285 GL_EXTCALL(glWeightbvARB(1, &one));
4286 checkGLcall("glWeightivARB(gl_info->max_blends, weights)");
4287 }
4288 }
4289
4290 /* Point Size ----------------------------------------------*/
4291 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4292 {
4293 /* no such functionality in the fixed function GL pipeline */
4294 TRACE("Cannot change ptSize here in openGl\n");
4295 /* TODO: Implement this function in using shaders if they are available */
4296 }
4297
4298 /* Vertex Pointers -----------------------------------------*/
4299 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4300 {
4301 e = &si->elements[WINED3D_FFP_POSITION];
4302 if (curVBO != e->buffer_object)
4303 {
4304 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4305 checkGLcall("glBindBufferARB");
4306 curVBO = e->buffer_object;
4307 }
4308
4309 /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord
4310 handling for rhw mode should not impact screen position whereas in GL it does.
4311 This may result in very slightly distorted textures in rhw mode.
4312 There's always the other option of fixing the view matrix to
4313 prevent w from having any effect.
4314
4315 This only applies to user pointer sources, in VBOs the vertices are fixed up
4316 */
4317 if (!e->buffer_object)
4318 {
4319 TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride,
4320 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4321 glVertexPointer(3 /* min(e->format_desc->gl_vtx_format, 3) */, e->format_desc->gl_vtx_type, e->stride,
4322 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4323 }
4324 else
4325 {
4326 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4327 e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4328 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4329 glVertexPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4330 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4331 }
4332 checkGLcall("glVertexPointer(...)");
4333 glEnableClientState(GL_VERTEX_ARRAY);
4334 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4335 }
4336
4337 /* Normals -------------------------------------------------*/
4338 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4339 {
4340 e = &si->elements[WINED3D_FFP_NORMAL];
4341 if (curVBO != e->buffer_object)
4342 {
4343 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4344 checkGLcall("glBindBufferARB");
4345 curVBO = e->buffer_object;
4346 }
4347
4348 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride,
4349 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4350 glNormalPointer(e->format_desc->gl_vtx_type, e->stride,
4351 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4352 checkGLcall("glNormalPointer(...)");
4353 glEnableClientState(GL_NORMAL_ARRAY);
4354 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4355
4356 } else {
4357 glNormal3f(0, 0, 0);
4358 checkGLcall("glNormal3f(0, 0, 0)");
4359 }
4360
4361 /* Diffuse Colour --------------------------------------------*/
4362 /* WARNING: Data here MUST be in RGBA format, so cannot */
4363 /* go directly into fast mode from app pgm, because */
4364 /* directx requires data in BGRA format. */
4365 /* currently fixupVertices swizzles the format, but this isn't*/
4366 /* very practical when using VBOs */
4367 /* NOTE: Unless we write a vertex shader to swizzle the colour*/
4368 /* , or the user doesn't care and wants the speed advantage */
4369
4370 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4371 {
4372 e = &si->elements[WINED3D_FFP_DIFFUSE];
4373 if (curVBO != e->buffer_object)
4374 {
4375 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4376 checkGLcall("glBindBufferARB");
4377 curVBO = e->buffer_object;
4378 }
4379
4380 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4381 e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4382 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4383 glColorPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4384 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4385 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4386 glEnableClientState(GL_COLOR_ARRAY);
4387 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4388
4389 } else {
4390 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4391 checkGLcall("glColor4f(1, 1, 1, 1)");
4392 }
4393
4394 /* Specular Colour ------------------------------------------*/
4395 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4396 {
4397 TRACE("setting specular colour\n");
4398
4399 e = &si->elements[WINED3D_FFP_SPECULAR];
4400 if (gl_info->supported[EXT_SECONDARY_COLOR])
4401 {
4402 GLenum type = e->format_desc->gl_vtx_type;
4403 GLint format = e->format_desc->gl_vtx_format;
4404
4405 if (curVBO != e->buffer_object)
4406 {
4407 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4408 checkGLcall("glBindBufferARB");
4409 curVBO = e->buffer_object;
4410 }
4411
4412 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4413 {
4414 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4415 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4416 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4417 * 4 component secondary colors use it
4418 */
4419 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4420 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4421 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4422 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
4423 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4424 }
4425 else
4426 {
4427 switch(type)
4428 {
4429 case GL_UNSIGNED_BYTE:
4430 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4431 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4432 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4433 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
4434 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4435 break;
4436
4437 default:
4438 FIXME("Add 4 component specular color pointers for type %x\n", type);
4439 /* Make sure that the right color component is dropped */
4440 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4441 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4442 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4443 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]));
4444 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4445 }
4446 }
4447 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4448 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4449 }
4450 else
4451 {
4452 WARN("Specular colour is not supported in this GL implementation.\n");
4453 }
4454 }
4455 else
4456 {
4457 if (gl_info->supported[EXT_SECONDARY_COLOR])
4458 {
4459 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4460 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4461 }
4462 else
4463 {
4464 WARN("Specular colour is not supported in this GL implementation.\n");
4465 }
4466 }
4467
4468 /* Texture coords -------------------------------------------*/
4469 loadTexCoords(context, stateblock, si, &curVBO);
4470}
4471
4472static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4473{
4474 IWineD3DDeviceImpl *device = stateblock->device;
4475 BOOL load_numbered = use_vs(stateblock) && !device->useDrawStridedSlow;
4476 BOOL load_named = !use_vs(stateblock) && !device->useDrawStridedSlow;
4477
4478 if (context->numberedArraysLoaded && !load_numbered)
4479 {
4480 unloadNumberedArrays(stateblock, context);
4481 context->numberedArraysLoaded = FALSE;
4482 context->numbered_array_mask = 0;
4483 }
4484 else if (context->namedArraysLoaded)
4485 {
4486 unloadVertexData(context);
4487 context->namedArraysLoaded = FALSE;
4488 }
4489
4490 if (load_numbered)
4491 {
4492 TRACE("Loading numbered arrays\n");
4493 loadNumberedArrays(stateblock, &device->strided_streams, context);
4494 context->numberedArraysLoaded = TRUE;
4495 }
4496 else if (load_named)
4497 {
4498 TRACE("Loading vertex data\n");
4499 loadVertexData(context, stateblock, &device->strided_streams);
4500 context->namedArraysLoaded = TRUE;
4501 }
4502}
4503
4504static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4505{
4506 const struct wined3d_gl_info *gl_info = context->gl_info;
4507 BOOL updateFog = FALSE;
4508 BOOL useVertexShaderFunction = use_vs(stateblock);
4509 BOOL usePixelShaderFunction = use_ps(stateblock);
4510 IWineD3DDeviceImpl *device = stateblock->device;
4511 BOOL transformed;
4512 BOOL wasrhw = context->last_was_rhw;
4513 unsigned int i;
4514
4515 transformed = device->strided_streams.position_transformed;
4516 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
4517 updateFog = TRUE;
4518 }
4519
4520 /* Reapply lighting if it is not scheduled for reapplication already */
4521 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
4522 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
4523 }
4524
4525 if (transformed) {
4526 context->last_was_rhw = TRUE;
4527 } else {
4528
4529 /* Untransformed, so relies on the view and projection matrices */
4530 context->last_was_rhw = FALSE;
4531 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
4532 device->untransformed = TRUE;
4533
4534 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
4535 * Not needed as long as only hw shaders are supported
4536 */
4537
4538 /* This sets the shader output position correction constants.
4539 * TODO: Move to the viewport state
4540 */
4541 if (useVertexShaderFunction)
4542 {
4543 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
4544#if !defined(VBOX_WITH_WDDM) || !defined(DEBUG_leo)
4545 device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f;
4546#else
4547 device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f;
4548#endif
4549 device->posFixup[3] = device->posFixup[1] * yoffset;
4550 }
4551 }
4552
4553 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
4554 * off this function will be called again anyway to make sure they're properly set
4555 */
4556 if(!useVertexShaderFunction) {
4557 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
4558 * or transformed / untransformed was switched
4559 */
4560 if(wasrhw != context->last_was_rhw &&
4561 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
4562 !isStateDirty(context, STATE_VIEWPORT)) {
4563 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4564 }
4565 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4566 * mode.
4567 *
4568 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4569 * this check will fail and the matrix not applied again. This is OK because a simple
4570 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4571 * needs of the vertex declaration.
4572 *
4573 * World and view matrix go into the same gl matrix, so only apply them when neither is
4574 * dirty
4575 */
4576 if(transformed != wasrhw &&
4577 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
4578 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
4579 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4580 }
4581
4582 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
4583 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
4584 }
4585
4586 if(context->last_was_vshader) {
4587 updateFog = TRUE;
4588 if(!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
4589 state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
4590 }
4591 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4592 {
4593 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4594 }
4595 }
4596 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
4597 state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
4598 }
4599 } else {
4600 if(!context->last_was_vshader) {
4601 static BOOL warned = FALSE;
4602 if(!device->vs_clipping) {
4603 /* Disable all clip planes to get defined results on all drivers. See comment in the
4604 * state_clipping state handler
4605 */
4606 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4607 {
4608 glDisable(GL_CLIP_PLANE0 + i);
4609 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4610 }
4611
4612 if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
4613 FIXME("Clipping not supported with vertex shaders\n");
4614 warned = TRUE;
4615 }
4616 }
4617 if(wasrhw) {
4618 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
4619 * shaders themselves do not need it, but the matrices are not reapplied automatically when
4620 * switching back from vertex shaders to fixed function processing. So make sure we leave the
4621 * fixed function vertex processing states back in a sane state before switching to shaders
4622 */
4623 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4624 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4625 }
4626 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
4627 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4628 }
4629 }
4630 updateFog = TRUE;
4631
4632 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4633 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4634 * device->vs_clipping is false.
4635 */
4636 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4637 {
4638 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4639 }
4640 }
4641 }
4642
4643 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
4644 * application
4645 */
4646 if (!isStateDirty(context, STATE_PIXELSHADER)) {
4647 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4648
4649 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
4650 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4651 }
4652 }
4653
4654 context->last_was_vshader = useVertexShaderFunction;
4655
4656 if (updateFog) stateblock_apply_state(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context);
4657
4658 if(!useVertexShaderFunction) {
4659 int i;
4660 for(i = 0; i < MAX_TEXTURES; i++) {
4661 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
4662 transform_texture(STATE_TEXTURESTAGE(i, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
4663 }
4664 }
4665 }
4666}
4667
4668static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4669{
4670 IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0];
4671 UINT width, height;
4672 WINED3DVIEWPORT vp = stateblock->viewport;
4673
4674 if(vp.Width > target->currentDesc.Width) vp.Width = target->currentDesc.Width;
4675 if(vp.Height > target->currentDesc.Height) vp.Height = target->currentDesc.Height;
4676
4677 glDepthRange(vp.MinZ, vp.MaxZ);
4678 checkGLcall("glDepthRange");
4679 /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
4680 */
4681 if (context->render_offscreen)
4682 {
4683 glViewport(vp.X, vp.Y, vp.Width, vp.Height);
4684 } else {
4685 target->get_drawable_size(context, &width, &height);
4686
4687 glViewport(vp.X,
4688 (height - (vp.Y + vp.Height)),
4689 vp.Width, vp.Height);
4690 }
4691
4692 checkGLcall("glViewport");
4693}
4694
4695static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4696{
4697 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
4698
4699 stateblock->device->posFixup[2] = (63.0f / 64.0f) / stateblock->viewport.Width;
4700 stateblock->device->posFixup[3] = stateblock->device->posFixup[1] * yoffset;
4701
4702 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4703 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4704 }
4705 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
4706 state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
4707 }
4708 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4709 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4710}
4711
4712static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4713{
4714 UINT Index = state - STATE_ACTIVELIGHT(0);
4715 const struct wined3d_light_info *lightInfo = stateblock->activeLights[Index];
4716
4717 if(!lightInfo) {
4718 glDisable(GL_LIGHT0 + Index);
4719 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4720 } else {
4721 float quad_att;
4722 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4723
4724 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4725 glMatrixMode(GL_MODELVIEW);
4726 glPushMatrix();
4727 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
4728
4729 /* Diffuse: */
4730 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
4731 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
4732 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
4733 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
4734 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4735 checkGLcall("glLightfv");
4736
4737 /* Specular */
4738 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
4739 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
4740 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
4741 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
4742 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4743 checkGLcall("glLightfv");
4744
4745 /* Ambient */
4746 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
4747 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
4748 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
4749 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
4750 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4751 checkGLcall("glLightfv");
4752
4753 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
4754 quad_att = 1.4f/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
4755 } else {
4756 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4757 }
4758
4759 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4760 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4761 * Attenuation0 to NaN and crashes in the gl lib
4762 */
4763
4764 switch (lightInfo->OriginalParms.Type) {
4765 case WINED3DLIGHT_POINT:
4766 /* Position */
4767 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4768 checkGLcall("glLightfv");
4769 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4770 checkGLcall("glLightf");
4771 /* Attenuation - Are these right? guessing... */
4772 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4773 checkGLcall("glLightf");
4774 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4775 checkGLcall("glLightf");
4776 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4777 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4778 checkGLcall("glLightf");
4779 /* FIXME: Range */
4780 break;
4781
4782 case WINED3DLIGHT_SPOT:
4783 /* Position */
4784 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4785 checkGLcall("glLightfv");
4786 /* Direction */
4787 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4788 checkGLcall("glLightfv");
4789 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4790 checkGLcall("glLightf");
4791 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4792 checkGLcall("glLightf");
4793 /* Attenuation - Are these right? guessing... */
4794 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4795 checkGLcall("glLightf");
4796 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4797 checkGLcall("glLightf");
4798 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4799 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4800 checkGLcall("glLightf");
4801 /* FIXME: Range */
4802 break;
4803
4804 case WINED3DLIGHT_DIRECTIONAL:
4805 /* Direction */
4806 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4807 checkGLcall("glLightfv");
4808 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4809 checkGLcall("glLightf");
4810 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4811 checkGLcall("glLightf");
4812 break;
4813
4814 default:
4815 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
4816 }
4817
4818 /* Restore the modelview matrix */
4819 glPopMatrix();
4820
4821 glEnable(GL_LIGHT0 + Index);
4822 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4823 }
4824}
4825
4826static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4827{
4828 IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0];
4829 RECT *pRect = &stateblock->scissorRect;
4830 UINT height;
4831 UINT width;
4832
4833 target->get_drawable_size(context, &width, &height);
4834 /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
4835 * Warning2: Even in windowed mode the coords are relative to the window, not the screen
4836 */
4837 TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->device, pRect->left, pRect->bottom - height,
4838 pRect->right - pRect->left, pRect->bottom - pRect->top);
4839
4840 if (context->render_offscreen)
4841 {
4842 glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
4843 } else {
4844 glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
4845 }
4846 checkGLcall("glScissor");
4847}
4848
4849static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4850{
4851 if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
4852 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4853 } else {
4854 struct wined3d_buffer *ib = (struct wined3d_buffer *) stateblock->pIndexData;
4855 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4856 }
4857}
4858
4859static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4860{
4861 if (context->render_offscreen)
4862 {
4863 glFrontFace(GL_CCW);
4864 checkGLcall("glFrontFace(GL_CCW)");
4865 } else {
4866 glFrontFace(GL_CW);
4867 checkGLcall("glFrontFace(GL_CW)");
4868 }
4869}
4870
4871const struct StateEntryTemplate misc_state_template[] = {
4872 { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4873 { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4874 { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4875 { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4876 { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4877 { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4878 { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4879 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4880 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4881 { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4882 { STATE_STREAMSRC, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
4883 { STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE },
4884 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4885 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4886 /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
4887 * vshader loadings are untied from each other
4888 */
4889 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4890 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4891 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4892 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4893 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4894 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4895 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4896 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4897 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4898 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4899 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4900 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4901 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4902 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4903 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4904 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4905 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4906 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4907 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4908 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4909 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4910 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4911 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4912 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4913 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4914 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4915 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4916 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4917 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4918 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4919 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4920 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4921 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4922 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4923 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4924 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4925 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4926 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4927 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4928 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4929 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4930 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4931 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4932 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4933 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4934 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4935 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4936 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4937 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4938 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
4939
4940 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
4941 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
4942 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
4943 { STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
4944 { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
4945 { STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
4946 { STATE_RENDER(WINED3DRS_WRAPU), { STATE_RENDER(WINED3DRS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
4947 { STATE_RENDER(WINED3DRS_WRAPV), { STATE_RENDER(WINED3DRS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
4948 { STATE_RENDER(WINED3DRS_FILLMODE), { STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
4949 { STATE_RENDER(WINED3DRS_SHADEMODE), { STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
4950 { STATE_RENDER(WINED3DRS_LINEPATTERN), { STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
4951 { STATE_RENDER(WINED3DRS_MONOENABLE), { STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
4952 { STATE_RENDER(WINED3DRS_ROP2), { STATE_RENDER(WINED3DRS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
4953 { STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
4954 { STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
4955 { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4956 { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4957 { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4958 { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4959 { STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
4960 { STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
4961 { STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
4962 { STATE_RENDER(WINED3DRS_DITHERENABLE), { STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
4963 { STATE_RENDER(WINED3DRS_SUBPIXEL), { STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
4964 { STATE_RENDER(WINED3DRS_SUBPIXELX), { STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
4965 { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
4966 { STATE_RENDER(WINED3DRS_ZBIAS), { STATE_RENDER(WINED3DRS_ZBIAS), state_zbias }, WINED3D_GL_EXT_NONE },
4967 { STATE_RENDER(WINED3DRS_STIPPLEENABLE), { STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
4968 { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
4969 { STATE_RENDER(WINED3DRS_ANISOTROPY), { STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
4970 { STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
4971 { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE },
4972 { STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4973 { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4974 { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4975 { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4976 { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4977 { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4978 { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4979 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
4980 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
4981 { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4982 { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4983 { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4984 { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4985 { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4986 { STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4987 { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4988 { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4989 { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4990 { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4991 { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4993 { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4994 { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4995 { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4997 { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4999 { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5001 { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5003 { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5004 { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5005 { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5006 { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5007 { STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5008 { STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5009 { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5011 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5012 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5013 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5014 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5015 { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
5016 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5017 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5018 { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5020 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5021 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5023 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5024 { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5026 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5027 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5029 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5030 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5031 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5032 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5033 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3DRS_ZVISIBLE), { STATE_RENDER(WINED3DRS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5036 /* Samplers */
5037 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5038 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5039 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5040 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5041 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5042 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5043 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5044 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5045 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5046 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5047 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5048 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5049 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5050 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5051 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5052 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5053 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5054 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5055 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5056 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5057 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5058};
5059
5060const struct StateEntryTemplate ffp_vertexstate_template[] = {
5061 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5062 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5063 { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5065 /* Clip planes */
5066 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5067 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5068 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5069 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5070 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5071 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5072 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5073 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5074 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5075 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5076 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5077 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5078 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5079 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5080 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5081 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5082 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5083 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5084 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5085 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5086 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5087 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5088 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5089 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5090 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5091 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5092 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5093 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5094 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5095 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5096 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5097 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5098 /* Lights */
5099 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5100 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5101 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5102 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5103 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5104 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5105 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5106 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5107 /* Viewport */
5108 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5109 /* Transform states follow */
5110 { STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5111 { STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5112 { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5113 { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5114 { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5115 { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5116 { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5117 { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5118 { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5119 { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5120 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5121 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5122 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5123 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5124 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5125 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5126 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5127 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5128 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5129 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5130 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5131 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5132 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5133 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5134 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5135 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5136 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5137 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5138 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5139 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5140 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5141 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5142 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5143 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5144 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5145 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5146 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5147 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5148 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5149 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5150 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5151 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5152 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5153 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5154 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5155 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5156 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5157 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5158 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5159 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5160 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5161 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5162 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5163 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5164 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5165 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5166 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5167 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5168 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5169 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5170 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5171 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5172 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5173 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5174 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5175 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5176 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5177 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5178 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5179 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5180 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5181 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5182 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5183 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5184 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5185 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5377 { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5378 { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5379 { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5380 { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5381 { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5382 { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5383 { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5384 { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5392 /* Fog */
5393 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5394 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5395 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5396 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE },
5397 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE },
5398 { STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5399 { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5400 { STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5401 { STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5402 { STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5403 { STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5404 { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5405 { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5406 { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5407 { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5408 { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5409 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5410 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5411 { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5412 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5413 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5414 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5415 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5416 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5417 { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5418 { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5419 { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5420 { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5421 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5422 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5423 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5424 { STATE_RENDER(WINED3DRS_TWEENFACTOR), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5425 { STATE_RENDER(WINED3DRS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5426
5427 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5428 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5429 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5430 */
5431 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5432 { STATE_SAMPLER(0), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5433 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5434 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5435 { STATE_SAMPLER(1), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5436 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5437 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5438 { STATE_SAMPLER(2), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5439 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5440 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5441 { STATE_SAMPLER(3), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5442 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5443 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5444 { STATE_SAMPLER(4), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5445 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5446 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5447 { STATE_SAMPLER(5), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5448 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5449 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5450 { STATE_SAMPLER(6), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5451 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5452 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5453 { STATE_SAMPLER(7), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5454 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5455 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5456};
5457
5458static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5459 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5460 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5461 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5462 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5463 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5464 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5465 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5466 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5467 { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5468 { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5469 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5470 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5471 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5472 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5473 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5474 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5475 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5476 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5477 { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5478 { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5479 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5480 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5481 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5491 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5492 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5493 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5494 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5495 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5496 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5497 { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5498 { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5499 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5500 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5501 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5502 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5503 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5504 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5505 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5506 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5507 { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5508 { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5510 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5511 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5512 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5513 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5514 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5515 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5516 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5517 { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5518 { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5519 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5520 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5521 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5522 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5523 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5524 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5525 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5527 { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5528 { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5529 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5530 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5531 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5532 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5533 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5534 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5535 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5536 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5537 { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5538 { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5539 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5540 { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5541 { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5542 { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5543 { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5544 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5545 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5547 { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5548 { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5550 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5551 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5552 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5553 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5554 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5555 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5556 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5557 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5558};
5559#undef GLINFO_LOCATION
5560
5561/* Context activation is done by the caller. */
5562static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
5563
5564static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
5565{
5566 pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
5567 WINED3DTEXOPCAPS_ADDSIGNED |
5568 WINED3DTEXOPCAPS_ADDSIGNED2X |
5569 WINED3DTEXOPCAPS_MODULATE |
5570 WINED3DTEXOPCAPS_MODULATE2X |
5571 WINED3DTEXOPCAPS_MODULATE4X |
5572 WINED3DTEXOPCAPS_SELECTARG1 |
5573 WINED3DTEXOPCAPS_SELECTARG2 |
5574 WINED3DTEXOPCAPS_DISABLE;
5575
5576 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5577 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5578 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5579 {
5580 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
5581 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
5582 WINED3DTEXOPCAPS_BLENDFACTORALPHA |
5583 WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
5584 WINED3DTEXOPCAPS_LERP |
5585 WINED3DTEXOPCAPS_SUBTRACT;
5586 }
5587 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5588 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5589 {
5590 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH |
5591 WINED3DTEXOPCAPS_MULTIPLYADD |
5592 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
5593 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
5594 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5595 }
5596 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5597 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5598
5599 pCaps->MaxTextureBlendStages = gl_info->limits.textures;
5600 pCaps->MaxSimultaneousTextures = gl_info->limits.textures;
5601}
5602
5603static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
5604static void ffp_fragment_free(IWineD3DDevice *iface) {}
5605static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5606{
5607 if (TRACE_ON(d3d))
5608 {
5609 TRACE("Checking support for fixup:\n");
5610 dump_color_fixup_desc(fixup);
5611 }
5612
5613 /* We only support identity conversions. */
5614 if (is_identity_fixup(fixup))
5615 {
5616 TRACE("[OK]\n");
5617 return TRUE;
5618 }
5619
5620 TRACE("[FAILED]\n");
5621 return FALSE;
5622}
5623
5624const struct fragment_pipeline ffp_fragment_pipeline = {
5625 ffp_enable,
5626 ffp_fragment_get_caps,
5627 ffp_fragment_alloc,
5628 ffp_fragment_free,
5629 ffp_color_fixup_supported,
5630 ffp_fragmentstate_template,
5631 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5632};
5633
5634static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5635{
5636 unsigned int i;
5637 for(i = 0; funcs[i]; i++);
5638 return i;
5639}
5640
5641static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
5642{
5643 stateblock->device->multistate_funcs[state][0](state, stateblock, context);
5644 stateblock->device->multistate_funcs[state][1](state, stateblock, context);
5645}
5646
5647static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
5648{
5649 stateblock->device->multistate_funcs[state][0](state, stateblock, context);
5650 stateblock->device->multistate_funcs[state][1](state, stateblock, context);
5651 stateblock->device->multistate_funcs[state][2](state, stateblock, context);
5652}
5653
5654static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5655{
5656 unsigned int start, last, i;
5657
5658 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5659 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5660 for (i = start; i <= last; ++i)
5661 {
5662 state_table[i].representative = 0;
5663 state_table[i].apply = state_undefined;
5664 }
5665
5666 start = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + gl_info->limits.texture_stages);
5667 last = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + MAX_TEXTURES - 1);
5668 for (i = start; i <= last; ++i)
5669 {
5670 state_table[i].representative = 0;
5671 state_table[i].apply = state_undefined;
5672 }
5673
5674 start = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(gl_info->limits.blends));
5675 last = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255));
5676 for (i = start; i <= last; ++i)
5677 {
5678 state_table[i].representative = 0;
5679 state_table[i].apply = state_undefined;
5680 }
5681}
5682
5683static void validate_state_table(struct StateEntry *state_table)
5684{
5685 static const struct
5686 {
5687 DWORD first;
5688 DWORD last;
5689 }
5690 rs_holes[] =
5691 {
5692 { 1, 1},
5693 { 3, 3},
5694 { 17, 18},
5695 { 21, 21},
5696 { 42, 45},
5697 { 61, 127},
5698 {149, 150},
5699 {169, 169},
5700 {177, 177},
5701 {196, 197},
5702 { 0, 0},
5703 };
5704 static const DWORD simple_states[] =
5705 {
5706 STATE_MATERIAL,
5707 STATE_VDECL,
5708 STATE_STREAMSRC,
5709 STATE_INDEXBUFFER,
5710 STATE_VERTEXSHADERCONSTANT,
5711 STATE_PIXELSHADERCONSTANT,
5712 STATE_VSHADER,
5713 STATE_PIXELSHADER,
5714 STATE_VIEWPORT,
5715 STATE_SCISSORRECT,
5716 STATE_FRONTFACE,
5717 };
5718 unsigned int i, current;
5719
5720 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5721 {
5722 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5723 {
5724 if (!state_table[i].representative)
5725 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5726 }
5727 else if (state_table[i].representative)
5728 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5729
5730 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5731 }
5732
5733 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5734 {
5735 if (!state_table[simple_states[i]].representative)
5736 ERR("State %s (%#x) should have a representative.\n",
5737 debug_d3dstate(simple_states[i]), simple_states[i]);
5738 }
5739
5740 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5741 {
5742 DWORD rep = state_table[i].representative;
5743 if (rep)
5744 {
5745 if (state_table[rep].representative != rep)
5746 {
5747 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5748 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5749 state_table[i].representative = 0;
5750 }
5751
5752 if (rep != i)
5753 {
5754 if (state_table[i].apply)
5755 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5756 }
5757 else if (!state_table[i].apply)
5758 {
5759 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5760 }
5761 }
5762 }
5763}
5764
5765HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5766 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5767 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5768{
5769 unsigned int i, type, handlers;
5770 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5771 const struct StateEntryTemplate *cur;
5772 BOOL set[STATE_HIGHEST + 1];
5773
5774 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5775
5776 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5777 StateTable[i].representative = 0;
5778 StateTable[i].apply = state_undefined;
5779 }
5780
5781 for(type = 0; type < 3; type++) {
5782 /* This switch decides the order in which the states are applied */
5783 switch(type) {
5784 case 0: cur = misc; break;
5785 case 1: cur = fragment->states; break;
5786 case 2: cur = vertex; break;
5787 default: cur = NULL; /* Stupid compiler */
5788 }
5789 if(!cur) continue;
5790
5791 /* GL extension filtering should not prevent multiple handlers being applied from different
5792 * pipeline parts
5793 */
5794 memset(set, 0, sizeof(set));
5795
5796 for(i = 0; cur[i].state; i++) {
5797 APPLYSTATEFUNC *funcs_array;
5798
5799 /* Only use the first matching state with the available extension from one template.
5800 * e.g.
5801 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5802 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5803 *
5804 * if GL_XYZ_fancy is supported, ignore the 2nd line
5805 */
5806 if(set[cur[i].state]) continue;
5807 /* Skip state lines depending on unsupported extensions */
5808 if (!gl_info->supported[cur[i].extension]) continue;
5809 set[cur[i].state] = TRUE;
5810 /* In some cases having an extension means that nothing has to be
5811 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5812 * supported, the texture coordinate fixup can be ignored. If the
5813 * apply function is used, mark the state set(done above) to prevent
5814 * applying later lines, but do not record anything in the state
5815 * table
5816 */
5817 if (!cur[i].content.representative) continue;
5818
5819 handlers = num_handlers(multistate_funcs[cur[i].state]);
5820 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5821 switch(handlers) {
5822 case 0:
5823 StateTable[cur[i].state].apply = cur[i].content.apply;
5824 break;
5825 case 1:
5826 StateTable[cur[i].state].apply = multistate_apply_2;
5827 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5828 0,
5829 sizeof(**dev_multistate_funcs) * 2);
5830 if (!dev_multistate_funcs[cur[i].state]) {
5831 goto out_of_mem;
5832 }
5833
5834 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5835 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5836 break;
5837 case 2:
5838 StateTable[cur[i].state].apply = multistate_apply_3;
5839 funcs_array = HeapReAlloc(GetProcessHeap(),
5840 0,
5841 dev_multistate_funcs[cur[i].state],
5842 sizeof(**dev_multistate_funcs) * 3);
5843 if (!funcs_array) {
5844 goto out_of_mem;
5845 }
5846
5847 dev_multistate_funcs[cur[i].state] = funcs_array;
5848 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5849 break;
5850 default:
5851 ERR("Unexpected amount of state handlers for state %u: %u\n",
5852 cur[i].state, handlers + 1);
5853 }
5854
5855 if(StateTable[cur[i].state].representative &&
5856 StateTable[cur[i].state].representative != cur[i].content.representative) {
5857 FIXME("State %u has different representatives in different pipeline parts\n",
5858 cur[i].state);
5859 }
5860 StateTable[cur[i].state].representative = cur[i].content.representative;
5861 }
5862 }
5863
5864 prune_invalid_states(StateTable, gl_info);
5865 validate_state_table(StateTable);
5866
5867 return WINED3D_OK;
5868
5869out_of_mem:
5870 for (i = 0; i <= STATE_HIGHEST; ++i) {
5871 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5872 }
5873
5874 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5875
5876 return E_OUTOFMEMORY;
5877}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette