VirtualBox

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

Last change on this file since 22652 was 22496, checked in by vboxsync, 16 years ago

crOpenGL: update wine to 1.1.27 and better fix for depthstencil surface refcounting

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

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