wined3d: Instancing emulation.
[wine/multimedia.git] / dlls / wined3d / state.c
blob808d478dbf6b44c172428dd8454724d3013ea83b
1 /*
2 * Direct3D state management
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-2007 Stefan Dösinger for CodeWeavers
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.
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.
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
27 #include "config.h"
28 #include <stdio.h>
29 #ifdef HAVE_FLOAT_H
30 # include <float.h>
31 #endif
32 #include "wined3d_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
35 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
37 #define GLINFO_LOCATION ((IWineD3DImpl *)(stateblock->wineD3DDevice->wineD3D))->gl_info
39 static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
40 /* Used for states which are not mapped to a gl state as-is, but used somehow different,
41 * e.g as a parameter for drawing, or which are unimplemented in windows d3d
43 if(STATE_IS_RENDER(state)) {
44 WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0);
45 TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]);
46 } else {
47 /* Shouldn't have an unknown type here */
48 FIXME("%d no direct mapping to gl of state with unknown type\n", state);
52 static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
53 /* Print a WARN, this allows the stateblock code to loop over all states to generate a display
54 * list without causing confusing terminal output. Deliberately no special debug name here
55 * because its undefined.
57 WARN("undefined state %d\n", state);
60 static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
61 D3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
63 switch(Value) {
64 case D3DFILL_POINT:
65 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
66 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
67 break;
68 case D3DFILL_WIREFRAME:
69 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
70 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
71 break;
72 case D3DFILL_SOLID:
73 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
74 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
75 break;
76 default:
77 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
81 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
82 BOOL normals;
84 /* Lighting is only enabled if Vertex normals are passed by the application,
85 * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
86 * This state reads the decoded vertex decl, so if it is dirty don't do anything. The
87 * vertex declaration appplying function calls this function for updating
90 if(isStateDirty(context, STATE_VDECL)) {
91 return;
94 normals = stateblock->wineD3DDevice->strided_streams.u.s.normal.lpData != NULL ||
95 stateblock->wineD3DDevice->strided_streams.u.s.normal.VBO != 0;
97 if (stateblock->renderState[WINED3DRS_LIGHTING] && normals) {
98 glEnable(GL_LIGHTING);
99 checkGLcall("glEnable GL_LIGHTING");
100 } else {
101 glDisable(GL_LIGHTING);
102 checkGLcall("glDisable GL_LIGHTING");
106 static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
107 switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
108 case WINED3DZB_FALSE:
109 glDisable(GL_DEPTH_TEST);
110 checkGLcall("glDisable GL_DEPTH_TEST");
111 break;
112 case WINED3DZB_TRUE:
113 glEnable(GL_DEPTH_TEST);
114 checkGLcall("glEnable GL_DEPTH_TEST");
115 break;
116 case WINED3DZB_USEW:
117 glEnable(GL_DEPTH_TEST);
118 checkGLcall("glEnable GL_DEPTH_TEST");
119 FIXME("W buffer is not well handled\n");
120 break;
121 default:
122 FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]);
126 static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
127 /* TODO: Put this into the offscreen / onscreen rendering block due to device->render_offscreen */
129 /* If we are culling "back faces with clockwise vertices" then
130 set front faces to be counter clockwise and enable culling
131 of back faces */
132 switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
133 case WINED3DCULL_NONE:
134 glDisable(GL_CULL_FACE);
135 checkGLcall("glDisable GL_CULL_FACE");
136 break;
137 case WINED3DCULL_CW:
138 glEnable(GL_CULL_FACE);
139 checkGLcall("glEnable GL_CULL_FACE");
140 if (stateblock->wineD3DDevice->render_offscreen) {
141 glFrontFace(GL_CW);
142 checkGLcall("glFrontFace GL_CW");
143 } else {
144 glFrontFace(GL_CCW);
145 checkGLcall("glFrontFace GL_CCW");
147 glCullFace(GL_BACK);
148 break;
149 case WINED3DCULL_CCW:
150 glEnable(GL_CULL_FACE);
151 checkGLcall("glEnable GL_CULL_FACE");
152 if (stateblock->wineD3DDevice->render_offscreen) {
153 glFrontFace(GL_CCW);
154 checkGLcall("glFrontFace GL_CCW");
155 } else {
156 glFrontFace(GL_CW);
157 checkGLcall("glFrontFace GL_CW");
159 glCullFace(GL_BACK);
160 break;
161 default:
162 FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
166 static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
167 switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
168 case WINED3DSHADE_FLAT:
169 glShadeModel(GL_FLAT);
170 checkGLcall("glShadeModel(GL_FLAT)");
171 break;
172 case WINED3DSHADE_GOURAUD:
173 glShadeModel(GL_SMOOTH);
174 checkGLcall("glShadeModel(GL_SMOOTH)");
175 break;
176 case WINED3DSHADE_PHONG:
177 FIXME("WINED3DSHADE_PHONG isn't supported\n");
178 break;
179 default:
180 FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]);
184 static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
185 if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
186 glEnable(GL_DITHER);
187 checkGLcall("glEnable GL_DITHER");
188 } else {
189 glDisable(GL_DITHER);
190 checkGLcall("glDisable GL_DITHER");
194 static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
195 /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
196 * this has to be merged with ZENABLE and ZFUNC
198 if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) {
199 glDepthMask(1);
200 checkGLcall("glDepthMask(1)");
201 } else {
202 glDepthMask(0);
203 checkGLcall("glDepthMask(0)");
207 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
208 int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
210 if(glParm) {
211 glDepthFunc(glParm);
212 checkGLcall("glDepthFunc");
216 static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
217 float col[4];
218 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
220 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
221 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
222 checkGLcall("glLightModel for MODEL_AMBIENT");
225 static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
226 int srcBlend = GL_ZERO;
227 int dstBlend = GL_ZERO;
229 /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */
230 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE] ||
231 stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
232 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
233 glEnable(GL_BLEND);
234 checkGLcall("glEnable GL_BLEND");
235 } else {
236 glDisable(GL_BLEND);
237 checkGLcall("glDisable GL_BLEND");
238 /* Nothing more to do - get out */
239 return;
242 switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
243 case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
244 case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
245 case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
246 case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
247 case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
248 case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
249 case WINED3DBLEND_DESTALPHA : srcBlend = GL_DST_ALPHA; break;
250 case WINED3DBLEND_INVDESTALPHA : srcBlend = GL_ONE_MINUS_DST_ALPHA; break;
251 case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
252 case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
253 case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
255 case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
256 dstBlend = GL_SRC_ALPHA;
257 break;
259 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
260 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
261 break;
263 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
264 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
265 default:
266 FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
269 switch (stateblock->renderState[WINED3DRS_DESTBLEND]) {
270 case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break;
271 case WINED3DBLEND_ONE : dstBlend = GL_ONE; break;
272 case WINED3DBLEND_SRCCOLOR : dstBlend = GL_SRC_COLOR; break;
273 case WINED3DBLEND_INVSRCCOLOR : dstBlend = GL_ONE_MINUS_SRC_COLOR; break;
274 case WINED3DBLEND_SRCALPHA : dstBlend = GL_SRC_ALPHA; break;
275 case WINED3DBLEND_INVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA; break;
276 case WINED3DBLEND_DESTALPHA : dstBlend = GL_DST_ALPHA; break;
277 case WINED3DBLEND_INVDESTALPHA : dstBlend = GL_ONE_MINUS_DST_ALPHA; break;
278 case WINED3DBLEND_DESTCOLOR : dstBlend = GL_DST_COLOR; break;
279 case WINED3DBLEND_INVDESTCOLOR : dstBlend = GL_ONE_MINUS_DST_COLOR; break;
280 case WINED3DBLEND_SRCALPHASAT : dstBlend = GL_SRC_ALPHA_SATURATE; break;
282 case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA;
283 srcBlend = GL_SRC_ALPHA;
284 break;
286 case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
287 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
288 break;
290 case D3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
291 case D3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
292 default:
293 FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
296 if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
297 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
298 glEnable(GL_LINE_SMOOTH);
299 checkGLcall("glEnable(GL_LINE_SMOOTH)");
300 if(srcBlend != GL_SRC_ALPHA) {
301 FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible src blending param - what to do?\n");
302 srcBlend = GL_SRC_ALPHA;
304 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA) {
305 FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible dst blending param - what to do?\n");
306 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
308 } else {
309 glDisable(GL_LINE_SMOOTH);
310 checkGLcall("glDisable(GL_LINE_SMOOTH)");
313 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
314 glBlendFunc(srcBlend, dstBlend);
315 checkGLcall("glBlendFunc");
318 static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
319 float col[4];
321 TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
322 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
323 glBlendColor (col[0],col[1],col[2],col[3]);
324 checkGLcall("glBlendColor");
327 static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
328 int glParm = 0;
329 float ref;
330 BOOL enable_ckey = FALSE;
332 IWineD3DSurfaceImpl *surf;
334 /* Find out if the texture on the first stage has a ckey set
335 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
336 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
337 * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
338 * in case it finds some texture+colorkeyenable combination which needs extra care.
340 if(stateblock->textures[0]) {
341 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
342 if(surf->CKeyFlags & DDSD_CKSRCBLT) enable_ckey = TRUE;
345 if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
346 (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
347 glEnable(GL_ALPHA_TEST);
348 checkGLcall("glEnable GL_ALPHA_TEST");
349 } else {
350 glDisable(GL_ALPHA_TEST);
351 checkGLcall("glDisable GL_ALPHA_TEST");
352 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
353 * enable call
355 return;
358 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
359 glParm = GL_NOTEQUAL;
360 ref = 0.0;
361 } else {
362 ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
363 glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
365 if(glParm) {
366 glAlphaFunc(glParm, ref);
367 checkGLcall("glAlphaFunc");
369 /* TODO: Some texture blending operations seem to affect the alpha test */
372 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
373 DWORD enable = 0xFFFFFFFF;
374 DWORD disable = 0x00000000;
376 /* TODO: Keep track of previously enabled clipplanes to avoid unneccessary resetting
377 * of already set values
380 /* If enabling / disabling all
381 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
383 if (stateblock->renderState[WINED3DRS_CLIPPING]) {
384 enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
385 disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
386 } else {
387 disable = 0xffffffff;
388 enable = 0x00;
391 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
392 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
393 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
394 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
395 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
396 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
398 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
399 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
400 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
401 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
402 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
403 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
405 /** update clipping status */
406 if (enable) {
407 stateblock->clip_status.ClipUnion = 0;
408 stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
409 } else {
410 stateblock->clip_status.ClipUnion = 0;
411 stateblock->clip_status.ClipIntersection = 0;
415 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
416 int glParm = GL_FUNC_ADD;
418 if(!GL_SUPPORT(EXT_BLEND_MINMAX)) {
419 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
420 return;
423 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
424 case WINED3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
425 case WINED3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
426 case WINED3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
427 case WINED3DBLENDOP_MIN : glParm = GL_MIN; break;
428 case WINED3DBLENDOP_MAX : glParm = GL_MAX; break;
429 default:
430 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
433 TRACE("glBlendEquation(%x)\n", glParm);
434 GL_EXTCALL(glBlendEquation(glParm));
435 checkGLcall("glBlendEquation");
438 static void
439 state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
440 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
441 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
442 * specular color. This is wrong:
443 * Separate specular color means the specular colour is maintained separately, whereas
444 * single color means it is merged in. However in both cases they are being used to
445 * some extent.
446 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
447 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
448 * running 1.4 yet!
451 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
452 * Instead, we need to setup the FinalCombiner properly.
454 * The default setup for the FinalCombiner is:
456 * <variable> <input> <mapping> <usage>
457 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
458 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
459 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
460 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
461 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
462 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
463 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
465 * That's pretty much fine as it is, except for variable B, which needs to take
466 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
467 * whether WINED3DRS_SPECULARENABLE is enabled or not.
470 TRACE("Setting specular enable state\n");
471 /* TODO: Add to the material setting functions */
472 if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
473 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
474 checkGLcall("glMaterialfv");
475 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
476 glEnable(GL_COLOR_SUM_EXT);
477 } else {
478 TRACE("Specular colors cannot be enabled in this version of opengl\n");
480 checkGLcall("glEnable(GL_COLOR_SUM)");
482 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
483 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
484 checkGLcall("glFinalCombinerInputNV()");
486 } else {
487 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
489 /* for the case of enabled lighting: */
490 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
491 checkGLcall("glMaterialfv");
493 /* for the case of disabled lighting: */
494 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
495 glDisable(GL_COLOR_SUM_EXT);
496 } else {
497 TRACE("Specular colors cannot be disabled in this version of opengl\n");
499 checkGLcall("glDisable(GL_COLOR_SUM)");
501 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
502 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
503 checkGLcall("glFinalCombinerInputNV()");
508 static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
509 unsigned int i;
511 /* Note the texture color applies to all textures whereas
512 * GL_TEXTURE_ENV_COLOR applies to active only
514 float col[4];
515 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
517 if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
518 /* And now the default texture color as well */
519 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
520 /* Note the WINED3DRS value applies to all textures, but GL has one
521 * per texture, so apply it now ready to be used!
523 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
524 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
525 checkGLcall("glActiveTextureARB");
526 } else if (i>0) {
527 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
530 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
531 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
533 } else {
534 GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
538 static void
539 renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass ) {
540 #if 0 /* Don't use OpenGL 2.0 calls for now */
541 if(GL_EXTCALL(glStencilFuncSeparate) && GL_EXTCALL(glStencilOpSeparate)) {
542 GL_EXTCALL(glStencilFuncSeparate(face, func, ref, mask));
543 checkGLcall("glStencilFuncSeparate(...)");
544 GL_EXTCALL(glStencilOpSeparate(face, stencilFail, depthFail, stencilPass));
545 checkGLcall("glStencilOpSeparate(...)");
547 else
548 #endif
549 if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
550 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
551 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
552 GL_EXTCALL(glActiveStencilFaceEXT(face));
553 checkGLcall("glActiveStencilFaceEXT(...)");
554 glStencilFunc(func, ref, mask);
555 checkGLcall("glStencilFunc(...)");
556 glStencilOp(stencilFail, depthFail, stencilPass);
557 checkGLcall("glStencilOp(...)");
558 } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
559 GL_EXTCALL(glStencilFuncSeparateATI(face, func, ref, mask));
560 checkGLcall("glStencilFuncSeparateATI(...)");
561 GL_EXTCALL(glStencilOpSeparateATI(face, stencilFail, depthFail, stencilPass));
562 checkGLcall("glStencilOpSeparateATI(...)");
563 } else {
564 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
568 static void
569 state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
570 DWORD onesided_enable = FALSE;
571 DWORD twosided_enable = FALSE;
572 GLint func = GL_ALWAYS;
573 GLint func_ccw = GL_ALWAYS;
574 GLint ref = 0;
575 GLuint mask = 0;
576 GLint stencilFail = GL_KEEP;
577 GLint depthFail = GL_KEEP;
578 GLint stencilPass = GL_KEEP;
579 GLint stencilFail_ccw = GL_KEEP;
580 GLint depthFail_ccw = GL_KEEP;
581 GLint stencilPass_ccw = GL_KEEP;
583 if( stateblock->set.renderState[WINED3DRS_STENCILENABLE] )
584 onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
585 if( stateblock->set.renderState[WINED3DRS_TWOSIDEDSTENCILMODE] )
586 twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
587 if( stateblock->set.renderState[WINED3DRS_STENCILFUNC] )
588 if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
589 func = GL_ALWAYS;
590 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFUNC] )
591 if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
592 func = GL_ALWAYS;
593 if( stateblock->set.renderState[WINED3DRS_STENCILREF] )
594 ref = stateblock->renderState[WINED3DRS_STENCILREF];
595 if( stateblock->set.renderState[WINED3DRS_STENCILMASK] )
596 mask = stateblock->renderState[WINED3DRS_STENCILMASK];
597 if( stateblock->set.renderState[WINED3DRS_STENCILFAIL] )
598 stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
599 if( stateblock->set.renderState[WINED3DRS_STENCILZFAIL] )
600 depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
601 if( stateblock->set.renderState[WINED3DRS_STENCILPASS] )
602 stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
603 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFAIL] )
604 stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
605 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILZFAIL] )
606 depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
607 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILPASS] )
608 stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
610 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
611 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
612 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
613 onesided_enable, twosided_enable, ref, mask,
614 func, stencilFail, depthFail, stencilPass,
615 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
617 if (twosided_enable) {
618 renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
619 renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
620 } else {
621 if (onesided_enable) {
622 glEnable(GL_STENCIL_TEST);
623 checkGLcall("glEnable GL_STENCIL_TEST");
624 glStencilFunc(func, ref, mask);
625 checkGLcall("glStencilFunc(...)");
626 glStencilOp(stencilFail, depthFail, stencilPass);
627 checkGLcall("glStencilOp(...)");
628 } else {
629 glDisable(GL_STENCIL_TEST);
630 checkGLcall("glDisable GL_STENCIL_TEST");
635 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
636 glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]);
637 checkGLcall("glStencilMask");
640 static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
641 /* TODO: Put this into the vertex type block once that is in the state table */
642 BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
643 float fogstart, fogend;
645 union {
646 DWORD d;
647 float f;
648 } tmpvalue;
650 if (!fogenable) {
651 /* No fog? Disable it, and we're done :-) */
652 glDisable(GL_FOG);
653 checkGLcall("glDisable GL_FOG");
656 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
657 fogstart = tmpvalue.f;
658 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
659 fogend = tmpvalue.f;
661 /* Activate when vertex shaders are in the state table */
662 if(stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function &&
663 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) {
664 glFogi(GL_FOG_MODE, GL_LINEAR);
665 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
666 fogstart = 1.0;
667 fogend = 0.0;
668 context->last_was_foggy_shader = TRUE;
670 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
671 * the system will apply only pixel(=table) fog effects."
673 else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == D3DFOG_NONE) {
674 glHint(GL_FOG_HINT, GL_FASTEST);
675 checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
676 context->last_was_foggy_shader = FALSE;
678 switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
679 /* Processed vertices have their fog factor stored in the specular value. Fall too the none case.
680 * If we are drawing untransformed vertices atm, d3ddevice_set_ortho will update the fog
682 case D3DFOG_EXP: {
683 if(!context->last_was_rhw) {
684 glFogi(GL_FOG_MODE, GL_EXP);
685 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
686 if(GL_SUPPORT(EXT_FOG_COORD)) {
687 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
688 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
690 break;
693 case D3DFOG_EXP2: {
694 if(!context->last_was_rhw) {
695 glFogi(GL_FOG_MODE, GL_EXP2);
696 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
697 if(GL_SUPPORT(EXT_FOG_COORD)) {
698 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
699 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
701 break;
704 case D3DFOG_LINEAR: {
705 if(!context->last_was_rhw) {
706 glFogi(GL_FOG_MODE, GL_LINEAR);
707 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
708 if(GL_SUPPORT(EXT_FOG_COORD)) {
709 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
710 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
712 break;
715 case D3DFOG_NONE: {
716 /* Both are none? According to msdn the alpha channel of the specular
717 * color contains a fog factor. Set it in drawStridedSlow.
718 * Same happens with Vertexfog on transformed vertices
720 if(GL_SUPPORT(EXT_FOG_COORD)) {
721 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
722 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
723 glFogi(GL_FOG_MODE, GL_LINEAR);
724 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
725 fogstart = 0xff;
726 fogend = 0x0;
727 } else {
728 /* Disable GL fog, handle this in software in drawStridedSlow */
729 fogenable = FALSE;
731 break;
733 default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
735 } else {
736 glHint(GL_FOG_HINT, GL_NICEST);
737 checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
738 context->last_was_foggy_shader = FALSE;
740 switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
741 case D3DFOG_EXP:
742 glFogi(GL_FOG_MODE, GL_EXP);
743 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
744 if(GL_SUPPORT(EXT_FOG_COORD)) {
745 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
746 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
748 break;
750 case D3DFOG_EXP2:
751 glFogi(GL_FOG_MODE, GL_EXP2);
752 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
753 if(GL_SUPPORT(EXT_FOG_COORD)) {
754 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
755 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
757 break;
759 case D3DFOG_LINEAR:
760 glFogi(GL_FOG_MODE, GL_LINEAR);
761 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
762 if(GL_SUPPORT(EXT_FOG_COORD)) {
763 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
764 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
766 break;
768 case D3DFOG_NONE: /* Won't happen */
769 default:
770 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
774 if(fogenable) {
775 glEnable(GL_FOG);
776 checkGLcall("glEnable GL_FOG");
778 glFogfv(GL_FOG_START, &fogstart);
779 checkGLcall("glFogf(GL_FOG_START, fogstart");
780 TRACE("Fog Start == %f\n", fogstart);
782 glFogfv(GL_FOG_END, &fogend);
783 checkGLcall("glFogf(GL_FOG_END, fogend");
784 TRACE("Fog End == %f\n", fogend);
785 } else {
786 glDisable(GL_FOG);
787 checkGLcall("glDisable GL_FOG");
790 if (GL_SUPPORT(NV_FOG_DISTANCE)) {
791 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
795 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
796 float col[4];
797 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
798 /* Set the default alpha blend color */
799 glFogfv(GL_FOG_COLOR, &col[0]);
800 checkGLcall("glFog GL_FOG_COLOR");
803 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
804 union {
805 DWORD d;
806 float f;
807 } tmpvalue;
808 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
809 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
810 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
813 /* TODO: Merge with primitive type + init_materials()!! */
814 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
815 IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)stateblock->wineD3DDevice;
816 GLenum Parm = 0;
817 WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
818 BOOL isDiffuseSupplied;
820 /* Depends on the decoded vertex declaration to read the existance of diffuse data.
821 * The vertex declaration will call this function if the fixed function pipeline is used.
824 if(isStateDirty(context, STATE_VDECL)) {
825 return;
828 isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
830 if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
831 TRACE("diff %d, amb %d, emis %d, spec %d\n",
832 stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
833 stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
834 stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
835 stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
837 if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
838 if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
839 Parm = GL_AMBIENT_AND_DIFFUSE;
840 } else {
841 Parm = GL_DIFFUSE;
843 } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
844 Parm = GL_AMBIENT;
845 } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
846 Parm = GL_EMISSION;
847 } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
848 Parm = GL_SPECULAR;
852 /* Nothing changed, return. */
853 if (Parm == context->tracking_parm) return;
855 if(!Parm) {
856 glDisable(GL_COLOR_MATERIAL);
857 checkGLcall("glDisable GL_COLOR_MATERIAL");
858 } else {
859 glColorMaterial(GL_FRONT_AND_BACK, Parm);
860 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
861 glEnable(GL_COLOR_MATERIAL);
862 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
865 /* Apparently calls to glMaterialfv are ignored for properties we're
866 * tracking with glColorMaterial, so apply those here. */
867 switch (context->tracking_parm) {
868 case GL_AMBIENT_AND_DIFFUSE:
869 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
870 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
871 checkGLcall("glMaterialfv");
872 break;
874 case GL_DIFFUSE:
875 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
876 checkGLcall("glMaterialfv");
877 break;
879 case GL_AMBIENT:
880 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
881 checkGLcall("glMaterialfv");
882 break;
884 case GL_EMISSION:
885 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
886 checkGLcall("glMaterialfv");
887 break;
889 case GL_SPECULAR:
890 /* Only change material color if specular is enabled, otherwise it is set to black */
891 if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
892 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
893 checkGLcall("glMaterialfv");
894 } else {
895 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
896 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
897 checkGLcall("glMaterialfv");
899 break;
902 context->tracking_parm = Parm;
905 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
906 union {
907 DWORD d;
908 WINED3DLINEPATTERN lp;
909 } tmppattern;
910 tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
912 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
914 if (tmppattern.lp.wRepeatFactor) {
915 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
916 checkGLcall("glLineStipple(repeat, linepattern)");
917 glEnable(GL_LINE_STIPPLE);
918 checkGLcall("glEnable(GL_LINE_STIPPLE);");
919 } else {
920 glDisable(GL_LINE_STIPPLE);
921 checkGLcall("glDisable(GL_LINE_STIPPLE);");
925 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
926 union {
927 DWORD d;
928 float f;
929 } tmpvalue;
931 if (stateblock->renderState[WINED3DRS_ZBIAS]) {
932 tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
933 TRACE("ZBias value %f\n", tmpvalue.f);
934 glPolygonOffset(0, -tmpvalue.f);
935 checkGLcall("glPolygonOffset(0, -Value)");
936 glEnable(GL_POLYGON_OFFSET_FILL);
937 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
938 glEnable(GL_POLYGON_OFFSET_LINE);
939 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
940 glEnable(GL_POLYGON_OFFSET_POINT);
941 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
942 } else {
943 glDisable(GL_POLYGON_OFFSET_FILL);
944 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
945 glDisable(GL_POLYGON_OFFSET_LINE);
946 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
947 glDisable(GL_POLYGON_OFFSET_POINT);
948 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
953 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
954 if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
955 glEnable(GL_NORMALIZE);
956 checkGLcall("glEnable(GL_NORMALIZE);");
957 } else {
958 glDisable(GL_NORMALIZE);
959 checkGLcall("glDisable(GL_NORMALIZE);");
963 static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
964 union {
965 DWORD d;
966 float f;
967 } tmpvalue;
969 /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
970 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
971 TRACE("Set point size to %f\n", tmpvalue.f);
972 glPointSize(tmpvalue.f);
973 checkGLcall("glPointSize(...);");
976 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
977 union {
978 DWORD d;
979 float f;
980 } tmpvalue;
982 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
983 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
984 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
985 checkGLcall("glPointParameterfARB(...");
987 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
988 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
989 checkGLcall("glPointParameterfEXT(...);");
990 } else if(tmpvalue.f != 1.0) {
991 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
995 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
996 union {
997 DWORD d;
998 float f;
999 } tmpvalue;
1001 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1002 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1003 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
1004 checkGLcall("glPointParameterfARB(...");
1006 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1007 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
1008 checkGLcall("glPointParameterfEXT(...);");
1009 } else if(tmpvalue.f != 64.0) {
1010 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1014 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1015 /* TODO: Group this with the viewport */
1017 * POINTSCALEENABLE controls how point size value is treated. If set to
1018 * true, the point size is scaled with respect to height of viewport.
1019 * When set to false point size is in pixels.
1021 * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
1024 /* Default values */
1025 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1028 * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
1029 * This means that OpenGL will clamp really small point sizes to 1.0f.
1030 * To correct for this we need to multiply by the scale factor when sizes
1031 * are less than 1.0f. scale_factor = 1.0f / point_size.
1033 GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
1034 if(pointSize > 0.0f) {
1035 GLfloat scaleFactor;
1037 if(pointSize < 1.0f) {
1038 scaleFactor = pointSize * pointSize;
1039 } else {
1040 scaleFactor = 1.0f;
1043 if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1044 att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
1045 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1046 att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
1047 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1048 att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
1049 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1053 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1054 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1055 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
1057 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1058 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1059 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
1060 } else {
1061 TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
1065 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1066 DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1068 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1069 Value & D3DCOLORWRITEENABLE_RED ? 1 : 0,
1070 Value & D3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1071 Value & D3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1072 Value & D3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1073 glColorMask(Value & D3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1074 Value & D3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1075 Value & D3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1076 Value & D3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1077 checkGLcall("glColorMask(...)");
1079 /* depends on WINED3DRS_COLORWRITEENABLE. */
1080 if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1081 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1082 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1083 ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1084 stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1085 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1086 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1090 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1091 if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1092 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1093 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1094 } else {
1095 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1096 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1100 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1101 if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1102 TRACE("Last Pixel Drawing Enabled\n");
1103 } else {
1104 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1108 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1109 unsigned int i;
1110 int val;
1112 /* TODO: NV_POINT_SPRITE */
1113 if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1114 TRACE("Point sprites not supported\n");
1115 return;
1118 if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1119 val = GL_TRUE;
1120 } else {
1121 val = GL_FALSE;
1124 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
1125 /* Note the WINED3DRS value applies to all textures, but GL has one
1126 * per texture, so apply it now ready to be used!
1128 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1129 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
1130 checkGLcall("glActiveTextureARB");
1131 } else if (i==1) {
1132 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1133 break;
1136 glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, val);
1137 checkGLcall((val?"glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)":
1138 "glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE)"));
1142 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1144 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1145 http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/FixedFunction/Textures/texturewrapping.asp
1146 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1147 Descussion that ways to turn on WRAPing to solve an opengl conversion problem.
1148 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1150 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1152 TRACE("Stub\n");
1153 if(stateblock->renderState[WINED3DRS_WRAP0] ||
1154 stateblock->renderState[WINED3DRS_WRAP1] ||
1155 stateblock->renderState[WINED3DRS_WRAP2] ||
1156 stateblock->renderState[WINED3DRS_WRAP3] ||
1157 stateblock->renderState[WINED3DRS_WRAP4] ||
1158 stateblock->renderState[WINED3DRS_WRAP5] ||
1159 stateblock->renderState[WINED3DRS_WRAP6] ||
1160 stateblock->renderState[WINED3DRS_WRAP7] ||
1161 stateblock->renderState[WINED3DRS_WRAP8] ||
1162 stateblock->renderState[WINED3DRS_WRAP9] ||
1163 stateblock->renderState[WINED3DRS_WRAP10] ||
1164 stateblock->renderState[WINED3DRS_WRAP11] ||
1165 stateblock->renderState[WINED3DRS_WRAP12] ||
1166 stateblock->renderState[WINED3DRS_WRAP13] ||
1167 stateblock->renderState[WINED3DRS_WRAP14] ||
1168 stateblock->renderState[WINED3DRS_WRAP15] ) {
1169 ERR("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1173 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1174 if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1175 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1176 glEnable(GL_MULTISAMPLE_ARB);
1177 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1178 } else {
1179 glDisable(GL_MULTISAMPLE_ARB);
1180 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1182 } else {
1183 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1184 ERR("Multisample antialiasing not supported by gl\n");
1189 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1190 if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1191 glEnable(GL_SCISSOR_TEST);
1192 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1193 } else {
1194 glDisable(GL_SCISSOR_TEST);
1195 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1199 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1200 union {
1201 DWORD d;
1202 float f;
1203 } tmpvalue;
1205 if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1206 stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1207 tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1208 glEnable(GL_POLYGON_OFFSET_FILL);
1209 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1210 glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1211 checkGLcall("glPolygonOffset(...)");
1212 } else {
1213 glDisable(GL_POLYGON_OFFSET_FILL);
1214 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1218 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1219 if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1220 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1221 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1222 } else {
1223 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1224 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1228 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1229 TRACE("Stub\n");
1230 if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1231 ERR(" Stippled Alpha not supported yet.\n");
1234 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1235 TRACE("Stub\n");
1236 if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1237 ERR(" Antialias not supported yet.\n");
1240 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1241 TRACE("Stub\n");
1242 if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1243 ERR("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1246 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1247 TRACE("Stub\n");
1248 if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != D3DPATCHEDGE_DISCRETE)
1249 ERR("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1252 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1253 union {
1254 DWORD d;
1255 float f;
1256 } tmpvalue;
1257 tmpvalue.f = 1.0f;
1259 TRACE("Stub\n");
1260 if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1261 ERR("(WINED3DRS_PATCHSEGMENTS,%d) not yet implemented\n", tmpvalue.d);
1264 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1265 TRACE("Stub\n");
1266 if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != D3DDEGREE_CUBIC)
1267 ERR("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1270 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1271 TRACE("Stub\n");
1272 if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != D3DDEGREE_LINEAR)
1273 ERR("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1276 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1277 TRACE("Stub\n");
1278 if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1279 FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1283 static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1284 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
1285 ERR("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
1288 static void state_seperateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1289 TRACE("Stub\n");
1290 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
1291 FIXME("(WINED3DRS_SEPARATEALPHABLENDENABLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]);
1294 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1295 if(stateblock->renderState[WINED3DRS_WRAPU]) {
1296 FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1300 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1301 if(stateblock->renderState[WINED3DRS_WRAPV]) {
1302 FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1306 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1307 if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1308 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1312 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1313 if(stateblock->renderState[WINED3DRS_ROP2]) {
1314 FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1318 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1319 if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1320 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1324 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1325 if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1326 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1330 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1331 if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1332 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1336 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1337 if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1338 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1342 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1343 if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1344 FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1348 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1349 if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1350 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1354 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1355 if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1356 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1360 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1361 if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1362 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1366 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1367 if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1368 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1372 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1373 if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1374 FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1378 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1379 if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1380 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1384 /* Activates the texture dimension according to the bound D3D texture.
1385 * Does not care for the colorop or correct gl texture unit(when using nvrc)
1386 * Requires the caller to activate the correct unit before
1388 static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock) {
1389 if(stateblock->textures[stage]) {
1390 glDisable(GL_TEXTURE_1D);
1391 checkGLcall("glDisable(GL_TEXTURE_1D)");
1392 switch(stateblock->textureDimensions[stage]) {
1393 case GL_TEXTURE_2D:
1394 glDisable(GL_TEXTURE_3D);
1395 checkGLcall("glDisable(GL_TEXTURE_3D)");
1396 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1397 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1398 glEnable(GL_TEXTURE_2D);
1399 checkGLcall("glEnable(GL_TEXTURE_2D)");
1400 break;
1401 case GL_TEXTURE_3D:
1402 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1403 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1404 glDisable(GL_TEXTURE_2D);
1405 checkGLcall("glDisable(GL_TEXTURE_2D)");
1406 glEnable(GL_TEXTURE_3D);
1407 checkGLcall("glEnable(GL_TEXTURE_3D)");
1408 break;
1409 case GL_TEXTURE_CUBE_MAP_ARB:
1410 glDisable(GL_TEXTURE_2D);
1411 checkGLcall("glDisable(GL_TEXTURE_2D)");
1412 glDisable(GL_TEXTURE_3D);
1413 checkGLcall("glDisable(GL_TEXTURE_3D)");
1414 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
1415 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
1416 break;
1418 } else {
1419 glDisable(GL_TEXTURE_2D);
1420 checkGLcall("glDisable(GL_TEXTURE_2D)");
1421 glDisable(GL_TEXTURE_3D);
1422 checkGLcall("glDisable(GL_TEXTURE_3D)");
1423 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1424 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1425 glEnable(GL_TEXTURE_1D);
1426 checkGLcall("glEnable(GL_TEXTURE_1D)");
1427 /* Binding textures is done by samplers. A dummy texture will be bound */
1431 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1432 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1433 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1435 TRACE("Setting color op for stage %d\n", stage);
1437 if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1438 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1439 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1440 return;
1443 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1445 if (mapped_stage != -1) {
1446 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1447 if (mapped_stage >= GL_LIMITS(sampler_stages)) {
1448 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1449 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1450 FIXME("Attempt to enable unsupported stage!\n");
1452 return;
1454 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1455 checkGLcall("glActiveTextureARB");
1456 } else if (stage > 0) {
1457 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1458 return;
1462 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1463 if(stateblock->lowest_disabled_stage > 0) {
1464 glEnable(GL_REGISTER_COMBINERS_NV);
1465 GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, stateblock->lowest_disabled_stage));
1466 } else {
1467 glDisable(GL_REGISTER_COMBINERS_NV);
1470 if(stage >= stateblock->lowest_disabled_stage) {
1471 TRACE("Stage disabled\n");
1472 if (mapped_stage != -1) {
1473 /* Disable everything here */
1474 glDisable(GL_TEXTURE_1D);
1475 checkGLcall("glDisable(GL_TEXTURE_1D)");
1476 glDisable(GL_TEXTURE_2D);
1477 checkGLcall("glDisable(GL_TEXTURE_2D)");
1478 glDisable(GL_TEXTURE_3D);
1479 checkGLcall("glDisable(GL_TEXTURE_3D)");
1480 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1481 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1483 /* All done */
1484 return;
1487 /* The sampler will also activate the correct texture dimensions, so no need to do it here
1488 * if the sampler for this stage is dirty
1490 if(!isStateDirty(context, STATE_SAMPLER(stage))) {
1491 if (mapped_stage != -1) activate_dimensions(stage, stateblock);
1494 /* Set the texture combiners */
1495 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1496 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1497 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1498 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1499 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1500 stateblock->textureState[stage][WINED3DTSS_COLORARG0],
1501 mapped_stage);
1502 } else {
1503 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1504 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1505 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1506 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1507 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1511 static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1512 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1513 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1515 TRACE("Setting alpha op for stage %d\n", stage);
1516 /* Do not care for enabled / disabled stages, just assign the settigns. colorop disables / enables required stuff */
1517 if (mapped_stage != -1) {
1518 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1519 if (stage >= GL_LIMITS(sampler_stages)) {
1520 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1521 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1522 FIXME("Attempt to enable unsupported stage!\n");
1524 return;
1526 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1527 checkGLcall("glActiveTextureARB");
1528 } else if (stage > 0) {
1529 /* We can't do anything here */
1530 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1531 return;
1535 TRACE("Setting alpha op for stage %d\n", stage);
1536 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1537 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1538 stateblock->textureState[stage][WINED3DTSS_ALPHAOP],
1539 stateblock->textureState[stage][WINED3DTSS_ALPHAARG1],
1540 stateblock->textureState[stage][WINED3DTSS_ALPHAARG2],
1541 stateblock->textureState[stage][WINED3DTSS_ALPHAARG0],
1542 mapped_stage);
1543 } else {
1544 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage, stateblock->textureState[stage][WINED3DTSS_ALPHAOP],
1545 stateblock->textureState[stage][WINED3DTSS_ALPHAARG1],
1546 stateblock->textureState[stage][WINED3DTSS_ALPHAARG2],
1547 stateblock->textureState[stage][WINED3DTSS_ALPHAARG0]);
1551 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1552 DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1554 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1555 if(texUnit >= GL_LIMITS(sampler_stages)) {
1556 return;
1558 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stateblock->wineD3DDevice->texUnitMap[texUnit]));
1559 checkGLcall("glActiveTextureARB");
1560 } else if (texUnit > 0) {
1561 /* We can't do anything here */
1562 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1563 return;
1566 set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1567 stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1568 (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU);
1572 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd);
1574 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1575 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1576 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1578 if (mapped_stage == -1) {
1579 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
1580 return;
1583 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1584 if(stage >= GL_LIMITS(sampler_stages)) {
1585 return;
1587 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1588 checkGLcall("glActiveTextureARB");
1589 } else if (stage > 0) {
1590 /* We can't do anything here */
1591 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1592 return;
1595 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
1597 * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
1598 * one flag, you can still specify an index value, which the system uses to
1599 * determine the texture wrapping mode.
1600 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
1601 * means use the vertex position (camera-space) as the input texture coordinates
1602 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
1603 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
1604 * to the TEXCOORDINDEX value
1608 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
1610 switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
1611 case WINED3DTSS_TCI_PASSTHRU:
1612 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
1613 glDisable(GL_TEXTURE_GEN_S);
1614 glDisable(GL_TEXTURE_GEN_T);
1615 glDisable(GL_TEXTURE_GEN_R);
1616 glDisable(GL_TEXTURE_GEN_Q);
1617 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
1618 break;
1620 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
1621 /* CameraSpacePosition means use the vertex position, transformed to camera space,
1622 * as the input texture coordinates for this stage's texture transformation. This
1623 * equates roughly to EYE_LINEAR
1626 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1627 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1628 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1629 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1630 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
1632 glMatrixMode(GL_MODELVIEW);
1633 glPushMatrix();
1634 glLoadIdentity();
1635 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1636 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1637 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1638 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1639 glPopMatrix();
1641 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
1642 glEnable(GL_TEXTURE_GEN_S);
1643 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1644 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1645 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1646 glEnable(GL_TEXTURE_GEN_T);
1647 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1648 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1649 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1650 glEnable(GL_TEXTURE_GEN_R);
1651 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1652 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1653 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1655 break;
1657 case WINED3DTSS_TCI_CAMERASPACENORMAL:
1659 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1660 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1661 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1662 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1663 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1664 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
1666 glMatrixMode(GL_MODELVIEW);
1667 glPushMatrix();
1668 glLoadIdentity();
1669 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1670 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1671 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1672 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1673 glPopMatrix();
1675 glEnable(GL_TEXTURE_GEN_S);
1676 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1677 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1678 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1679 glEnable(GL_TEXTURE_GEN_T);
1680 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1681 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1682 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1683 glEnable(GL_TEXTURE_GEN_R);
1684 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1685 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1686 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1689 break;
1691 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
1693 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1694 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1695 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1696 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1697 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1698 TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
1700 glMatrixMode(GL_MODELVIEW);
1701 glPushMatrix();
1702 glLoadIdentity();
1703 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1704 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1705 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1706 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1707 glPopMatrix();
1709 glEnable(GL_TEXTURE_GEN_S);
1710 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1711 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1712 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1713 glEnable(GL_TEXTURE_GEN_T);
1714 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1715 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1716 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1717 glEnable(GL_TEXTURE_GEN_R);
1718 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1719 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1720 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1723 break;
1725 /* Unhandled types: */
1726 default:
1727 /* Todo: */
1728 /* ? disable GL_TEXTURE_GEN_n ? */
1729 glDisable(GL_TEXTURE_GEN_S);
1730 glDisable(GL_TEXTURE_GEN_T);
1731 glDisable(GL_TEXTURE_GEN_R);
1732 glDisable(GL_TEXTURE_GEN_Q);
1733 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
1734 break;
1737 /* Update the texture matrix */
1738 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
1739 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
1742 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
1743 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
1744 * source. Call loadVertexData directly because there is no need to reparse the vertex declaration
1745 * and do all the things linked to it
1746 * TODO: Tidy that up to reload only the arrays of the changed unit
1748 loadVertexData(stateblock, &stateblock->wineD3DDevice->strided_streams);
1752 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1753 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1754 union {
1755 DWORD d;
1756 float f;
1757 } tmpvalue;
1759 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
1760 if(tmpvalue.f != 0.0) {
1761 ERR("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
1765 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1766 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1767 union {
1768 DWORD d;
1769 float f;
1770 } tmpvalue;
1772 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
1773 if(tmpvalue.f != 0.0) {
1774 ERR("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
1778 static void tex_resultarg(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1779 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1781 if(stage >= GL_LIMITS(texture_stages)) {
1782 return;
1785 if(stateblock->textureState[stage][WINED3DTSS_RESULTARG] != D3DTA_CURRENT) {
1786 ERR("WINED3DTSS_RESULTARG not supported yet\n");
1790 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1791 DWORD sampler = state - STATE_SAMPLER(0);
1792 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
1793 union {
1794 float f;
1795 DWORD d;
1796 } tmpvalue;
1798 TRACE("Sampler: %d\n", sampler);
1799 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
1800 * only has to bind textures and set the per texture states
1803 if (mapped_stage == -1) {
1804 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
1805 return;
1808 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1809 if(sampler >= GL_LIMITS(sampler_stages)) {
1810 return;
1812 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1813 checkGLcall("glActiveTextureARB");
1814 } else if (sampler > 0) {
1815 /* We can't do anything here */
1816 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1817 return;
1820 if(stateblock->textures[sampler]) {
1821 BOOL texIsPow2 = FALSE;
1823 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
1824 * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
1825 * scaling is reapplied or removed, the texture matrix has to be reapplied
1827 if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
1828 if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
1829 if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
1830 ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
1831 texIsPow2 = TRUE;
1833 } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
1834 if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
1835 texIsPow2 = TRUE;
1839 if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
1840 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
1841 context->lastWasPow2Texture[sampler] = texIsPow2;
1845 IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
1846 IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
1848 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
1849 tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
1850 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
1851 GL_TEXTURE_LOD_BIAS_EXT,
1852 tmpvalue.f);
1853 checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
1856 if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
1857 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1858 /* Using a pixel shader? Verify the sampler types */
1860 /* Make sure that the texture dimensions are enabled. I don't have to disable the other
1861 * dimensions because the shader knows from which texture type to sample from. For the sake of
1862 * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
1863 * dimensions. This should make wrong sampling sources visible :-)
1865 glEnable(stateblock->textureDimensions[sampler]);
1866 checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
1867 } else if(sampler < stateblock->lowest_disabled_stage) {
1868 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1869 activate_dimensions(sampler, stateblock);
1872 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
1873 /* If color keying is enabled update the alpha test, it depends on the existence
1874 * of a color key in stage 0
1876 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
1879 } else if(sampler < GL_LIMITS(texture_stages)) {
1880 if(sampler < stateblock->lowest_disabled_stage) {
1881 /* TODO: What should I do with pixel shaders here ??? */
1882 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1883 activate_dimensions(sampler, stateblock);
1885 } /* Otherwise tex_colorop disables the stage */
1886 glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
1887 checkGLcall("glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
1891 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1892 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
1894 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
1895 * has an update pending
1897 if(isStateDirty(context, STATE_VDECL) ||
1898 isStateDirty(context, STATE_PIXELSHADER)) {
1899 return;
1902 device->shader_backend->shader_load_constants((IWineD3DDevice *) device,
1903 stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function,
1904 stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function);
1907 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1908 BOOL use_ps = stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function != NULL;
1909 BOOL use_vs = stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL;
1910 int i;
1912 if (use_ps) {
1913 if(!context->last_was_pshader) {
1914 /* Former draw without a pixel shader, some samplers
1915 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
1916 * make sure to enable them
1918 for(i=0; i < MAX_SAMPLERS; i++) {
1919 if(!isStateDirty(context, STATE_SAMPLER(i))) {
1920 sampler(STATE_SAMPLER(i), stateblock, context);
1923 } else {
1924 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
1925 * if a different texture was bound. I don't have to do anything.
1929 /* Compile and bind the shader */
1930 IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
1931 } else {
1932 /* Disabled the pixel shader - color ops weren't applied
1933 * while it was enabled, so re-apply them.
1935 for(i=0; i < MAX_TEXTURES; i++) {
1936 if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
1937 tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
1942 if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
1943 stateblock->wineD3DDevice->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_ps, use_vs);
1945 if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vs || use_ps)) {
1946 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
1950 context->last_was_pshader = use_ps;
1953 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1954 /* This function is called by transform_view below if the view matrix was changed too
1956 * Deliberately no check if the vertex declaration is dirty because the vdecl state
1957 * does not always update the world matrix, only on a switch between transformed
1958 * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
1959 * draw, but that should be rather rare and cheaper in total.
1961 glMatrixMode(GL_MODELVIEW);
1962 checkGLcall("glMatrixMode");
1964 if(context->last_was_rhw) {
1965 glLoadIdentity();
1966 checkGLcall("glLoadIdentity()");
1967 } else {
1968 /* In the general case, the view matrix is the identity matrix */
1969 if (stateblock->wineD3DDevice->view_ident) {
1970 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
1971 checkGLcall("glLoadMatrixf");
1972 } else {
1973 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
1974 checkGLcall("glLoadMatrixf");
1975 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
1976 checkGLcall("glMultMatrixf");
1981 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1982 unsigned int k;
1984 /* If we are changing the View matrix, reset the light and clipping planes to the new view
1985 * NOTE: We have to reset the positions even if the light/plane is not currently
1986 * enabled, since the call to enable it will not reset the position.
1987 * NOTE2: Apparently texture transforms do NOT need reapplying
1990 PLIGHTINFOEL *light = NULL;
1992 glMatrixMode(GL_MODELVIEW);
1993 checkGLcall("glMatrixMode(GL_MODELVIEW)");
1994 glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
1995 checkGLcall("glLoadMatrixf(...)");
1997 /* Reset lights. TODO: Call light apply func */
1998 for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
1999 light = stateblock->activeLights[k];
2000 if(!light) continue;
2001 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
2002 checkGLcall("glLightfv posn");
2003 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
2004 checkGLcall("glLightfv dirn");
2007 /* Reset Clipping Planes if clipping is enabled. TODO: Call clipplane apply func */
2008 for (k = 0; k < GL_LIMITS(clipplanes); k++) {
2009 glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]);
2010 checkGLcall("glClipPlane");
2013 if(context->last_was_rhw) {
2014 glLoadIdentity();
2015 checkGLcall("glLoadIdentity()");
2016 /* No need to update the world matrix, the identity is fine */
2017 return;
2020 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
2021 * No need to do it here if the state is scheduled for update.
2023 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
2024 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2028 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2029 WARN("World matrix 1 - 255 not supported yet\n");
2032 static const GLfloat invymat[16] = {
2033 1.0f, 0.0f, 0.0f, 0.0f,
2034 0.0f, -1.0f, 0.0f, 0.0f,
2035 0.0f, 0.0f, 1.0f, 0.0f,
2036 0.0f, 0.0f, 0.0f, 1.0f};
2038 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2039 glMatrixMode(GL_PROJECTION);
2040 checkGLcall("glMatrixMode(GL_PROJECTION)");
2041 glLoadIdentity();
2042 checkGLcall("glLoadIdentity");
2044 if(context->last_was_rhw) {
2045 double X, Y, height, width, minZ, maxZ;
2047 X = stateblock->viewport.X;
2048 Y = stateblock->viewport.Y;
2049 height = stateblock->viewport.Height;
2050 width = stateblock->viewport.Width;
2051 minZ = stateblock->viewport.MinZ;
2052 maxZ = stateblock->viewport.MaxZ;
2054 if(!stateblock->wineD3DDevice->untransformed) {
2055 /* Transformed vertices are supposed to bypass the whole transform pipeline including
2056 * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2057 * suppress depth clipping. This can be done because it is an orthogonal projection and
2058 * the Z coordinate does not affect the size of the primitives
2060 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2061 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2062 } else {
2063 /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2064 * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2065 * unmodified to opengl.
2067 * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2068 * replacement shader.
2070 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2071 glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
2073 checkGLcall("glOrtho");
2075 /* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */
2076 glTranslatef(0.375, 0.375, 0);
2077 checkGLcall("glTranslatef(0.375, 0.375, 0)");
2078 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2079 * render everything upside down when rendering offscreen. */
2080 if (stateblock->wineD3DDevice->render_offscreen) {
2081 glMultMatrixf(invymat);
2082 checkGLcall("glMultMatrixf(invymat)");
2084 } else {
2085 /* The rule is that the window coordinate 0 does not correspond to the
2086 beginning of the first pixel, but the center of the first pixel.
2087 As a consequence if you want to correctly draw one line exactly from
2088 the left to the right end of the viewport (with all matrices set to
2089 be identity), the x coords of both ends of the line would be not
2090 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2091 instead. */
2092 glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
2093 checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
2095 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2096 * render everything upside down when rendering offscreen. */
2097 if (stateblock->wineD3DDevice->render_offscreen) {
2098 glMultMatrixf(invymat);
2099 checkGLcall("glMultMatrixf(invymat)");
2101 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2102 checkGLcall("glLoadMatrixf");
2106 /* This should match any arrays loaded in loadVertexData.
2107 * stateblock impl is required for GL_SUPPORT
2108 * TODO: Only load / unload arrays if we have to.
2110 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2111 int texture_idx;
2113 glDisableClientState(GL_VERTEX_ARRAY);
2114 glDisableClientState(GL_NORMAL_ARRAY);
2115 glDisableClientState(GL_COLOR_ARRAY);
2116 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2117 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2119 for (texture_idx = 0; texture_idx < GL_LIMITS(textures); ++texture_idx) {
2120 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2121 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2125 /* This should match any arrays loaded in loadNumberedArrays
2126 * TODO: Only load / unload arrays if we have to.
2128 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2129 /* disable any attribs (this is the same for both GLSL and ARB modes) */
2130 GLint maxAttribs;
2131 int i;
2133 /* Leave all the attribs disabled */
2134 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2135 /* MESA does not support it right not */
2136 if (glGetError() != GL_NO_ERROR)
2137 maxAttribs = 16;
2138 for (i = 0; i < maxAttribs; ++i) {
2139 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2140 checkGLcall("glDisableVertexAttribArrayARB(reg);");
2144 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2145 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2146 int i;
2147 UINT *offset = stateblock->streamOffset;
2149 /* Default to no instancing */
2150 stateblock->wineD3DDevice->instancedDraw = FALSE;
2152 for (i = 0; i < MAX_ATTRIBS; i++) {
2154 if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2155 continue;
2157 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
2158 if(stateblock->streamFlags[strided->u.input[i].streamNo] & D3DSTREAMSOURCE_INSTANCEDATA) {
2159 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2160 stateblock->wineD3DDevice->instancedDraw = TRUE;
2161 continue;
2164 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2166 if(strided->u.input[i].dwStride) {
2167 if(curVBO != strided->u.input[i].VBO) {
2168 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2169 checkGLcall("glBindBufferARB");
2170 curVBO = strided->u.input[i].VBO;
2172 GL_EXTCALL(glVertexAttribPointerARB(i,
2173 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2174 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2175 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2176 strided->u.input[i].dwStride,
2177 strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + offset[strided->u.input[i].streamNo]) );
2178 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2179 } else {
2180 /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
2181 * set up the attribute statically. But we have to figure out the system memory address.
2183 BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
2184 if(strided->u.input[i].VBO) {
2185 IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2186 ptr += (long) vb->resource.allocatedMemory;
2188 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2190 switch(strided->u.input[i].dwType) {
2191 case WINED3DDECLTYPE_FLOAT1:
2192 GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
2193 break;
2194 case WINED3DDECLTYPE_FLOAT2:
2195 GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
2196 break;
2197 case WINED3DDECLTYPE_FLOAT3:
2198 GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
2199 break;
2200 case WINED3DDECLTYPE_FLOAT4:
2201 GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
2202 break;
2204 case WINED3DDECLTYPE_UBYTE4:
2205 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2206 break;
2207 case WINED3DDECLTYPE_UBYTE4N:
2208 case WINED3DDECLTYPE_D3DCOLOR:
2209 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2210 break;
2212 case WINED3DDECLTYPE_SHORT2:
2213 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2214 break;
2215 case WINED3DDECLTYPE_SHORT4:
2216 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2217 break;
2219 case WINED3DDECLTYPE_SHORT2N:
2221 GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
2222 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
2223 break;
2225 case WINED3DDECLTYPE_USHORT2N:
2227 GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
2228 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
2229 break;
2231 case WINED3DDECLTYPE_SHORT4N:
2232 GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
2233 break;
2234 case WINED3DDECLTYPE_USHORT4N:
2235 GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
2236 break;
2238 case WINED3DDECLTYPE_UDEC3:
2239 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
2240 /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
2241 break;
2242 case WINED3DDECLTYPE_DEC3N:
2243 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
2244 /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
2245 break;
2247 case WINED3DDECLTYPE_FLOAT16_2:
2248 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
2249 * byte float according to the IEEE standard
2251 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
2252 break;
2253 case WINED3DDECLTYPE_FLOAT16_4:
2254 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
2255 break;
2257 case WINED3DDECLTYPE_UNUSED:
2258 default:
2259 ERR("Unexpected declaration in stride 0 attributes\n");
2260 break;
2267 /* Used from 2 different functions, and too big to justify making it inlined */
2268 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
2269 unsigned int textureNo = 0;
2270 unsigned int texture_idx = 0;
2271 UINT *offset = stateblock->streamOffset;
2272 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2274 TRACE("Using fast vertex array code\n");
2276 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
2277 stateblock->wineD3DDevice->instancedDraw = FALSE;
2279 /* Blend Data ---------------------------------------------- */
2280 if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
2281 (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
2284 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2286 #if 1
2287 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
2288 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
2289 #endif
2291 TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2292 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2293 /* FIXME("TODO\n");*/
2294 /* Note dwType == float3 or float4 == 2 or 3 */
2296 #if 0
2297 /* with this on, the normals appear to be being modified,
2298 but the vertices aren't being translated as they should be
2299 Maybe the world matrix aren't being setup properly? */
2300 glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1);
2301 #endif
2304 VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
2305 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
2306 sd->u.s.blendWeights.dwStride,
2307 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
2309 if(curVBO != sd->u.s.blendWeights.VBO) {
2310 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
2311 checkGLcall("glBindBufferARB");
2312 curVBO = sd->u.s.blendWeights.VBO;
2315 GL_EXTCALL(glWeightPointerARB)(
2316 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2317 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2318 sd->u.s.blendWeights.dwStride,
2319 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2321 checkGLcall("glWeightPointerARB");
2323 if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
2324 static BOOL showfixme = TRUE;
2325 if(showfixme){
2326 FIXME("blendMatrixIndices support\n");
2327 showfixme = FALSE;
2331 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2332 /* FIXME("TODO\n");*/
2333 #if 0
2335 GL_EXTCALL(glVertexWeightPointerEXT)(
2336 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2337 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2338 sd->u.s.blendWeights.dwStride,
2339 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2340 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
2341 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2342 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2343 #endif
2345 } else {
2346 /* TODO: support blends in fixupVertices */
2347 FIXME("unsupported blending in openGl\n");
2349 } else {
2350 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2351 #if 0 /* TODO: Vertex blending */
2352 glDisable(GL_VERTEX_BLEND_ARB);
2353 #endif
2354 TRACE("ARB_VERTEX_BLEND\n");
2355 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2356 TRACE(" EXT_VERTEX_WEIGHTING\n");
2357 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2358 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2363 #if 0 /* FOG ----------------------------------------------*/
2364 if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
2365 /* TODO: fog*/
2366 if (GL_SUPPORT(EXT_FOG_COORD) {
2367 glEnableClientState(GL_FOG_COORDINATE_EXT);
2368 (GL_EXTCALL)(FogCoordPointerEXT)(
2369 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
2370 sd->u.s.fog.dwStride,
2371 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
2372 } else {
2373 /* don't bother falling back to 'slow' as we don't support software FOG yet. */
2374 /* FIXME: fixme once */
2375 TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
2377 } else {
2378 if (GL_SUPPRT(EXT_FOR_COORD) {
2379 /* make sure fog is disabled */
2380 glDisableClientState(GL_FOG_COORDINATE_EXT);
2383 #endif
2385 #if 0 /* tangents ----------------------------------------------*/
2386 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
2387 sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2388 /* TODO: tangents*/
2389 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2390 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
2391 glEnable(GL_TANGENT_ARRAY_EXT);
2392 (GL_EXTCALL)(TangentPointerEXT)(
2393 WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
2394 sd->u.s.tangent.dwStride,
2395 sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
2396 } else {
2397 glDisable(GL_TANGENT_ARRAY_EXT);
2399 if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2400 glEnable(GL_BINORMAL_ARRAY_EXT);
2401 (GL_EXTCALL)(BinormalPointerEXT)(
2402 WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
2403 sd->u.s.binormal.dwStride,
2404 sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
2405 } else{
2406 glDisable(GL_BINORMAL_ARRAY_EXT);
2409 } else {
2410 /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
2411 /* FIXME: fixme once */
2412 TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
2414 } else {
2415 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2416 /* make sure fog is disabled */
2417 glDisable(GL_TANGENT_ARRAY_EXT);
2418 glDisable(GL_BINORMAL_ARRAY_EXT);
2421 #endif
2423 /* Point Size ----------------------------------------------*/
2424 if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
2426 /* no such functionality in the fixed function GL pipeline */
2427 TRACE("Cannot change ptSize here in openGl\n");
2428 /* TODO: Implement this function in using shaders if they are available */
2432 /* Vertex Pointers -----------------------------------------*/
2433 if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
2434 /* Note dwType == float3 or float4 == 2 or 3 */
2435 VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
2436 sd->u.s.position.dwStride,
2437 sd->u.s.position.dwType + 1,
2438 sd->u.s.position.lpData));
2440 if(curVBO != sd->u.s.position.VBO) {
2441 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
2442 checkGLcall("glBindBufferARB");
2443 curVBO = sd->u.s.position.VBO;
2446 /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
2447 handling for rhw mode should not impact screen position whereas in GL it does.
2448 This may result in very slightly distored textures in rhw mode, but
2449 a very minimal different. There's always the other option of
2450 fixing the view matrix to prevent w from having any effect
2452 This only applies to user pointer sources, in VBOs the vertices are fixed up
2454 if(sd->u.s.position.VBO == 0) {
2455 glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
2456 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2457 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2458 } else {
2459 glVertexPointer(
2460 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
2461 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2462 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2464 checkGLcall("glVertexPointer(...)");
2465 glEnableClientState(GL_VERTEX_ARRAY);
2466 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
2468 } else {
2469 glDisableClientState(GL_VERTEX_ARRAY);
2470 checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
2473 /* Normals -------------------------------------------------*/
2474 if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
2475 /* Note dwType == float3 or float4 == 2 or 3 */
2476 VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
2477 sd->u.s.normal.dwStride,
2478 sd->u.s.normal.lpData));
2479 if(curVBO != sd->u.s.normal.VBO) {
2480 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
2481 checkGLcall("glBindBufferARB");
2482 curVBO = sd->u.s.normal.VBO;
2484 glNormalPointer(
2485 WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
2486 sd->u.s.normal.dwStride,
2487 sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
2488 checkGLcall("glNormalPointer(...)");
2489 glEnableClientState(GL_NORMAL_ARRAY);
2490 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
2492 } else {
2493 glDisableClientState(GL_NORMAL_ARRAY);
2494 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
2495 glNormal3f(0, 0, 1);
2496 checkGLcall("glNormal3f(0, 0, 1)");
2499 /* Diffuse Colour --------------------------------------------*/
2500 /* WARNING: Data here MUST be in RGBA format, so cannot */
2501 /* go directly into fast mode from app pgm, because */
2502 /* directx requires data in BGRA format. */
2503 /* currently fixupVertices swizels the format, but this isn't */
2504 /* very practical when using VBOS */
2505 /* NOTE: Unless we write a vertex shader to swizel the colour */
2506 /* , or the user doesn't care and wants the speed advantage */
2508 if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
2509 /* Note dwType == float3 or float4 == 2 or 3 */
2510 VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2511 sd->u.s.diffuse.dwStride,
2512 sd->u.s.diffuse.lpData));
2514 if(curVBO != sd->u.s.diffuse.VBO) {
2515 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
2516 checkGLcall("glBindBufferARB");
2517 curVBO = sd->u.s.diffuse.VBO;
2519 glColorPointer(4, GL_UNSIGNED_BYTE,
2520 sd->u.s.diffuse.dwStride,
2521 sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
2522 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
2523 glEnableClientState(GL_COLOR_ARRAY);
2524 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
2526 } else {
2527 glDisableClientState(GL_COLOR_ARRAY);
2528 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
2529 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2530 checkGLcall("glColor4f(1, 1, 1, 1)");
2533 /* Specular Colour ------------------------------------------*/
2534 if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
2535 TRACE("setting specular colour\n");
2536 /* Note dwType == float3 or float4 == 2 or 3 */
2537 VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2538 sd->u.s.specular.dwStride,
2539 sd->u.s.specular.lpData));
2540 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2541 if(curVBO != sd->u.s.specular.VBO) {
2542 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
2543 checkGLcall("glBindBufferARB");
2544 curVBO = sd->u.s.specular.VBO;
2546 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
2547 sd->u.s.specular.dwStride,
2548 sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
2549 vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
2550 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2551 vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2552 } else {
2554 /* Missing specular color is not critical, no warnings */
2555 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2558 } else {
2559 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2561 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2562 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2563 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
2564 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
2565 } else {
2567 /* Missing specular color is not critical, no warnings */
2568 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2572 /* Texture coords -------------------------------------------*/
2574 for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
2575 /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
2576 /* Abort if we don't support the extension. */
2577 if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
2578 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2579 continue;
2582 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) {
2583 /* Select the correct texture stage */
2584 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2587 if (stateblock->textures[textureNo] != NULL) {
2588 int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
2590 if (coordIdx >= MAX_TEXTURES) {
2591 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
2592 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2593 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2595 } else if (sd->u.s.texCoords[coordIdx].lpData == NULL && sd->u.s.texCoords[coordIdx].VBO == 0) {
2596 VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
2597 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2598 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2600 } else {
2601 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
2602 textureNo, texture_idx, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
2603 if(curVBO != sd->u.s.texCoords[coordIdx].VBO) {
2604 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
2605 checkGLcall("glBindBufferARB");
2606 curVBO = sd->u.s.texCoords[coordIdx].VBO;
2608 /* The coords to supply depend completely on the fvf / vertex shader */
2609 glTexCoordPointer(
2610 WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
2611 WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
2612 sd->u.s.texCoords[coordIdx].dwStride,
2613 sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
2614 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2616 } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2617 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2618 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2620 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) ++texture_idx;
2622 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2623 for (textureNo = texture_idx; textureNo < GL_LIMITS(textures); ++textureNo) {
2624 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
2625 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2626 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2631 inline void drawPrimitiveTraceDataLocations(
2632 WineDirect3DVertexStridedData *dataLocations) {
2634 /* Dump out what parts we have supplied */
2635 TRACE("Strided Data:\n");
2636 TRACE_STRIDED((dataLocations), position);
2637 TRACE_STRIDED((dataLocations), blendWeights);
2638 TRACE_STRIDED((dataLocations), blendMatrixIndices);
2639 TRACE_STRIDED((dataLocations), normal);
2640 TRACE_STRIDED((dataLocations), pSize);
2641 TRACE_STRIDED((dataLocations), diffuse);
2642 TRACE_STRIDED((dataLocations), specular);
2643 TRACE_STRIDED((dataLocations), texCoords[0]);
2644 TRACE_STRIDED((dataLocations), texCoords[1]);
2645 TRACE_STRIDED((dataLocations), texCoords[2]);
2646 TRACE_STRIDED((dataLocations), texCoords[3]);
2647 TRACE_STRIDED((dataLocations), texCoords[4]);
2648 TRACE_STRIDED((dataLocations), texCoords[5]);
2649 TRACE_STRIDED((dataLocations), texCoords[6]);
2650 TRACE_STRIDED((dataLocations), texCoords[7]);
2651 TRACE_STRIDED((dataLocations), position2);
2652 TRACE_STRIDED((dataLocations), normal2);
2653 TRACE_STRIDED((dataLocations), tangent);
2654 TRACE_STRIDED((dataLocations), binormal);
2655 TRACE_STRIDED((dataLocations), tessFactor);
2656 TRACE_STRIDED((dataLocations), fog);
2657 TRACE_STRIDED((dataLocations), depth);
2658 TRACE_STRIDED((dataLocations), sample);
2660 return;
2663 /* Helper for vertexdeclaration() */
2664 static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction, WineD3DContext *context) {
2665 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2666 BOOL fixup = FALSE;
2667 WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
2669 if(device->up_strided) {
2670 /* Note: this is a ddraw fixed-function code path */
2671 TRACE("================ Strided Input ===================\n");
2672 memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
2674 if(TRACE_ON(d3d)) {
2675 drawPrimitiveTraceDataLocations(dataLocations);
2677 } else if (stateblock->vertexDecl || stateblock->vertexShader) {
2678 /* Note: This is a fixed function or shader codepath.
2679 * This means it must handle both types of strided data.
2680 * Shaders must go through here to zero the strided data, even if they
2681 * don't set any declaration at all
2683 TRACE("================ Vertex Declaration ===================\n");
2684 memset(dataLocations, 0, sizeof(*dataLocations));
2686 if (stateblock->vertexDecl) {
2687 primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
2688 dataLocations, &fixup);
2690 } else {
2691 /* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
2692 * It is reachable through d3d8, but only for fixed-function.
2693 * It will not work properly for shaders.
2695 TRACE("================ FVF ===================\n");
2696 memset(dataLocations, 0, sizeof(*dataLocations));
2697 primitiveConvertToStridedData((IWineD3DDevice *) device, dataLocations, &fixup);
2698 if(TRACE_ON(d3d)) {
2699 drawPrimitiveTraceDataLocations(dataLocations);
2703 /* Unload the old arrays before loading the new ones to get old junk out */
2704 if(context->numberedArraysLoaded) {
2705 unloadNumberedArrays(stateblock);
2706 context->numberedArraysLoaded = FALSE;
2708 if(context->namedArraysLoaded) {
2709 unloadVertexData(stateblock);
2710 context->namedArraysLoaded = FALSE;
2713 if(useVertexShaderFunction) {
2714 TRACE("Loading numbered arrays\n");
2715 loadNumberedArrays(stateblock, dataLocations);
2716 device->useDrawStridedSlow = FALSE;
2717 context->numberedArraysLoaded = TRUE;
2718 } else if (fixup ||
2719 (dataLocations->u.s.pSize.lpData == NULL &&
2720 dataLocations->u.s.diffuse.lpData == NULL &&
2721 dataLocations->u.s.specular.lpData == NULL)) {
2722 /* Load the vertex data using named arrays */
2723 TRACE("Loading vertex data\n");
2724 loadVertexData(stateblock, dataLocations);
2725 device->useDrawStridedSlow = FALSE;
2726 context->namedArraysLoaded = TRUE;
2727 } else {
2728 TRACE("Not loading vertex data\n");
2729 device->useDrawStridedSlow = TRUE;
2732 /* Generate some fixme's if unsupported functionality is being used */
2733 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
2734 /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
2735 if (!useVertexShaderFunction && (BUFFER_OR_DATA(blendMatrixIndices) || BUFFER_OR_DATA(blendWeights))) {
2736 FIXME("Blending data is only valid with vertex shaders %p %p\n",dataLocations->u.s.blendWeights.lpData,dataLocations->u.s.blendWeights.lpData);
2738 if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
2739 FIXME("Tweening is only valid with vertex shaders\n");
2741 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
2742 FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
2744 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
2745 FIXME("Extended attributes are only valid with vertex shaders\n");
2747 #undef BUFFER_OR_DATA
2750 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2751 BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
2752 BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
2753 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
2754 BOOL transformed;
2755 /* Some stuff is in the device until we have per context tracking */
2756 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2757 BOOL wasrhw = context->last_was_rhw;
2759 /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
2760 * here simply check whether a shader was set, or the user disabled shaders
2762 if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
2763 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
2764 useVertexShaderFunction = TRUE;
2766 if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog != context->last_was_foggy_shader) {
2767 updateFog = TRUE;
2769 } else if(context->last_was_foggy_shader) {
2770 updateFog = TRUE;
2773 handleStreams(stateblock, useVertexShaderFunction, context);
2775 /* Do I have to use ? TRUE : FALSE ? Or can I rely on 15==15 being equal to TRUE(=1)? */
2776 transformed = ((device->strided_streams.u.s.position.lpData != NULL ||
2777 device->strided_streams.u.s.position.VBO != 0) &&
2778 device->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
2780 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
2781 updateFog = TRUE;
2784 /* Reapply lighting if it is not sheduled for reapplication already */
2785 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
2786 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
2789 if (!useVertexShaderFunction && transformed) {
2790 context->last_was_rhw = TRUE;
2791 } else {
2793 /* Untransformed, so relies on the view and projection matrices */
2794 context->last_was_rhw = FALSE;
2795 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
2796 device->untransformed = TRUE;
2798 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
2799 * Not needed as long as only hw shaders are supported
2802 /* This sets the shader output position correction constants.
2803 * TODO: Move to the viewport state
2805 if (useVertexShaderFunction) {
2806 device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
2810 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
2811 * off this function will be called again anyway to make sure they're properly set
2813 if(!useVertexShaderFunction) {
2814 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
2815 * or transformed / untransformed was switched
2817 if(wasrhw != context->last_was_rhw &&
2818 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
2819 !isStateDirty(context, STATE_VIEWPORT)) {
2820 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
2822 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
2823 * mode.
2825 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
2826 * this check will fail and the matrix not applied again. This is OK because a simple
2827 * world matrix change reapplies the matrix - These checks here are only to satisfy the
2828 * needs of the vertex declaration.
2830 * World and view matrix go into the same gl matrix, so only apply them when neither is
2831 * dirty
2833 if(transformed != wasrhw &&
2834 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
2835 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2836 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2839 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
2840 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
2842 } else {
2843 /* We compile the shader here because we need the vertex declaration
2844 * in order to determine if we need to do any swizzling for D3DCOLOR
2845 * registers. If the shader is already compiled this call will do nothing. */
2846 IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
2849 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
2850 * application
2852 if (!isStateDirty(context, STATE_PIXELSHADER)) {
2853 device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
2855 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
2856 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
2860 context->last_was_vshader = useVertexShaderFunction;
2862 if(updateFog) {
2863 state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
2867 static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2868 glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
2869 checkGLcall("glDepthRange");
2870 /* Note: GL requires lower left, DirectX supplies upper left */
2871 /* TODO: replace usage of renderTarget with context management */
2872 glViewport(stateblock->viewport.X,
2873 (((IWineD3DSurfaceImpl *)stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height - (stateblock->viewport.Y + stateblock->viewport.Height)),
2874 stateblock->viewport.Width, stateblock->viewport.Height);
2876 checkGLcall("glViewport");
2878 stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
2879 stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
2880 if(!isStateDirty(context, STATE_TRANSFORM(D3DTS_PROJECTION))) {
2881 transform_projection(STATE_TRANSFORM(D3DTS_PROJECTION), stateblock, context);
2886 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2887 UINT Index = state - STATE_ACTIVELIGHT(0);
2888 PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
2890 if(!lightInfo) {
2891 glDisable(GL_LIGHT0 + Index);
2892 checkGLcall("glDisable(GL_LIGHT0 + Index)");
2893 } else {
2894 float quad_att;
2895 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
2897 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2898 glMatrixMode(GL_MODELVIEW);
2899 glPushMatrix();
2900 glLoadMatrixf((float *)&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2902 /* Diffuse: */
2903 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
2904 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
2905 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
2906 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
2907 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
2908 checkGLcall("glLightfv");
2910 /* Specular */
2911 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
2912 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
2913 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
2914 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
2915 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
2916 checkGLcall("glLightfv");
2918 /* Ambient */
2919 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
2920 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
2921 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
2922 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
2923 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
2924 checkGLcall("glLightfv");
2926 /* Attenuation - Are these right? guessing... */
2927 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
2928 checkGLcall("glLightf");
2929 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
2930 checkGLcall("glLightf");
2932 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
2933 quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
2934 } else {
2935 quad_att = 0; /* 0 or MAX? (0 seems to be ok) */
2938 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
2939 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
2940 checkGLcall("glLightf");
2942 switch (lightInfo->OriginalParms.Type) {
2943 case WINED3DLIGHT_POINT:
2944 /* Position */
2945 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
2946 checkGLcall("glLightfv");
2947 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
2948 checkGLcall("glLightf");
2949 /* FIXME: Range */
2950 break;
2952 case WINED3DLIGHT_SPOT:
2953 /* Position */
2954 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
2955 checkGLcall("glLightfv");
2956 /* Direction */
2957 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
2958 checkGLcall("glLightfv");
2959 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
2960 checkGLcall("glLightf");
2961 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
2962 checkGLcall("glLightf");
2963 /* FIXME: Range */
2964 break;
2966 case WINED3DLIGHT_DIRECTIONAL:
2967 /* Direction */
2968 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
2969 checkGLcall("glLightfv");
2970 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
2971 checkGLcall("glLightf");
2972 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
2973 checkGLcall("glLightf");
2974 break;
2976 default:
2977 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
2980 /* Restore the modelview matrix */
2981 glPopMatrix();
2983 glEnable(GL_LIGHT0 + Index);
2984 checkGLcall("glEnable(GL_LIGHT0 + Index)");
2987 return;
2990 const struct StateEntry StateTable[] =
2992 /* State name representative, apply function */
2993 { /* 0, Undefined */ 0, state_undefined },
2994 { /* 1, WINED3DRS_TEXTUREHANDLE */ 0 /* Handled in ddraw */, state_undefined },
2995 { /* 2, WINED3DRS_ANTIALIAS */ STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias },
2996 { /* 3, WINED3DRS_TEXTUREADDRESS */ 0 /* Handled in ddraw */, state_undefined },
2997 { /* 4, WINED3DRS_TEXTUREPERSPECTIVE */ STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective },
2998 { /* 5, WINED3DRS_WRAPU */ STATE_RENDER(WINED3DRS_WRAPU), state_wrapu },
2999 { /* 6, WINED3DRS_WRAPV */ STATE_RENDER(WINED3DRS_WRAPV), state_wrapv },
3000 { /* 7, WINED3DRS_ZENABLE */ STATE_RENDER(WINED3DRS_ZENABLE), state_zenable },
3001 { /* 8, WINED3DRS_FILLMODE */ STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode },
3002 { /* 9, WINED3DRS_SHADEMODE */ STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode },
3003 { /* 10, WINED3DRS_LINEPATTERN */ STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern },
3004 { /* 11, WINED3DRS_MONOENABLE */ STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable },
3005 { /* 12, WINED3DRS_ROP2 */ STATE_RENDER(WINED3DRS_ROP2), state_rop2 },
3006 { /* 13, WINED3DRS_PLANEMASK */ STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask },
3007 { /* 14, WINED3DRS_ZWRITEENABLE */ STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable },
3008 { /* 15, WINED3DRS_ALPHATESTENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3009 { /* 16, WINED3DRS_LASTPIXEL */ STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel },
3010 { /* 17, WINED3DRS_TEXTUREMAG */ 0 /* Handled in ddraw */, state_undefined },
3011 { /* 18, WINED3DRS_TEXTUREMIN */ 0 /* Handled in ddraw */, state_undefined },
3012 { /* 19, WINED3DRS_SRCBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3013 { /* 20, WINED3DRS_DESTBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3014 { /* 21, WINED3DRS_TEXTUREMAPBLEND */ 0 /* Handled in ddraw */, state_undefined },
3015 { /* 22, WINED3DRS_CULLMODE */ STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode },
3016 { /* 23, WINED3DRS_ZFUNC */ STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc },
3017 { /* 24, WINED3DRS_ALPHAREF */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3018 { /* 25, WINED3DRS_ALPHAFUNC */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3019 { /* 26, WINED3DRS_DITHERENABLE */ STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable },
3020 { /* 27, WINED3DRS_ALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3021 { /* 28, WINED3DRS_FOGENABLE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3022 { /* 29, WINED3DRS_SPECULARENABLE */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},
3023 { /* 30, WINED3DRS_ZVISIBLE */ 0 /* Not supported according to the msdn */, state_nogl },
3024 { /* 31, WINED3DRS_SUBPIXEL */ STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel },
3025 { /* 32, WINED3DRS_SUBPIXELX */ STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx },
3026 { /* 33, WINED3DRS_STIPPLEDALPHA */ STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha },
3027 { /* 34, WINED3DRS_FOGCOLOR */ STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor },
3028 { /* 35, WINED3DRS_FOGTABLEMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3029 { /* 36, WINED3DRS_FOGSTART */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3030 { /* 37, WINED3DRS_FOGEND */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3031 { /* 38, WINED3DRS_FOGDENSITY */ STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity },
3032 { /* 39, WINED3DRS_STIPPLEENABLE */ STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable },
3033 { /* 40, WINED3DRS_EDGEANTIALIAS */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3034 { /* 41, WINED3DRS_COLORKEYENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3035 { /* 42, undefined */ 0, state_undefined },
3036 { /* 43, WINED3DRS_BORDERCOLOR */ STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor },
3037 { /* 44, WINED3DRS_TEXTUREADDRESSU */ 0, /* Handled in ddraw */ state_undefined },
3038 { /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined },
3039 { /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias },
3040 { /* 47, WINED3DRS_ZBIAS */ STATE_RENDER(WINED3DRS_ZBIAS), state_zbias },
3041 { /* 48, WINED3DRS_RANGEFOGENABLE */ 0, state_nogl },
3042 { /* 49, WINED3DRS_ANISOTROPY */ STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy },
3043 { /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch },
3044 { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT */ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
3045 { /* 52, WINED3DRS_STENCILENABLE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3046 { /* 53, WINED3DRS_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3047 { /* 54, WINED3DRS_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3048 { /* 55, WINED3DRS_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3049 { /* 56, WINED3DRS_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3050 { /* 57, WINED3DRS_STENCILREF */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3051 { /* 58, WINED3DRS_STENCILMASK */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3052 { /* 59, WINED3DRS_STENCILWRITEMASK */ STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite },
3053 { /* 60, WINED3DRS_TEXTUREFACTOR */ STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor },
3054 { /* 61, Undefined */ 0, state_undefined },
3055 { /* 62, Undefined */ 0, state_undefined },
3056 { /* 63, Undefined */ 0, state_undefined },
3057 { /* 64, WINED3DRS_STIPPLEPATTERN00 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3058 { /* 65, WINED3DRS_STIPPLEPATTERN01 */ 0 /* Obsolete, should he handled by ddraw */, state_undefined },
3059 { /* 66, WINED3DRS_STIPPLEPATTERN02 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3060 { /* 67, WINED3DRS_STIPPLEPATTERN03 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3061 { /* 68, WINED3DRS_STIPPLEPATTERN04 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3062 { /* 69, WINED3DRS_STIPPLEPATTERN05 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3063 { /* 70, WINED3DRS_STIPPLEPATTERN06 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3064 { /* 71, WINED3DRS_STIPPLEPATTERN07 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3065 { /* 72, WINED3DRS_STIPPLEPATTERN08 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3066 { /* 73, WINED3DRS_STIPPLEPATTERN09 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3067 { /* 74, WINED3DRS_STIPPLEPATTERN10 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3068 { /* 75, WINED3DRS_STIPPLEPATTERN11 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3069 { /* 76, WINED3DRS_STIPPLEPATTERN12 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3070 { /* 77, WINED3DRS_STIPPLEPATTERN13 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3071 { /* 78, WINED3DRS_STIPPLEPATTERN14 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3072 { /* 79, WINED3DRS_STIPPLEPATTERN15 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3073 { /* 80, WINED3DRS_STIPPLEPATTERN16 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3074 { /* 81, WINED3DRS_STIPPLEPATTERN17 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3075 { /* 82, WINED3DRS_STIPPLEPATTERN18 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3076 { /* 83, WINED3DRS_STIPPLEPATTERN19 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3077 { /* 84, WINED3DRS_STIPPLEPATTERN20 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3078 { /* 85, WINED3DRS_STIPPLEPATTERN21 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3079 { /* 86, WINED3DRS_STIPPLEPATTERN22 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3080 { /* 87, WINED3DRS_STIPPLEPATTERN23 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3081 { /* 88, WINED3DRS_STIPPLEPATTERN24 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3082 { /* 89, WINED3DRS_STIPPLEPATTERN25 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3083 { /* 90, WINED3DRS_STIPPLEPATTERN26 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3084 { /* 91, WINED3DRS_STIPPLEPATTERN27 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3085 { /* 92, WINED3DRS_STIPPLEPATTERN28 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3086 { /* 93, WINED3DRS_STIPPLEPATTERN29 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3087 { /* 94, WINED3DRS_STIPPLEPATTERN30 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3088 { /* 95, WINED3DRS_STIPPLEPATTERN31 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3089 { /* 96, Undefined */ 0, state_undefined },
3090 { /* 97, Undefined */ 0, state_undefined },
3091 { /* 98, Undefined */ 0, state_undefined },
3092 { /* 99, Undefined */ 0, state_undefined },
3093 { /*100, Undefined */ 0, state_undefined },
3094 { /*101, Undefined */ 0, state_undefined },
3095 { /*102, Undefined */ 0, state_undefined },
3096 { /*103, Undefined */ 0, state_undefined },
3097 { /*104, Undefined */ 0, state_undefined },
3098 { /*105, Undefined */ 0, state_undefined },
3099 { /*106, Undefined */ 0, state_undefined },
3100 { /*107, Undefined */ 0, state_undefined },
3101 { /*108, Undefined */ 0, state_undefined },
3102 { /*109, Undefined */ 0, state_undefined },
3103 { /*110, Undefined */ 0, state_undefined },
3104 { /*111, Undefined */ 0, state_undefined },
3105 { /*112, Undefined */ 0, state_undefined },
3106 { /*113, Undefined */ 0, state_undefined },
3107 { /*114, Undefined */ 0, state_undefined },
3108 { /*115, Undefined */ 0, state_undefined },
3109 { /*116, Undefined */ 0, state_undefined },
3110 { /*117, Undefined */ 0, state_undefined },
3111 { /*118, Undefined */ 0, state_undefined },
3112 { /*119, Undefined */ 0, state_undefined },
3113 { /*120, Undefined */ 0, state_undefined },
3114 { /*121, Undefined */ 0, state_undefined },
3115 { /*122, Undefined */ 0, state_undefined },
3116 { /*123, Undefined */ 0, state_undefined },
3117 { /*124, Undefined */ 0, state_undefined },
3118 { /*125, Undefined */ 0, state_undefined },
3119 { /*126, Undefined */ 0, state_undefined },
3120 { /*127, Undefined */ 0, state_undefined },
3121 /* Big hole ends */
3122 { /*128, WINED3DRS_WRAP0 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3123 { /*129, WINED3DRS_WRAP1 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3124 { /*130, WINED3DRS_WRAP2 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3125 { /*131, WINED3DRS_WRAP3 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3126 { /*132, WINED3DRS_WRAP4 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3127 { /*133, WINED3DRS_WRAP5 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3128 { /*134, WINED3DRS_WRAP6 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3129 { /*135, WINED3DRS_WRAP7 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3130 { /*136, WINED3DRS_CLIPPING */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3131 { /*137, WINED3DRS_LIGHTING */ STATE_RENDER(WINED3DRS_LIGHTING), state_lighting },
3132 { /*138, WINED3DRS_EXTENTS */ STATE_RENDER(WINED3DRS_EXTENTS), state_extents },
3133 { /*139, WINED3DRS_AMBIENT */ STATE_RENDER(WINED3DRS_AMBIENT), state_ambient },
3134 { /*140, WINED3DRS_FOGVERTEXMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3135 { /*141, WINED3DRS_COLORVERTEX */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3136 { /*142, WINED3DRS_LOCALVIEWER */ STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer },
3137 { /*143, WINED3DRS_NORMALIZENORMALS */ STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize },
3138 { /*144, WINED3DRS_COLORKEYBLENDENABLE */ STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend },
3139 { /*145, WINED3DRS_DIFFUSEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3140 { /*146, WINED3DRS_SPECULARMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3141 { /*147, WINED3DRS_AMBIENTMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3142 { /*148, WINED3DRS_EMISSIVEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3143 { /*149, Undefined */ 0, state_undefined },
3144 { /*150, Undefined */ 0, state_undefined },
3145 { /*151, WINED3DRS_VERTEXBLEND */ 0, state_nogl },
3146 { /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3147 { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING */ 0, state_nogl },
3148 { /*154, WINED3DRS_POINTSIZE */ STATE_RENDER(WINED3DRS_POINTSIZE), state_psize },
3149 { /*155, WINED3DRS_POINTSIZE_MIN */ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin },
3150 { /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite },
3151 { /*157, WINED3DRS_POINTSCALEENABLE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3152 { /*158, WINED3DRS_POINTSCALE_A */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3153 { /*159, WINED3DRS_POINTSCALE_B */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3154 { /*160, WINED3DRS_POINTSCALE_C */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3155 { /*161, WINED3DRS_MULTISAMPLEANTIALIAS */ STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_multisampleaa },
3156 { /*162, WINED3DRS_MULTISAMPLEMASK */ STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask },
3157 { /*163, WINED3DRS_PATCHEDGESTYLE */ STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle},
3158 { /*164, WINED3DRS_PATCHSEGMENTS */ STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments },
3159 { /*165, WINED3DRS_DEBUGMONITORTOKEN */ STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_nogl },
3160 { /*166, WINED3DRS_POINTSIZE_MAX */ STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax },
3161 { /*167, WINED3DRS_INDEXEDVERTEXBLENDENABLE */ 0, state_nogl },
3162 { /*168, WINED3DRS_COLORWRITEENABLE */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3163 { /*169, Undefined */ 0, state_undefined },
3164 { /*170, WINED3DRS_TWEENFACTOR */ 0, state_nogl },
3165 { /*171, WINED3DRS_BLENDOP */ STATE_RENDER(WINED3DRS_BLENDOP), state_blendop },
3166 { /*172, WINED3DRS_POSITIONDEGREE */ STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree},
3167 { /*173, WINED3DRS_NORMALDEGREE */ STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree },
3168 /*172, WINED3DRS_POSITIONORDER */ /* Value assigned to 2 state names */
3169 /*173, WINED3DRS_NORMALORDER */ /* Value assigned to 2 state names */
3170 { /*174, WINED3DRS_SCISSORTESTENABLE */ STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor },
3171 { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3172 { /*176, WINED3DRS_ANTIALIASEDLINEENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3173 { /*177, undefined */ 0, state_undefined },
3174 { /*178, WINED3DRS_MINTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3175 { /*179, WINED3DRS_MAXTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3176 { /*180, WINED3DRS_ADAPTIVETESS_X */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3177 { /*181, WINED3DRS_ADAPTIVETESS_Y */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3178 { /*182, WINED3DRS_ADAPTIVETESS_Z */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3179 { /*183, WINED3DRS_ADAPTIVETESS_W */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3180 { /*184, WINED3DRS_ENABLEADAPTIVETESSELLATION */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3181 { /*185, WINED3DRS_TWOSIDEDSTENCILMODE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3182 { /*186, WINED3DRS_CCW_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3183 { /*187, WINED3DRS_CCW_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3184 { /*188, WINED3DRS_CCW_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3185 { /*189, WINED3DRS_CCW_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3186 { /*190, WINED3DRS_COLORWRITEENABLE1 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3187 { /*191, WINED3DRS_COLORWRITEENABLE2 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3188 { /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3189 { /*193, WINED3DRS_BLENDFACTOR */ STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor },
3190 { /*194, WINED3DRS_SRGBWRITEENABLE */ STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), state_srgbwrite },
3191 { /*195, WINED3DRS_DEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3192 { /*196, undefined */ 0, state_undefined },
3193 { /*197, undefined */ 0, state_undefined },
3194 { /*198, WINED3DRS_WRAP8 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3195 { /*199, WINED3DRS_WRAP9 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3196 { /*200, WINED3DRS_WRAP10 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3197 { /*201, WINED3DRS_WRAP11 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3198 { /*202, WINED3DRS_WRAP12 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3199 { /*203, WINED3DRS_WRAP13 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3200 { /*204, WINED3DRS_WRAP14 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3201 { /*205, WINED3DRS_WRAP15 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3202 { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3203 { /*207, WINED3DRS_SRCBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3204 { /*208, WINED3DRS_DESTBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3205 { /*209, WINED3DRS_BLENDOPALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3206 /* Texture stage states */
3207 { /*0, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3208 { /*0, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3209 { /*0, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3210 { /*0, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3211 { /*0, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3212 { /*0, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3213 { /*0, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3214 { /*0, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3215 { /*0, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3216 { /*0, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3217 { /*0, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3218 { /*0, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3219 { /*0, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3220 { /*0, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3221 { /*0, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3222 { /*0, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3223 { /*0, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3224 { /*0, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3225 { /*0, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3226 { /*0, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3227 { /*0, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3228 { /*0, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3229 { /*0, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3230 { /*0, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3231 { /*0, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3232 { /*0, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3233 { /*0, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3234 { /*0, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), tex_resultarg },
3235 { /*0, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3236 { /*0, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3237 { /*0, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3238 { /*0, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3240 { /*1, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3241 { /*1, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3242 { /*1, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3243 { /*1, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3244 { /*1, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3245 { /*1, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3246 { /*1, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3247 { /*1, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3248 { /*1, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3249 { /*1, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3250 { /*1, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3251 { /*1, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3252 { /*1, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3253 { /*1, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3254 { /*1, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3255 { /*1, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3256 { /*1, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3257 { /*1, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3258 { /*1, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3259 { /*1, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3260 { /*1, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3261 { /*1, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3262 { /*1, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3263 { /*1, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3264 { /*1, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3265 { /*1, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3266 { /*1, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3267 { /*1, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), tex_resultarg },
3268 { /*1, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3269 { /*1, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3270 { /*1, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3271 { /*1, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3273 { /*2, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3274 { /*2, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3275 { /*2, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3276 { /*2, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3277 { /*2, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3278 { /*2, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3279 { /*2, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3280 { /*2, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3281 { /*2, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3282 { /*2, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3283 { /*2, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3284 { /*2, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3285 { /*2, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3286 { /*2, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3287 { /*2, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3288 { /*2, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3289 { /*2, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3290 { /*2, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3291 { /*2, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3292 { /*2, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3293 { /*2, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3294 { /*2, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3295 { /*2, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3296 { /*2, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3297 { /*2, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3298 { /*2, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3299 { /*2, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3300 { /*2, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), tex_resultarg },
3301 { /*2, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3302 { /*2, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3303 { /*2, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3304 { /*2, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3306 { /*3, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3307 { /*3, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3308 { /*3, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3309 { /*3, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3310 { /*3, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3311 { /*3, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3312 { /*3, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3313 { /*3, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3314 { /*3, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3315 { /*3, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3316 { /*3, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3317 { /*3, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3318 { /*3, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3319 { /*3, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3320 { /*3, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3321 { /*3, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3322 { /*3, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3323 { /*3, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3324 { /*3, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3325 { /*3, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3326 { /*3, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3327 { /*3, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3328 { /*3, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3329 { /*3, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3330 { /*3, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3331 { /*3, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3332 { /*3, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3333 { /*3, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), tex_resultarg },
3334 { /*3, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3335 { /*3, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3336 { /*3, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3337 { /*3, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3339 { /*4, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3340 { /*4, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3341 { /*4, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3342 { /*4, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3343 { /*4, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3344 { /*4, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3345 { /*4, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), state_undefined },
3346 { /*4, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), state_undefined },
3347 { /*4, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), state_undefined },
3348 { /*4, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), state_undefined },
3349 { /*4, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3350 { /*4, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3351 { /*4, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3352 { /*4, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3353 { /*4, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3354 { /*4, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3355 { /*4, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3356 { /*4, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3357 { /*4, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3358 { /*4, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3359 { /*4, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3360 { /*4, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3361 { /*4, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3362 { /*4, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3363 { /*4, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3364 { /*4, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3365 { /*4, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3366 { /*4, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), tex_resultarg },
3367 { /*4, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3368 { /*4, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3369 { /*4, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3370 { /*4, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3372 { /*5, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3373 { /*5, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3374 { /*5, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3375 { /*5, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3376 { /*5, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3377 { /*5, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3378 { /*5, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3379 { /*5, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3380 { /*5, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3381 { /*5, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3382 { /*5, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3383 { /*5, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3384 { /*5, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3385 { /*5, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3386 { /*5, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3387 { /*5, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3388 { /*5, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3389 { /*5, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3390 { /*5, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3391 { /*5, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3392 { /*5, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3393 { /*5, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3394 { /*5, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3395 { /*5, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3396 { /*5, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3397 { /*5, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3398 { /*5, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3399 { /*5, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), tex_resultarg },
3400 { /*5, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3401 { /*5, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3402 { /*5, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3403 { /*5, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3405 { /*6, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3406 { /*6, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3407 { /*6, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3408 { /*6, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3409 { /*6, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3410 { /*6, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3411 { /*6, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3412 { /*6, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3413 { /*6, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3414 { /*6, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3415 { /*6, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3416 { /*6, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3417 { /*6, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3418 { /*6, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3419 { /*6, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3420 { /*6, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3421 { /*6, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3422 { /*6, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3423 { /*6, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3424 { /*6, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3425 { /*6, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3426 { /*6, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3427 { /*6, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3428 { /*6, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3429 { /*6, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3430 { /*6, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3431 { /*6, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3432 { /*6, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), tex_resultarg },
3433 { /*6, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3434 { /*6, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3435 { /*6, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3436 { /*6, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3438 { /*7, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3439 { /*7, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3440 { /*7, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3441 { /*7, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3442 { /*7, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3443 { /*7, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3444 { /*7, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3445 { /*7, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3446 { /*7, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3447 { /*7, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3448 { /*7, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3449 { /*7, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3450 { /*7, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3451 { /*7, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3452 { /*7, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3453 { /*7, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3454 { /*7, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3455 { /*7, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3456 { /*7, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3457 { /*7, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3458 { /*7, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3459 { /*7, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3460 { /*7, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3461 { /*7, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3462 { /*7, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3463 { /*7, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3464 { /*7, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3465 { /*7, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), tex_resultarg },
3466 { /*7, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3467 { /*7, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3468 { /*7, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3469 { /*7, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3470 /* Sampler states */
3471 { /* 0, Sampler 0 */ STATE_SAMPLER(0), sampler },
3472 { /* 1, Sampler 1 */ STATE_SAMPLER(1), sampler },
3473 { /* 2, Sampler 2 */ STATE_SAMPLER(2), sampler },
3474 { /* 3, Sampler 3 */ STATE_SAMPLER(3), sampler },
3475 { /* 4, Sampler 3 */ STATE_SAMPLER(4), sampler },
3476 { /* 5, Sampler 5 */ STATE_SAMPLER(5), sampler },
3477 { /* 6, Sampler 6 */ STATE_SAMPLER(6), sampler },
3478 { /* 7, Sampler 7 */ STATE_SAMPLER(7), sampler },
3479 { /* 8, Sampler 8 */ STATE_SAMPLER(8), sampler },
3480 { /* 9, Sampler 9 */ STATE_SAMPLER(9), sampler },
3481 { /*10, Sampler 10 */ STATE_SAMPLER(10), sampler },
3482 { /*11, Sampler 11 */ STATE_SAMPLER(11), sampler },
3483 { /*12, Sampler 12 */ STATE_SAMPLER(12), sampler },
3484 { /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
3485 { /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
3486 { /*15, Sampler 15 */ STATE_SAMPLER(15), sampler },
3487 /* Pixel shader */
3488 { /* , Pixel Shader */ STATE_PIXELSHADER, pixelshader },
3489 /* Transform states follow */
3490 { /* 1, undefined */ 0, state_undefined },
3491 { /* 2, WINED3DTS_VIEW */ STATE_TRANSFORM(WINED3DTS_VIEW), transform_view },
3492 { /* 3, WINED3DTS_PROJECTION */ STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection},
3493 { /* 4, undefined */ 0, state_undefined },
3494 { /* 5, undefined */ 0, state_undefined },
3495 { /* 6, undefined */ 0, state_undefined },
3496 { /* 7, undefined */ 0, state_undefined },
3497 { /* 8, undefined */ 0, state_undefined },
3498 { /* 9, undefined */ 0, state_undefined },
3499 { /* 10, undefined */ 0, state_undefined },
3500 { /* 11, undefined */ 0, state_undefined },
3501 { /* 12, undefined */ 0, state_undefined },
3502 { /* 13, undefined */ 0, state_undefined },
3503 { /* 14, undefined */ 0, state_undefined },
3504 { /* 15, undefined */ 0, state_undefined },
3505 { /* 16, WINED3DTS_TEXTURE0 */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3506 { /* 17, WINED3DTS_TEXTURE1 */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3507 { /* 18, WINED3DTS_TEXTURE2 */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3508 { /* 19, WINED3DTS_TEXTURE3 */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3509 { /* 20, WINED3DTS_TEXTURE4 */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3510 { /* 21, WINED3DTS_TEXTURE5 */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3511 { /* 22, WINED3DTS_TEXTURE6 */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3512 { /* 23, WINED3DTS_TEXTURE7 */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3513 /* A huge gap between TEXTURE7 and WORLDMATRIX(0) :-( But entries are needed to catch then if a broken app sets them */
3514 { /* 24, undefined */ 0, state_undefined },
3515 { /* 25, undefined */ 0, state_undefined },
3516 { /* 26, undefined */ 0, state_undefined },
3517 { /* 27, undefined */ 0, state_undefined },
3518 { /* 28, undefined */ 0, state_undefined },
3519 { /* 29, undefined */ 0, state_undefined },
3520 { /* 30, undefined */ 0, state_undefined },
3521 { /* 31, undefined */ 0, state_undefined },
3522 { /* 32, undefined */ 0, state_undefined },
3523 { /* 33, undefined */ 0, state_undefined },
3524 { /* 34, undefined */ 0, state_undefined },
3525 { /* 35, undefined */ 0, state_undefined },
3526 { /* 36, undefined */ 0, state_undefined },
3527 { /* 37, undefined */ 0, state_undefined },
3528 { /* 38, undefined */ 0, state_undefined },
3529 { /* 39, undefined */ 0, state_undefined },
3530 { /* 40, undefined */ 0, state_undefined },
3531 { /* 41, undefined */ 0, state_undefined },
3532 { /* 42, undefined */ 0, state_undefined },
3533 { /* 43, undefined */ 0, state_undefined },
3534 { /* 44, undefined */ 0, state_undefined },
3535 { /* 45, undefined */ 0, state_undefined },
3536 { /* 46, undefined */ 0, state_undefined },
3537 { /* 47, undefined */ 0, state_undefined },
3538 { /* 48, undefined */ 0, state_undefined },
3539 { /* 49, undefined */ 0, state_undefined },
3540 { /* 50, undefined */ 0, state_undefined },
3541 { /* 51, undefined */ 0, state_undefined },
3542 { /* 52, undefined */ 0, state_undefined },
3543 { /* 53, undefined */ 0, state_undefined },
3544 { /* 54, undefined */ 0, state_undefined },
3545 { /* 55, undefined */ 0, state_undefined },
3546 { /* 56, undefined */ 0, state_undefined },
3547 { /* 57, undefined */ 0, state_undefined },
3548 { /* 58, undefined */ 0, state_undefined },
3549 { /* 59, undefined */ 0, state_undefined },
3550 { /* 60, undefined */ 0, state_undefined },
3551 { /* 61, undefined */ 0, state_undefined },
3552 { /* 62, undefined */ 0, state_undefined },
3553 { /* 63, undefined */ 0, state_undefined },
3554 { /* 64, undefined */ 0, state_undefined },
3555 { /* 65, undefined */ 0, state_undefined },
3556 { /* 66, undefined */ 0, state_undefined },
3557 { /* 67, undefined */ 0, state_undefined },
3558 { /* 68, undefined */ 0, state_undefined },
3559 { /* 69, undefined */ 0, state_undefined },
3560 { /* 70, undefined */ 0, state_undefined },
3561 { /* 71, undefined */ 0, state_undefined },
3562 { /* 72, undefined */ 0, state_undefined },
3563 { /* 73, undefined */ 0, state_undefined },
3564 { /* 74, undefined */ 0, state_undefined },
3565 { /* 75, undefined */ 0, state_undefined },
3566 { /* 76, undefined */ 0, state_undefined },
3567 { /* 77, undefined */ 0, state_undefined },
3568 { /* 78, undefined */ 0, state_undefined },
3569 { /* 79, undefined */ 0, state_undefined },
3570 { /* 80, undefined */ 0, state_undefined },
3571 { /* 81, undefined */ 0, state_undefined },
3572 { /* 82, undefined */ 0, state_undefined },
3573 { /* 83, undefined */ 0, state_undefined },
3574 { /* 84, undefined */ 0, state_undefined },
3575 { /* 85, undefined */ 0, state_undefined },
3576 { /* 86, undefined */ 0, state_undefined },
3577 { /* 87, undefined */ 0, state_undefined },
3578 { /* 88, undefined */ 0, state_undefined },
3579 { /* 89, undefined */ 0, state_undefined },
3580 { /* 90, undefined */ 0, state_undefined },
3581 { /* 91, undefined */ 0, state_undefined },
3582 { /* 92, undefined */ 0, state_undefined },
3583 { /* 93, undefined */ 0, state_undefined },
3584 { /* 94, undefined */ 0, state_undefined },
3585 { /* 95, undefined */ 0, state_undefined },
3586 { /* 96, undefined */ 0, state_undefined },
3587 { /* 97, undefined */ 0, state_undefined },
3588 { /* 98, undefined */ 0, state_undefined },
3589 { /* 99, undefined */ 0, state_undefined },
3590 { /*100, undefined */ 0, state_undefined },
3591 { /*101, undefined */ 0, state_undefined },
3592 { /*102, undefined */ 0, state_undefined },
3593 { /*103, undefined */ 0, state_undefined },
3594 { /*104, undefined */ 0, state_undefined },
3595 { /*105, undefined */ 0, state_undefined },
3596 { /*106, undefined */ 0, state_undefined },
3597 { /*107, undefined */ 0, state_undefined },
3598 { /*108, undefined */ 0, state_undefined },
3599 { /*109, undefined */ 0, state_undefined },
3600 { /*110, undefined */ 0, state_undefined },
3601 { /*111, undefined */ 0, state_undefined },
3602 { /*112, undefined */ 0, state_undefined },
3603 { /*113, undefined */ 0, state_undefined },
3604 { /*114, undefined */ 0, state_undefined },
3605 { /*115, undefined */ 0, state_undefined },
3606 { /*116, undefined */ 0, state_undefined },
3607 { /*117, undefined */ 0, state_undefined },
3608 { /*118, undefined */ 0, state_undefined },
3609 { /*119, undefined */ 0, state_undefined },
3610 { /*120, undefined */ 0, state_undefined },
3611 { /*121, undefined */ 0, state_undefined },
3612 { /*122, undefined */ 0, state_undefined },
3613 { /*123, undefined */ 0, state_undefined },
3614 { /*124, undefined */ 0, state_undefined },
3615 { /*125, undefined */ 0, state_undefined },
3616 { /*126, undefined */ 0, state_undefined },
3617 { /*127, undefined */ 0, state_undefined },
3618 { /*128, undefined */ 0, state_undefined },
3619 { /*129, undefined */ 0, state_undefined },
3620 { /*130, undefined */ 0, state_undefined },
3621 { /*131, undefined */ 0, state_undefined },
3622 { /*132, undefined */ 0, state_undefined },
3623 { /*133, undefined */ 0, state_undefined },
3624 { /*134, undefined */ 0, state_undefined },
3625 { /*135, undefined */ 0, state_undefined },
3626 { /*136, undefined */ 0, state_undefined },
3627 { /*137, undefined */ 0, state_undefined },
3628 { /*138, undefined */ 0, state_undefined },
3629 { /*139, undefined */ 0, state_undefined },
3630 { /*140, undefined */ 0, state_undefined },
3631 { /*141, undefined */ 0, state_undefined },
3632 { /*142, undefined */ 0, state_undefined },
3633 { /*143, undefined */ 0, state_undefined },
3634 { /*144, undefined */ 0, state_undefined },
3635 { /*145, undefined */ 0, state_undefined },
3636 { /*146, undefined */ 0, state_undefined },
3637 { /*147, undefined */ 0, state_undefined },
3638 { /*148, undefined */ 0, state_undefined },
3639 { /*149, undefined */ 0, state_undefined },
3640 { /*150, undefined */ 0, state_undefined },
3641 { /*151, undefined */ 0, state_undefined },
3642 { /*152, undefined */ 0, state_undefined },
3643 { /*153, undefined */ 0, state_undefined },
3644 { /*154, undefined */ 0, state_undefined },
3645 { /*155, undefined */ 0, state_undefined },
3646 { /*156, undefined */ 0, state_undefined },
3647 { /*157, undefined */ 0, state_undefined },
3648 { /*158, undefined */ 0, state_undefined },
3649 { /*159, undefined */ 0, state_undefined },
3650 { /*160, undefined */ 0, state_undefined },
3651 { /*161, undefined */ 0, state_undefined },
3652 { /*162, undefined */ 0, state_undefined },
3653 { /*163, undefined */ 0, state_undefined },
3654 { /*164, undefined */ 0, state_undefined },
3655 { /*165, undefined */ 0, state_undefined },
3656 { /*166, undefined */ 0, state_undefined },
3657 { /*167, undefined */ 0, state_undefined },
3658 { /*168, undefined */ 0, state_undefined },
3659 { /*169, undefined */ 0, state_undefined },
3660 { /*170, undefined */ 0, state_undefined },
3661 { /*171, undefined */ 0, state_undefined },
3662 { /*172, undefined */ 0, state_undefined },
3663 { /*173, undefined */ 0, state_undefined },
3664 { /*174, undefined */ 0, state_undefined },
3665 { /*175, undefined */ 0, state_undefined },
3666 { /*176, undefined */ 0, state_undefined },
3667 { /*177, undefined */ 0, state_undefined },
3668 { /*178, undefined */ 0, state_undefined },
3669 { /*179, undefined */ 0, state_undefined },
3670 { /*180, undefined */ 0, state_undefined },
3671 { /*181, undefined */ 0, state_undefined },
3672 { /*182, undefined */ 0, state_undefined },
3673 { /*183, undefined */ 0, state_undefined },
3674 { /*184, undefined */ 0, state_undefined },
3675 { /*185, undefined */ 0, state_undefined },
3676 { /*186, undefined */ 0, state_undefined },
3677 { /*187, undefined */ 0, state_undefined },
3678 { /*188, undefined */ 0, state_undefined },
3679 { /*189, undefined */ 0, state_undefined },
3680 { /*190, undefined */ 0, state_undefined },
3681 { /*191, undefined */ 0, state_undefined },
3682 { /*192, undefined */ 0, state_undefined },
3683 { /*193, undefined */ 0, state_undefined },
3684 { /*194, undefined */ 0, state_undefined },
3685 { /*195, undefined */ 0, state_undefined },
3686 { /*196, undefined */ 0, state_undefined },
3687 { /*197, undefined */ 0, state_undefined },
3688 { /*198, undefined */ 0, state_undefined },
3689 { /*199, undefined */ 0, state_undefined },
3690 { /*200, undefined */ 0, state_undefined },
3691 { /*201, undefined */ 0, state_undefined },
3692 { /*202, undefined */ 0, state_undefined },
3693 { /*203, undefined */ 0, state_undefined },
3694 { /*204, undefined */ 0, state_undefined },
3695 { /*205, undefined */ 0, state_undefined },
3696 { /*206, undefined */ 0, state_undefined },
3697 { /*207, undefined */ 0, state_undefined },
3698 { /*208, undefined */ 0, state_undefined },
3699 { /*209, undefined */ 0, state_undefined },
3700 { /*210, undefined */ 0, state_undefined },
3701 { /*211, undefined */ 0, state_undefined },
3702 { /*212, undefined */ 0, state_undefined },
3703 { /*213, undefined */ 0, state_undefined },
3704 { /*214, undefined */ 0, state_undefined },
3705 { /*215, undefined */ 0, state_undefined },
3706 { /*216, undefined */ 0, state_undefined },
3707 { /*217, undefined */ 0, state_undefined },
3708 { /*218, undefined */ 0, state_undefined },
3709 { /*219, undefined */ 0, state_undefined },
3710 { /*220, undefined */ 0, state_undefined },
3711 { /*221, undefined */ 0, state_undefined },
3712 { /*222, undefined */ 0, state_undefined },
3713 { /*223, undefined */ 0, state_undefined },
3714 { /*224, undefined */ 0, state_undefined },
3715 { /*225, undefined */ 0, state_undefined },
3716 { /*226, undefined */ 0, state_undefined },
3717 { /*227, undefined */ 0, state_undefined },
3718 { /*228, undefined */ 0, state_undefined },
3719 { /*229, undefined */ 0, state_undefined },
3720 { /*230, undefined */ 0, state_undefined },
3721 { /*231, undefined */ 0, state_undefined },
3722 { /*232, undefined */ 0, state_undefined },
3723 { /*233, undefined */ 0, state_undefined },
3724 { /*234, undefined */ 0, state_undefined },
3725 { /*235, undefined */ 0, state_undefined },
3726 { /*236, undefined */ 0, state_undefined },
3727 { /*237, undefined */ 0, state_undefined },
3728 { /*238, undefined */ 0, state_undefined },
3729 { /*239, undefined */ 0, state_undefined },
3730 { /*240, undefined */ 0, state_undefined },
3731 { /*241, undefined */ 0, state_undefined },
3732 { /*242, undefined */ 0, state_undefined },
3733 { /*243, undefined */ 0, state_undefined },
3734 { /*244, undefined */ 0, state_undefined },
3735 { /*245, undefined */ 0, state_undefined },
3736 { /*246, undefined */ 0, state_undefined },
3737 { /*247, undefined */ 0, state_undefined },
3738 { /*248, undefined */ 0, state_undefined },
3739 { /*249, undefined */ 0, state_undefined },
3740 { /*250, undefined */ 0, state_undefined },
3741 { /*251, undefined */ 0, state_undefined },
3742 { /*252, undefined */ 0, state_undefined },
3743 { /*253, undefined */ 0, state_undefined },
3744 { /*254, undefined */ 0, state_undefined },
3745 { /*255, undefined */ 0, state_undefined },
3746 /* End huge gap */
3747 { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), transform_world },
3748 { /*257, WINED3DTS_WORLDMATRIX(1) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)), transform_worldex },
3749 { /*258, WINED3DTS_WORLDMATRIX(2) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)), transform_worldex },
3750 { /*259, WINED3DTS_WORLDMATRIX(3) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)), transform_worldex },
3751 { /*260, WINED3DTS_WORLDMATRIX(4) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(4)), transform_worldex },
3752 { /*261, WINED3DTS_WORLDMATRIX(5) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(5)), transform_worldex },
3753 { /*262, WINED3DTS_WORLDMATRIX(6) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(6)), transform_worldex },
3754 { /*263, WINED3DTS_WORLDMATRIX(7) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(7)), transform_worldex },
3755 { /*264, WINED3DTS_WORLDMATRIX(8) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(8)), transform_worldex },
3756 { /*265, WINED3DTS_WORLDMATRIX(9) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(9)), transform_worldex },
3757 { /*266, WINED3DTS_WORLDMATRIX(10) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(10)), transform_worldex },
3758 { /*267, WINED3DTS_WORLDMATRIX(11) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(11)), transform_worldex },
3759 { /*268, WINED3DTS_WORLDMATRIX(12) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(12)), transform_worldex },
3760 { /*269, WINED3DTS_WORLDMATRIX(13) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(13)), transform_worldex },
3761 { /*270, WINED3DTS_WORLDMATRIX(14) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(14)), transform_worldex },
3762 { /*271, WINED3DTS_WORLDMATRIX(15) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(15)), transform_worldex },
3763 { /*272, WINED3DTS_WORLDMATRIX(16) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(16)), transform_worldex },
3764 { /*273, WINED3DTS_WORLDMATRIX(17) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(17)), transform_worldex },
3765 { /*274, WINED3DTS_WORLDMATRIX(18) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(18)), transform_worldex },
3766 { /*275, WINED3DTS_WORLDMATRIX(19) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(19)), transform_worldex },
3767 { /*276, WINED3DTS_WORLDMATRIX(20) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(20)), transform_worldex },
3768 { /*277, WINED3DTS_WORLDMATRIX(21) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(21)), transform_worldex },
3769 { /*278, WINED3DTS_WORLDMATRIX(22) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(22)), transform_worldex },
3770 { /*279, WINED3DTS_WORLDMATRIX(23) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(23)), transform_worldex },
3771 { /*280, WINED3DTS_WORLDMATRIX(24) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(24)), transform_worldex },
3772 { /*281, WINED3DTS_WORLDMATRIX(25) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(25)), transform_worldex },
3773 { /*282, WINED3DTS_WORLDMATRIX(26) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(26)), transform_worldex },
3774 { /*283, WINED3DTS_WORLDMATRIX(27) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(27)), transform_worldex },
3775 { /*284, WINED3DTS_WORLDMATRIX(28) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(28)), transform_worldex },
3776 { /*285, WINED3DTS_WORLDMATRIX(29) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(29)), transform_worldex },
3777 { /*286, WINED3DTS_WORLDMATRIX(30) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(30)), transform_worldex },
3778 { /*287, WINED3DTS_WORLDMATRIX(31) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(31)), transform_worldex },
3779 { /*288, WINED3DTS_WORLDMATRIX(32) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(32)), transform_worldex },
3780 { /*289, WINED3DTS_WORLDMATRIX(33) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(33)), transform_worldex },
3781 { /*290, WINED3DTS_WORLDMATRIX(34) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(34)), transform_worldex },
3782 { /*291, WINED3DTS_WORLDMATRIX(35) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(35)), transform_worldex },
3783 { /*292, WINED3DTS_WORLDMATRIX(36) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(36)), transform_worldex },
3784 { /*293, WINED3DTS_WORLDMATRIX(37) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(37)), transform_worldex },
3785 { /*294, WINED3DTS_WORLDMATRIX(38) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(38)), transform_worldex },
3786 { /*295, WINED3DTS_WORLDMATRIX(39) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(39)), transform_worldex },
3787 { /*296, WINED3DTS_WORLDMATRIX(40) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(40)), transform_worldex },
3788 { /*297, WINED3DTS_WORLDMATRIX(41) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(41)), transform_worldex },
3789 { /*298, WINED3DTS_WORLDMATRIX(42) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(42)), transform_worldex },
3790 { /*299, WINED3DTS_WORLDMATRIX(43) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(43)), transform_worldex },
3791 { /*300, WINED3DTS_WORLDMATRIX(44) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(44)), transform_worldex },
3792 { /*301, WINED3DTS_WORLDMATRIX(45) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(45)), transform_worldex },
3793 { /*302, WINED3DTS_WORLDMATRIX(46) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(46)), transform_worldex },
3794 { /*303, WINED3DTS_WORLDMATRIX(47) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(47)), transform_worldex },
3795 { /*304, WINED3DTS_WORLDMATRIX(48) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(48)), transform_worldex },
3796 { /*305, WINED3DTS_WORLDMATRIX(49) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(49)), transform_worldex },
3797 { /*306, WINED3DTS_WORLDMATRIX(50) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(50)), transform_worldex },
3798 { /*307, WINED3DTS_WORLDMATRIX(51) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(51)), transform_worldex },
3799 { /*308, WINED3DTS_WORLDMATRIX(52) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(52)), transform_worldex },
3800 { /*309, WINED3DTS_WORLDMATRIX(53) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(53)), transform_worldex },
3801 { /*310, WINED3DTS_WORLDMATRIX(54) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(54)), transform_worldex },
3802 { /*311, WINED3DTS_WORLDMATRIX(55) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(55)), transform_worldex },
3803 { /*312, WINED3DTS_WORLDMATRIX(56) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(56)), transform_worldex },
3804 { /*313, WINED3DTS_WORLDMATRIX(57) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(57)), transform_worldex },
3805 { /*314, WINED3DTS_WORLDMATRIX(58) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(58)), transform_worldex },
3806 { /*315, WINED3DTS_WORLDMATRIX(59) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(59)), transform_worldex },
3807 { /*316, WINED3DTS_WORLDMATRIX(60) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(60)), transform_worldex },
3808 { /*317, WINED3DTS_WORLDMATRIX(61) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(61)), transform_worldex },
3809 { /*318, WINED3DTS_WORLDMATRIX(62) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(62)), transform_worldex },
3810 { /*319, WINED3DTS_WORLDMATRIX(63) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(63)), transform_worldex },
3811 { /*320, WINED3DTS_WORLDMATRIX(64) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(64)), transform_worldex },
3812 { /*321, WINED3DTS_WORLDMATRIX(65) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(65)), transform_worldex },
3813 { /*322, WINED3DTS_WORLDMATRIX(66) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(66)), transform_worldex },
3814 { /*323, WINED3DTS_WORLDMATRIX(67) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(67)), transform_worldex },
3815 { /*324, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(68)), transform_worldex },
3816 { /*325, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(69)), transform_worldex },
3817 { /*326, WINED3DTS_WORLDMATRIX(70) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(70)), transform_worldex },
3818 { /*327, WINED3DTS_WORLDMATRIX(71) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(71)), transform_worldex },
3819 { /*328, WINED3DTS_WORLDMATRIX(72) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(72)), transform_worldex },
3820 { /*329, WINED3DTS_WORLDMATRIX(73) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(73)), transform_worldex },
3821 { /*330, WINED3DTS_WORLDMATRIX(74) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(74)), transform_worldex },
3822 { /*331, WINED3DTS_WORLDMATRIX(75) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(75)), transform_worldex },
3823 { /*332, WINED3DTS_WORLDMATRIX(76) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(76)), transform_worldex },
3824 { /*333, WINED3DTS_WORLDMATRIX(77) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(77)), transform_worldex },
3825 { /*334, WINED3DTS_WORLDMATRIX(78) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(78)), transform_worldex },
3826 { /*335, WINED3DTS_WORLDMATRIX(79) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(79)), transform_worldex },
3827 { /*336, WINED3DTS_WORLDMATRIX(80) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(80)), transform_worldex },
3828 { /*337, WINED3DTS_WORLDMATRIX(81) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(81)), transform_worldex },
3829 { /*338, WINED3DTS_WORLDMATRIX(82) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(82)), transform_worldex },
3830 { /*339, WINED3DTS_WORLDMATRIX(83) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(83)), transform_worldex },
3831 { /*340, WINED3DTS_WORLDMATRIX(84) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(84)), transform_worldex },
3832 { /*341, WINED3DTS_WORLDMATRIX(85) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(85)), transform_worldex },
3833 { /*341, WINED3DTS_WORLDMATRIX(86) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(86)), transform_worldex },
3834 { /*343, WINED3DTS_WORLDMATRIX(87) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(87)), transform_worldex },
3835 { /*344, WINED3DTS_WORLDMATRIX(88) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(88)), transform_worldex },
3836 { /*345, WINED3DTS_WORLDMATRIX(89) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(89)), transform_worldex },
3837 { /*346, WINED3DTS_WORLDMATRIX(90) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(90)), transform_worldex },
3838 { /*347, WINED3DTS_WORLDMATRIX(91) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(91)), transform_worldex },
3839 { /*348, WINED3DTS_WORLDMATRIX(92) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(92)), transform_worldex },
3840 { /*349, WINED3DTS_WORLDMATRIX(93) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(93)), transform_worldex },
3841 { /*350, WINED3DTS_WORLDMATRIX(94) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(94)), transform_worldex },
3842 { /*351, WINED3DTS_WORLDMATRIX(95) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(95)), transform_worldex },
3843 { /*352, WINED3DTS_WORLDMATRIX(96) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(96)), transform_worldex },
3844 { /*353, WINED3DTS_WORLDMATRIX(97) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(97)), transform_worldex },
3845 { /*354, WINED3DTS_WORLDMATRIX(98) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(98)), transform_worldex },
3846 { /*355, WINED3DTS_WORLDMATRIX(99) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(99)), transform_worldex },
3847 { /*356, WINED3DTS_WORLDMATRIX(100) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex },
3848 { /*357, WINED3DTS_WORLDMATRIX(101) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex },
3849 { /*358, WINED3DTS_WORLDMATRIX(102) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex },
3850 { /*359, WINED3DTS_WORLDMATRIX(103) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex },
3851 { /*360, WINED3DTS_WORLDMATRIX(104) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex },
3852 { /*361, WINED3DTS_WORLDMATRIX(105) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex },
3853 { /*362, WINED3DTS_WORLDMATRIX(106) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex },
3854 { /*363, WINED3DTS_WORLDMATRIX(107) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex },
3855 { /*364, WINED3DTS_WORLDMATRIX(108) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex },
3856 { /*365, WINED3DTS_WORLDMATRIX(109) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex },
3857 { /*366, WINED3DTS_WORLDMATRIX(110) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex },
3858 { /*367, WINED3DTS_WORLDMATRIX(111) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex },
3859 { /*368, WINED3DTS_WORLDMATRIX(112) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex },
3860 { /*369, WINED3DTS_WORLDMATRIX(113) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex },
3861 { /*370, WINED3DTS_WORLDMATRIX(114) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex },
3862 { /*371, WINED3DTS_WORLDMATRIX(115) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex },
3863 { /*372, WINED3DTS_WORLDMATRIX(116) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex },
3864 { /*373, WINED3DTS_WORLDMATRIX(117) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex },
3865 { /*374, WINED3DTS_WORLDMATRIX(118) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex },
3866 { /*375, WINED3DTS_WORLDMATRIX(119) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex },
3867 { /*376, WINED3DTS_WORLDMATRIX(120) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex },
3868 { /*377, WINED3DTS_WORLDMATRIX(121) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex },
3869 { /*378, WINED3DTS_WORLDMATRIX(122) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex },
3870 { /*379, WINED3DTS_WORLDMATRIX(123) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex },
3871 { /*380, WINED3DTS_WORLDMATRIX(124) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex },
3872 { /*381, WINED3DTS_WORLDMATRIX(125) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex },
3873 { /*382, WINED3DTS_WORLDMATRIX(126) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex },
3874 { /*383, WINED3DTS_WORLDMATRIX(127) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex },
3875 { /*384, WINED3DTS_WORLDMATRIX(128) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex },
3876 { /*385, WINED3DTS_WORLDMATRIX(129) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex },
3877 { /*386, WINED3DTS_WORLDMATRIX(130) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex },
3878 { /*387, WINED3DTS_WORLDMATRIX(131) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex },
3879 { /*388, WINED3DTS_WORLDMATRIX(132) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex },
3880 { /*389, WINED3DTS_WORLDMATRIX(133) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex },
3881 { /*390, WINED3DTS_WORLDMATRIX(134) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex },
3882 { /*391, WINED3DTS_WORLDMATRIX(135) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex },
3883 { /*392, WINED3DTS_WORLDMATRIX(136) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex },
3884 { /*393, WINED3DTS_WORLDMATRIX(137) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex },
3885 { /*394, WINED3DTS_WORLDMATRIX(138) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex },
3886 { /*395, WINED3DTS_WORLDMATRIX(139) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex },
3887 { /*396, WINED3DTS_WORLDMATRIX(140) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex },
3888 { /*397, WINED3DTS_WORLDMATRIX(141) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex },
3889 { /*398, WINED3DTS_WORLDMATRIX(142) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex },
3890 { /*399, WINED3DTS_WORLDMATRIX(143) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex },
3891 { /*400, WINED3DTS_WORLDMATRIX(144) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex },
3892 { /*401, WINED3DTS_WORLDMATRIX(145) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex },
3893 { /*402, WINED3DTS_WORLDMATRIX(146) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex },
3894 { /*403, WINED3DTS_WORLDMATRIX(147) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex },
3895 { /*404, WINED3DTS_WORLDMATRIX(148) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex },
3896 { /*405, WINED3DTS_WORLDMATRIX(149) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex },
3897 { /*406, WINED3DTS_WORLDMATRIX(150) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex },
3898 { /*407, WINED3DTS_WORLDMATRIX(151) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex },
3899 { /*408, WINED3DTS_WORLDMATRIX(152) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex },
3900 { /*409, WINED3DTS_WORLDMATRIX(153) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex },
3901 { /*410, WINED3DTS_WORLDMATRIX(154) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex },
3902 { /*411, WINED3DTS_WORLDMATRIX(155) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex },
3903 { /*412, WINED3DTS_WORLDMATRIX(156) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex },
3904 { /*413, WINED3DTS_WORLDMATRIX(157) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex },
3905 { /*414, WINED3DTS_WORLDMATRIX(158) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex },
3906 { /*415, WINED3DTS_WORLDMATRIX(159) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex },
3907 { /*416, WINED3DTS_WORLDMATRIX(160) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex },
3908 { /*417, WINED3DTS_WORLDMATRIX(161) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex },
3909 { /*418, WINED3DTS_WORLDMATRIX(162) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex },
3910 { /*419, WINED3DTS_WORLDMATRIX(163) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex },
3911 { /*420, WINED3DTS_WORLDMATRIX(164) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex },
3912 { /*421, WINED3DTS_WORLDMATRIX(165) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex },
3913 { /*422, WINED3DTS_WORLDMATRIX(166) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex },
3914 { /*423, WINED3DTS_WORLDMATRIX(167) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex },
3915 { /*424, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex },
3916 { /*425, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex },
3917 { /*426, WINED3DTS_WORLDMATRIX(170) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex },
3918 { /*427, WINED3DTS_WORLDMATRIX(171) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex },
3919 { /*428, WINED3DTS_WORLDMATRIX(172) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex },
3920 { /*429, WINED3DTS_WORLDMATRIX(173) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex },
3921 { /*430, WINED3DTS_WORLDMATRIX(174) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex },
3922 { /*431, WINED3DTS_WORLDMATRIX(175) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex },
3923 { /*432, WINED3DTS_WORLDMATRIX(176) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex },
3924 { /*433, WINED3DTS_WORLDMATRIX(177) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex },
3925 { /*434, WINED3DTS_WORLDMATRIX(178) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex },
3926 { /*435, WINED3DTS_WORLDMATRIX(179) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex },
3927 { /*436, WINED3DTS_WORLDMATRIX(180) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex },
3928 { /*437, WINED3DTS_WORLDMATRIX(181) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex },
3929 { /*438, WINED3DTS_WORLDMATRIX(182) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex },
3930 { /*439, WINED3DTS_WORLDMATRIX(183) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex },
3931 { /*440, WINED3DTS_WORLDMATRIX(184) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex },
3932 { /*441, WINED3DTS_WORLDMATRIX(185) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex },
3933 { /*441, WINED3DTS_WORLDMATRIX(186) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex },
3934 { /*443, WINED3DTS_WORLDMATRIX(187) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex },
3935 { /*444, WINED3DTS_WORLDMATRIX(188) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex },
3936 { /*445, WINED3DTS_WORLDMATRIX(189) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex },
3937 { /*446, WINED3DTS_WORLDMATRIX(190) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex },
3938 { /*447, WINED3DTS_WORLDMATRIX(191) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex },
3939 { /*448, WINED3DTS_WORLDMATRIX(192) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex },
3940 { /*449, WINED3DTS_WORLDMATRIX(193) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex },
3941 { /*450, WINED3DTS_WORLDMATRIX(194) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex },
3942 { /*451, WINED3DTS_WORLDMATRIX(195) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex },
3943 { /*452, WINED3DTS_WORLDMATRIX(196) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex },
3944 { /*453, WINED3DTS_WORLDMATRIX(197) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex },
3945 { /*454, WINED3DTS_WORLDMATRIX(198) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex },
3946 { /*455, WINED3DTS_WORLDMATRIX(199) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex },
3947 { /*356, WINED3DTS_WORLDMATRIX(200) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex },
3948 { /*457, WINED3DTS_WORLDMATRIX(201) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex },
3949 { /*458, WINED3DTS_WORLDMATRIX(202) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex },
3950 { /*459, WINED3DTS_WORLDMATRIX(203) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex },
3951 { /*460, WINED3DTS_WORLDMATRIX(204) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex },
3952 { /*461, WINED3DTS_WORLDMATRIX(205) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex },
3953 { /*462, WINED3DTS_WORLDMATRIX(206) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex },
3954 { /*463, WINED3DTS_WORLDMATRIX(207) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex },
3955 { /*464, WINED3DTS_WORLDMATRIX(208) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex },
3956 { /*465, WINED3DTS_WORLDMATRIX(209) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex },
3957 { /*466, WINED3DTS_WORLDMATRIX(210) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex },
3958 { /*467, WINED3DTS_WORLDMATRIX(211) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex },
3959 { /*468, WINED3DTS_WORLDMATRIX(212) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex },
3960 { /*469, WINED3DTS_WORLDMATRIX(213) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex },
3961 { /*470, WINED3DTS_WORLDMATRIX(214) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex },
3962 { /*471, WINED3DTS_WORLDMATRIX(215) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex },
3963 { /*472, WINED3DTS_WORLDMATRIX(216) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex },
3964 { /*473, WINED3DTS_WORLDMATRIX(217) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex },
3965 { /*474, WINED3DTS_WORLDMATRIX(218) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex },
3966 { /*475, WINED3DTS_WORLDMATRIX(219) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex },
3967 { /*476, WINED3DTS_WORLDMATRIX(220) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex },
3968 { /*477, WINED3DTS_WORLDMATRIX(221) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex },
3969 { /*478, WINED3DTS_WORLDMATRIX(222) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex },
3970 { /*479, WINED3DTS_WORLDMATRIX(223) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex },
3971 { /*480, WINED3DTS_WORLDMATRIX(224) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex },
3972 { /*481, WINED3DTS_WORLDMATRIX(225) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex },
3973 { /*482, WINED3DTS_WORLDMATRIX(226) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex },
3974 { /*483, WINED3DTS_WORLDMATRIX(227) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex },
3975 { /*484, WINED3DTS_WORLDMATRIX(228) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex },
3976 { /*485, WINED3DTS_WORLDMATRIX(229) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex },
3977 { /*486, WINED3DTS_WORLDMATRIX(230) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex },
3978 { /*487, WINED3DTS_WORLDMATRIX(231) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex },
3979 { /*488, WINED3DTS_WORLDMATRIX(232) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex },
3980 { /*489, WINED3DTS_WORLDMATRIX(233) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex },
3981 { /*490, WINED3DTS_WORLDMATRIX(234) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex },
3982 { /*491, WINED3DTS_WORLDMATRIX(235) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex },
3983 { /*492, WINED3DTS_WORLDMATRIX(236) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex },
3984 { /*493, WINED3DTS_WORLDMATRIX(237) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex },
3985 { /*494, WINED3DTS_WORLDMATRIX(238) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex },
3986 { /*495, WINED3DTS_WORLDMATRIX(239) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex },
3987 { /*496, WINED3DTS_WORLDMATRIX(240) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex },
3988 { /*497, WINED3DTS_WORLDMATRIX(241) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex },
3989 { /*498, WINED3DTS_WORLDMATRIX(242) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex },
3990 { /*499, WINED3DTS_WORLDMATRIX(243) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex },
3991 { /*500, WINED3DTS_WORLDMATRIX(244) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex },
3992 { /*501, WINED3DTS_WORLDMATRIX(245) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex },
3993 { /*502, WINED3DTS_WORLDMATRIX(246) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex },
3994 { /*503, WINED3DTS_WORLDMATRIX(247) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex },
3995 { /*504, WINED3DTS_WORLDMATRIX(248) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex },
3996 { /*505, WINED3DTS_WORLDMATRIX(249) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex },
3997 { /*506, WINED3DTS_WORLDMATRIX(250) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex },
3998 { /*507, WINED3DTS_WORLDMATRIX(251) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex },
3999 { /*508, WINED3DTS_WORLDMATRIX(252) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex },
4000 { /*509, WINED3DTS_WORLDMATRIX(253) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex },
4001 { /*510, WINED3DTS_WORLDMATRIX(254) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex },
4002 { /*511, WINED3DTS_WORLDMATRIX(255) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex },
4003 /* Various Vertex states follow */
4004 { /* , STATE_STREAMSRC */ STATE_VDECL, vertexdeclaration },
4005 { /* , STATE_VDECL */ STATE_VDECL, vertexdeclaration },
4006 { /* , STATE_VSHADER */ STATE_VDECL, vertexdeclaration },
4007 { /* , STATE_VIEWPORT */ STATE_VIEWPORT, viewport },
4008 { /* , STATE_VERTEXSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4009 { /* , STATE_PIXELSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4010 /* Lights */
4011 { /* , STATE_ACTIVELIGHT(0) */ STATE_ACTIVELIGHT(0), light },
4012 { /* , STATE_ACTIVELIGHT(1) */ STATE_ACTIVELIGHT(1), light },
4013 { /* , STATE_ACTIVELIGHT(2) */ STATE_ACTIVELIGHT(2), light },
4014 { /* , STATE_ACTIVELIGHT(3) */ STATE_ACTIVELIGHT(3), light },
4015 { /* , STATE_ACTIVELIGHT(4) */ STATE_ACTIVELIGHT(4), light },
4016 { /* , STATE_ACTIVELIGHT(5) */ STATE_ACTIVELIGHT(5), light },
4017 { /* , STATE_ACTIVELIGHT(6) */ STATE_ACTIVELIGHT(6), light },
4018 { /* , STATE_ACTIVELIGHT(7) */ STATE_ACTIVELIGHT(7), light },