wined3d: Enable color keying only for surfaces without an alpha channel.
[wine/wine-kai.git] / dlls / wined3d / state.c
blobe437136a7485282a474f975717f72a4eb18457ad
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] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
341 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
343 if(surf->CKeyFlags & DDSD_CKSRCBLT) {
344 const PixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format);
345 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
346 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
347 * surface has alpha bits
349 if(fmt->alphaMask == 0x00000000) {
350 enable_ckey = TRUE;
355 if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
356 (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
357 glEnable(GL_ALPHA_TEST);
358 checkGLcall("glEnable GL_ALPHA_TEST");
359 } else {
360 glDisable(GL_ALPHA_TEST);
361 checkGLcall("glDisable GL_ALPHA_TEST");
362 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
363 * enable call
365 return;
368 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
369 glParm = GL_NOTEQUAL;
370 ref = 0.0;
371 } else {
372 ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
373 glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
375 if(glParm) {
376 glAlphaFunc(glParm, ref);
377 checkGLcall("glAlphaFunc");
379 /* TODO: Some texture blending operations seem to affect the alpha test */
382 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
383 DWORD enable = 0xFFFFFFFF;
384 DWORD disable = 0x00000000;
386 /* TODO: Keep track of previously enabled clipplanes to avoid unneccessary resetting
387 * of already set values
390 /* If enabling / disabling all
391 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
393 if (stateblock->renderState[WINED3DRS_CLIPPING]) {
394 enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
395 disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
396 } else {
397 disable = 0xffffffff;
398 enable = 0x00;
401 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
402 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
403 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
404 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
405 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
406 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
408 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
409 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
410 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
411 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
412 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
413 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
415 /** update clipping status */
416 if (enable) {
417 stateblock->clip_status.ClipUnion = 0;
418 stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
419 } else {
420 stateblock->clip_status.ClipUnion = 0;
421 stateblock->clip_status.ClipIntersection = 0;
425 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
426 int glParm = GL_FUNC_ADD;
428 if(!GL_SUPPORT(EXT_BLEND_MINMAX)) {
429 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
430 return;
433 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
434 case WINED3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
435 case WINED3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
436 case WINED3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
437 case WINED3DBLENDOP_MIN : glParm = GL_MIN; break;
438 case WINED3DBLENDOP_MAX : glParm = GL_MAX; break;
439 default:
440 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
443 TRACE("glBlendEquation(%x)\n", glParm);
444 GL_EXTCALL(glBlendEquation(glParm));
445 checkGLcall("glBlendEquation");
448 static void
449 state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
450 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
451 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
452 * specular color. This is wrong:
453 * Separate specular color means the specular colour is maintained separately, whereas
454 * single color means it is merged in. However in both cases they are being used to
455 * some extent.
456 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
457 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
458 * running 1.4 yet!
461 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
462 * Instead, we need to setup the FinalCombiner properly.
464 * The default setup for the FinalCombiner is:
466 * <variable> <input> <mapping> <usage>
467 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
468 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
469 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
470 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
471 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
472 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
473 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
475 * That's pretty much fine as it is, except for variable B, which needs to take
476 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
477 * whether WINED3DRS_SPECULARENABLE is enabled or not.
480 TRACE("Setting specular enable state\n");
481 /* TODO: Add to the material setting functions */
482 if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
483 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
484 checkGLcall("glMaterialfv");
485 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
486 glEnable(GL_COLOR_SUM_EXT);
487 } else {
488 TRACE("Specular colors cannot be enabled in this version of opengl\n");
490 checkGLcall("glEnable(GL_COLOR_SUM)");
492 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
493 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
494 checkGLcall("glFinalCombinerInputNV()");
496 } else {
497 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
499 /* for the case of enabled lighting: */
500 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
501 checkGLcall("glMaterialfv");
503 /* for the case of disabled lighting: */
504 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
505 glDisable(GL_COLOR_SUM_EXT);
506 } else {
507 TRACE("Specular colors cannot be disabled in this version of opengl\n");
509 checkGLcall("glDisable(GL_COLOR_SUM)");
511 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
512 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
513 checkGLcall("glFinalCombinerInputNV()");
518 static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
519 unsigned int i;
521 /* Note the texture color applies to all textures whereas
522 * GL_TEXTURE_ENV_COLOR applies to active only
524 float col[4];
525 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
527 if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
528 /* And now the default texture color as well */
529 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
530 /* Note the WINED3DRS value applies to all textures, but GL has one
531 * per texture, so apply it now ready to be used!
533 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
534 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
535 checkGLcall("glActiveTextureARB");
536 } else if (i>0) {
537 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
540 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
541 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
543 } else {
544 GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
548 static void
549 renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass ) {
550 #if 0 /* Don't use OpenGL 2.0 calls for now */
551 if(GL_EXTCALL(glStencilFuncSeparate) && GL_EXTCALL(glStencilOpSeparate)) {
552 GL_EXTCALL(glStencilFuncSeparate(face, func, ref, mask));
553 checkGLcall("glStencilFuncSeparate(...)");
554 GL_EXTCALL(glStencilOpSeparate(face, stencilFail, depthFail, stencilPass));
555 checkGLcall("glStencilOpSeparate(...)");
557 else
558 #endif
559 if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
560 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
561 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
562 GL_EXTCALL(glActiveStencilFaceEXT(face));
563 checkGLcall("glActiveStencilFaceEXT(...)");
564 glStencilFunc(func, ref, mask);
565 checkGLcall("glStencilFunc(...)");
566 glStencilOp(stencilFail, depthFail, stencilPass);
567 checkGLcall("glStencilOp(...)");
568 } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
569 GL_EXTCALL(glStencilFuncSeparateATI(face, func, ref, mask));
570 checkGLcall("glStencilFuncSeparateATI(...)");
571 GL_EXTCALL(glStencilOpSeparateATI(face, stencilFail, depthFail, stencilPass));
572 checkGLcall("glStencilOpSeparateATI(...)");
573 } else {
574 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
578 static void
579 state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
580 DWORD onesided_enable = FALSE;
581 DWORD twosided_enable = FALSE;
582 GLint func = GL_ALWAYS;
583 GLint func_ccw = GL_ALWAYS;
584 GLint ref = 0;
585 GLuint mask = 0;
586 GLint stencilFail = GL_KEEP;
587 GLint depthFail = GL_KEEP;
588 GLint stencilPass = GL_KEEP;
589 GLint stencilFail_ccw = GL_KEEP;
590 GLint depthFail_ccw = GL_KEEP;
591 GLint stencilPass_ccw = GL_KEEP;
593 if( stateblock->set.renderState[WINED3DRS_STENCILENABLE] )
594 onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
595 if( stateblock->set.renderState[WINED3DRS_TWOSIDEDSTENCILMODE] )
596 twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
597 if( stateblock->set.renderState[WINED3DRS_STENCILFUNC] )
598 if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
599 func = GL_ALWAYS;
600 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFUNC] )
601 if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
602 func = GL_ALWAYS;
603 if( stateblock->set.renderState[WINED3DRS_STENCILREF] )
604 ref = stateblock->renderState[WINED3DRS_STENCILREF];
605 if( stateblock->set.renderState[WINED3DRS_STENCILMASK] )
606 mask = stateblock->renderState[WINED3DRS_STENCILMASK];
607 if( stateblock->set.renderState[WINED3DRS_STENCILFAIL] )
608 stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
609 if( stateblock->set.renderState[WINED3DRS_STENCILZFAIL] )
610 depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
611 if( stateblock->set.renderState[WINED3DRS_STENCILPASS] )
612 stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
613 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFAIL] )
614 stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
615 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILZFAIL] )
616 depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
617 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILPASS] )
618 stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
620 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
621 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
622 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
623 onesided_enable, twosided_enable, ref, mask,
624 func, stencilFail, depthFail, stencilPass,
625 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
627 if (twosided_enable) {
628 renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
629 renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
630 } else {
631 if (onesided_enable) {
632 glEnable(GL_STENCIL_TEST);
633 checkGLcall("glEnable GL_STENCIL_TEST");
634 glStencilFunc(func, ref, mask);
635 checkGLcall("glStencilFunc(...)");
636 glStencilOp(stencilFail, depthFail, stencilPass);
637 checkGLcall("glStencilOp(...)");
638 } else {
639 glDisable(GL_STENCIL_TEST);
640 checkGLcall("glDisable GL_STENCIL_TEST");
645 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
646 glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]);
647 checkGLcall("glStencilMask");
650 static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
651 /* TODO: Put this into the vertex type block once that is in the state table */
652 BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
653 float fogstart, fogend;
655 union {
656 DWORD d;
657 float f;
658 } tmpvalue;
660 if (!fogenable) {
661 /* No fog? Disable it, and we're done :-) */
662 glDisable(GL_FOG);
663 checkGLcall("glDisable GL_FOG");
666 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
667 fogstart = tmpvalue.f;
668 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
669 fogend = tmpvalue.f;
671 /* Activate when vertex shaders are in the state table */
672 if(stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function &&
673 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) {
674 glFogi(GL_FOG_MODE, GL_LINEAR);
675 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
676 fogstart = 1.0;
677 fogend = 0.0;
678 context->last_was_foggy_shader = TRUE;
680 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
681 * the system will apply only pixel(=table) fog effects."
683 else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == D3DFOG_NONE) {
684 glHint(GL_FOG_HINT, GL_FASTEST);
685 checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
686 context->last_was_foggy_shader = FALSE;
688 switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
689 /* Processed vertices have their fog factor stored in the specular value. Fall too the none case.
690 * If we are drawing untransformed vertices atm, d3ddevice_set_ortho will update the fog
692 case D3DFOG_EXP: {
693 if(!context->last_was_rhw) {
694 glFogi(GL_FOG_MODE, GL_EXP);
695 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
696 if(GL_SUPPORT(EXT_FOG_COORD)) {
697 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
698 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
700 break;
703 case D3DFOG_EXP2: {
704 if(!context->last_was_rhw) {
705 glFogi(GL_FOG_MODE, GL_EXP2);
706 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
707 if(GL_SUPPORT(EXT_FOG_COORD)) {
708 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
709 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
711 break;
714 case D3DFOG_LINEAR: {
715 if(!context->last_was_rhw) {
716 glFogi(GL_FOG_MODE, GL_LINEAR);
717 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
718 if(GL_SUPPORT(EXT_FOG_COORD)) {
719 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
720 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
722 break;
725 case D3DFOG_NONE: {
726 /* Both are none? According to msdn the alpha channel of the specular
727 * color contains a fog factor. Set it in drawStridedSlow.
728 * Same happens with Vertexfog on transformed vertices
730 if(GL_SUPPORT(EXT_FOG_COORD)) {
731 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
732 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
733 glFogi(GL_FOG_MODE, GL_LINEAR);
734 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
735 fogstart = 0xff;
736 fogend = 0x0;
737 } else {
738 /* Disable GL fog, handle this in software in drawStridedSlow */
739 fogenable = FALSE;
741 break;
743 default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
745 } else {
746 glHint(GL_FOG_HINT, GL_NICEST);
747 checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
748 context->last_was_foggy_shader = FALSE;
750 switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
751 case D3DFOG_EXP:
752 glFogi(GL_FOG_MODE, GL_EXP);
753 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
754 if(GL_SUPPORT(EXT_FOG_COORD)) {
755 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
756 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
758 break;
760 case D3DFOG_EXP2:
761 glFogi(GL_FOG_MODE, GL_EXP2);
762 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
763 if(GL_SUPPORT(EXT_FOG_COORD)) {
764 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
765 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
767 break;
769 case D3DFOG_LINEAR:
770 glFogi(GL_FOG_MODE, GL_LINEAR);
771 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
772 if(GL_SUPPORT(EXT_FOG_COORD)) {
773 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
774 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
776 break;
778 case D3DFOG_NONE: /* Won't happen */
779 default:
780 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
784 if(fogenable) {
785 glEnable(GL_FOG);
786 checkGLcall("glEnable GL_FOG");
788 glFogfv(GL_FOG_START, &fogstart);
789 checkGLcall("glFogf(GL_FOG_START, fogstart");
790 TRACE("Fog Start == %f\n", fogstart);
792 glFogfv(GL_FOG_END, &fogend);
793 checkGLcall("glFogf(GL_FOG_END, fogend");
794 TRACE("Fog End == %f\n", fogend);
795 } else {
796 glDisable(GL_FOG);
797 checkGLcall("glDisable GL_FOG");
800 if (GL_SUPPORT(NV_FOG_DISTANCE)) {
801 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
805 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
806 float col[4];
807 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
808 /* Set the default alpha blend color */
809 glFogfv(GL_FOG_COLOR, &col[0]);
810 checkGLcall("glFog GL_FOG_COLOR");
813 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
814 union {
815 DWORD d;
816 float f;
817 } tmpvalue;
818 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
819 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
820 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
823 /* TODO: Merge with primitive type + init_materials()!! */
824 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
825 IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)stateblock->wineD3DDevice;
826 GLenum Parm = 0;
827 WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
828 BOOL isDiffuseSupplied;
830 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
831 * The vertex declaration will call this function if the fixed function pipeline is used.
834 if(isStateDirty(context, STATE_VDECL)) {
835 return;
838 isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
840 if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
841 TRACE("diff %d, amb %d, emis %d, spec %d\n",
842 stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
843 stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
844 stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
845 stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
847 if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
848 if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
849 Parm = GL_AMBIENT_AND_DIFFUSE;
850 } else {
851 Parm = GL_DIFFUSE;
853 } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
854 Parm = GL_AMBIENT;
855 } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
856 Parm = GL_EMISSION;
857 } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
858 Parm = GL_SPECULAR;
862 /* Nothing changed, return. */
863 if (Parm == context->tracking_parm) return;
865 if(!Parm) {
866 glDisable(GL_COLOR_MATERIAL);
867 checkGLcall("glDisable GL_COLOR_MATERIAL");
868 } else {
869 glColorMaterial(GL_FRONT_AND_BACK, Parm);
870 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
871 glEnable(GL_COLOR_MATERIAL);
872 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
875 /* Apparently calls to glMaterialfv are ignored for properties we're
876 * tracking with glColorMaterial, so apply those here. */
877 switch (context->tracking_parm) {
878 case GL_AMBIENT_AND_DIFFUSE:
879 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
880 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
881 checkGLcall("glMaterialfv");
882 break;
884 case GL_DIFFUSE:
885 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
886 checkGLcall("glMaterialfv");
887 break;
889 case GL_AMBIENT:
890 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
891 checkGLcall("glMaterialfv");
892 break;
894 case GL_EMISSION:
895 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
896 checkGLcall("glMaterialfv");
897 break;
899 case GL_SPECULAR:
900 /* Only change material color if specular is enabled, otherwise it is set to black */
901 if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
902 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
903 checkGLcall("glMaterialfv");
904 } else {
905 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
906 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
907 checkGLcall("glMaterialfv");
909 break;
912 context->tracking_parm = Parm;
915 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
916 union {
917 DWORD d;
918 WINED3DLINEPATTERN lp;
919 } tmppattern;
920 tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
922 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
924 if (tmppattern.lp.wRepeatFactor) {
925 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
926 checkGLcall("glLineStipple(repeat, linepattern)");
927 glEnable(GL_LINE_STIPPLE);
928 checkGLcall("glEnable(GL_LINE_STIPPLE);");
929 } else {
930 glDisable(GL_LINE_STIPPLE);
931 checkGLcall("glDisable(GL_LINE_STIPPLE);");
935 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
936 union {
937 DWORD d;
938 float f;
939 } tmpvalue;
941 if (stateblock->renderState[WINED3DRS_ZBIAS]) {
942 tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
943 TRACE("ZBias value %f\n", tmpvalue.f);
944 glPolygonOffset(0, -tmpvalue.f);
945 checkGLcall("glPolygonOffset(0, -Value)");
946 glEnable(GL_POLYGON_OFFSET_FILL);
947 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
948 glEnable(GL_POLYGON_OFFSET_LINE);
949 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
950 glEnable(GL_POLYGON_OFFSET_POINT);
951 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
952 } else {
953 glDisable(GL_POLYGON_OFFSET_FILL);
954 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
955 glDisable(GL_POLYGON_OFFSET_LINE);
956 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
957 glDisable(GL_POLYGON_OFFSET_POINT);
958 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
963 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
964 if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
965 glEnable(GL_NORMALIZE);
966 checkGLcall("glEnable(GL_NORMALIZE);");
967 } else {
968 glDisable(GL_NORMALIZE);
969 checkGLcall("glDisable(GL_NORMALIZE);");
973 static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
974 union {
975 DWORD d;
976 float f;
977 } tmpvalue;
979 /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
980 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
981 TRACE("Set point size to %f\n", tmpvalue.f);
982 glPointSize(tmpvalue.f);
983 checkGLcall("glPointSize(...);");
986 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
987 union {
988 DWORD d;
989 float f;
990 } tmpvalue;
992 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
993 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
994 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
995 checkGLcall("glPointParameterfARB(...");
997 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
998 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
999 checkGLcall("glPointParameterfEXT(...);");
1000 } else if(tmpvalue.f != 1.0) {
1001 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1005 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1006 union {
1007 DWORD d;
1008 float f;
1009 } tmpvalue;
1011 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1012 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1013 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
1014 checkGLcall("glPointParameterfARB(...");
1016 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1017 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
1018 checkGLcall("glPointParameterfEXT(...);");
1019 } else if(tmpvalue.f != 64.0) {
1020 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1024 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1025 /* TODO: Group this with the viewport */
1027 * POINTSCALEENABLE controls how point size value is treated. If set to
1028 * true, the point size is scaled with respect to height of viewport.
1029 * When set to false point size is in pixels.
1031 * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
1034 /* Default values */
1035 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1038 * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
1039 * This means that OpenGL will clamp really small point sizes to 1.0f.
1040 * To correct for this we need to multiply by the scale factor when sizes
1041 * are less than 1.0f. scale_factor = 1.0f / point_size.
1043 GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
1044 if(pointSize > 0.0f) {
1045 GLfloat scaleFactor;
1047 if(pointSize < 1.0f) {
1048 scaleFactor = pointSize * pointSize;
1049 } else {
1050 scaleFactor = 1.0f;
1053 if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1054 att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
1055 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1056 att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
1057 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1058 att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
1059 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1063 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1064 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1065 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
1067 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1068 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1069 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
1070 } else {
1071 TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
1075 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1076 DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1078 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1079 Value & D3DCOLORWRITEENABLE_RED ? 1 : 0,
1080 Value & D3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1081 Value & D3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1082 Value & D3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1083 glColorMask(Value & D3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1084 Value & D3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1085 Value & D3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1086 Value & D3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1087 checkGLcall("glColorMask(...)");
1089 /* depends on WINED3DRS_COLORWRITEENABLE. */
1090 if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1091 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1092 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1093 ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1094 stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1095 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1096 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1100 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1101 if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1102 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1103 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1104 } else {
1105 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1106 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1110 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1111 if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1112 TRACE("Last Pixel Drawing Enabled\n");
1113 } else {
1114 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1118 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1119 unsigned int i;
1120 int val;
1122 /* TODO: NV_POINT_SPRITE */
1123 if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1124 TRACE("Point sprites not supported\n");
1125 return;
1128 if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1129 val = GL_TRUE;
1130 } else {
1131 val = GL_FALSE;
1134 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
1135 /* Note the WINED3DRS value applies to all textures, but GL has one
1136 * per texture, so apply it now ready to be used!
1138 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1139 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
1140 checkGLcall("glActiveTextureARB");
1141 } else if (i==1) {
1142 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1143 break;
1146 glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, val);
1147 checkGLcall((val?"glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)":
1148 "glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE)"));
1152 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1154 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1155 http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/FixedFunction/Textures/texturewrapping.asp
1156 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1157 Descussion that ways to turn on WRAPing to solve an opengl conversion problem.
1158 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1160 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1162 TRACE("Stub\n");
1163 if(stateblock->renderState[WINED3DRS_WRAP0] ||
1164 stateblock->renderState[WINED3DRS_WRAP1] ||
1165 stateblock->renderState[WINED3DRS_WRAP2] ||
1166 stateblock->renderState[WINED3DRS_WRAP3] ||
1167 stateblock->renderState[WINED3DRS_WRAP4] ||
1168 stateblock->renderState[WINED3DRS_WRAP5] ||
1169 stateblock->renderState[WINED3DRS_WRAP6] ||
1170 stateblock->renderState[WINED3DRS_WRAP7] ||
1171 stateblock->renderState[WINED3DRS_WRAP8] ||
1172 stateblock->renderState[WINED3DRS_WRAP9] ||
1173 stateblock->renderState[WINED3DRS_WRAP10] ||
1174 stateblock->renderState[WINED3DRS_WRAP11] ||
1175 stateblock->renderState[WINED3DRS_WRAP12] ||
1176 stateblock->renderState[WINED3DRS_WRAP13] ||
1177 stateblock->renderState[WINED3DRS_WRAP14] ||
1178 stateblock->renderState[WINED3DRS_WRAP15] ) {
1179 ERR("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1183 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1184 if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1185 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1186 glEnable(GL_MULTISAMPLE_ARB);
1187 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1188 } else {
1189 glDisable(GL_MULTISAMPLE_ARB);
1190 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1192 } else {
1193 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1194 ERR("Multisample antialiasing not supported by gl\n");
1199 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1200 if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1201 glEnable(GL_SCISSOR_TEST);
1202 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1203 } else {
1204 glDisable(GL_SCISSOR_TEST);
1205 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1209 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1210 union {
1211 DWORD d;
1212 float f;
1213 } tmpvalue;
1215 if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1216 stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1217 tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1218 glEnable(GL_POLYGON_OFFSET_FILL);
1219 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1220 glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1221 checkGLcall("glPolygonOffset(...)");
1222 } else {
1223 glDisable(GL_POLYGON_OFFSET_FILL);
1224 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1228 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1229 if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1230 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1231 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1232 } else {
1233 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1234 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1238 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1239 TRACE("Stub\n");
1240 if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1241 ERR(" Stippled Alpha not supported yet.\n");
1244 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1245 TRACE("Stub\n");
1246 if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1247 ERR(" Antialias not supported yet.\n");
1250 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1251 TRACE("Stub\n");
1252 if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1253 ERR("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1256 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1257 TRACE("Stub\n");
1258 if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != D3DPATCHEDGE_DISCRETE)
1259 ERR("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1262 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1263 union {
1264 DWORD d;
1265 float f;
1266 } tmpvalue;
1267 tmpvalue.f = 1.0f;
1269 TRACE("Stub\n");
1270 if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1271 ERR("(WINED3DRS_PATCHSEGMENTS,%d) not yet implemented\n", tmpvalue.d);
1274 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1275 TRACE("Stub\n");
1276 if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != D3DDEGREE_CUBIC)
1277 ERR("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1280 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1281 TRACE("Stub\n");
1282 if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != D3DDEGREE_LINEAR)
1283 ERR("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1286 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1287 TRACE("Stub\n");
1288 if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1289 FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1293 static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1294 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
1295 ERR("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
1298 static void state_seperateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1299 TRACE("Stub\n");
1300 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
1301 FIXME("(WINED3DRS_SEPARATEALPHABLENDENABLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]);
1304 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1305 if(stateblock->renderState[WINED3DRS_WRAPU]) {
1306 FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1310 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1311 if(stateblock->renderState[WINED3DRS_WRAPV]) {
1312 FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1316 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1317 if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1318 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1322 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1323 if(stateblock->renderState[WINED3DRS_ROP2]) {
1324 FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1328 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1329 if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1330 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1334 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1335 if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1336 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1340 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1341 if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1342 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1346 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1347 if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1348 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1352 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1353 if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1354 FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1358 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1359 if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1360 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1364 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1365 if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1366 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1370 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1371 if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1372 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1376 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1377 if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1378 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1382 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1383 if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1384 FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1388 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1389 if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1390 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1394 /* Activates the texture dimension according to the bound D3D texture.
1395 * Does not care for the colorop or correct gl texture unit(when using nvrc)
1396 * Requires the caller to activate the correct unit before
1398 static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock) {
1399 if(stateblock->textures[stage]) {
1400 glDisable(GL_TEXTURE_1D);
1401 checkGLcall("glDisable(GL_TEXTURE_1D)");
1402 switch(stateblock->textureDimensions[stage]) {
1403 case GL_TEXTURE_2D:
1404 glDisable(GL_TEXTURE_3D);
1405 checkGLcall("glDisable(GL_TEXTURE_3D)");
1406 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1407 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1408 glEnable(GL_TEXTURE_2D);
1409 checkGLcall("glEnable(GL_TEXTURE_2D)");
1410 break;
1411 case GL_TEXTURE_3D:
1412 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1413 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1414 glDisable(GL_TEXTURE_2D);
1415 checkGLcall("glDisable(GL_TEXTURE_2D)");
1416 glEnable(GL_TEXTURE_3D);
1417 checkGLcall("glEnable(GL_TEXTURE_3D)");
1418 break;
1419 case GL_TEXTURE_CUBE_MAP_ARB:
1420 glDisable(GL_TEXTURE_2D);
1421 checkGLcall("glDisable(GL_TEXTURE_2D)");
1422 glDisable(GL_TEXTURE_3D);
1423 checkGLcall("glDisable(GL_TEXTURE_3D)");
1424 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
1425 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
1426 break;
1428 } else {
1429 glDisable(GL_TEXTURE_2D);
1430 checkGLcall("glDisable(GL_TEXTURE_2D)");
1431 glDisable(GL_TEXTURE_3D);
1432 checkGLcall("glDisable(GL_TEXTURE_3D)");
1433 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1434 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1435 glEnable(GL_TEXTURE_1D);
1436 checkGLcall("glEnable(GL_TEXTURE_1D)");
1437 /* Binding textures is done by samplers. A dummy texture will be bound */
1441 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1442 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1443 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1445 TRACE("Setting color op for stage %d\n", stage);
1447 if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1448 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1449 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1450 return;
1453 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1455 if (mapped_stage != -1) {
1456 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1457 if (mapped_stage >= GL_LIMITS(sampler_stages)) {
1458 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1459 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1460 FIXME("Attempt to enable unsupported stage!\n");
1462 return;
1464 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1465 checkGLcall("glActiveTextureARB");
1466 } else if (stage > 0) {
1467 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1468 return;
1472 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1473 if(stateblock->lowest_disabled_stage > 0) {
1474 glEnable(GL_REGISTER_COMBINERS_NV);
1475 GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, stateblock->lowest_disabled_stage));
1476 } else {
1477 glDisable(GL_REGISTER_COMBINERS_NV);
1480 if(stage >= stateblock->lowest_disabled_stage) {
1481 TRACE("Stage disabled\n");
1482 if (mapped_stage != -1) {
1483 /* Disable everything here */
1484 glDisable(GL_TEXTURE_1D);
1485 checkGLcall("glDisable(GL_TEXTURE_1D)");
1486 glDisable(GL_TEXTURE_2D);
1487 checkGLcall("glDisable(GL_TEXTURE_2D)");
1488 glDisable(GL_TEXTURE_3D);
1489 checkGLcall("glDisable(GL_TEXTURE_3D)");
1490 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1491 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1493 /* All done */
1494 return;
1497 /* The sampler will also activate the correct texture dimensions, so no need to do it here
1498 * if the sampler for this stage is dirty
1500 if(!isStateDirty(context, STATE_SAMPLER(stage))) {
1501 if (mapped_stage != -1) activate_dimensions(stage, stateblock);
1504 /* Set the texture combiners */
1505 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1506 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1507 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1508 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1509 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1510 stateblock->textureState[stage][WINED3DTSS_COLORARG0],
1511 mapped_stage);
1512 } else {
1513 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1514 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1515 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1516 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1517 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1521 static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1522 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1523 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1525 TRACE("Setting alpha op for stage %d\n", stage);
1526 /* Do not care for enabled / disabled stages, just assign the settigns. colorop disables / enables required stuff */
1527 if (mapped_stage != -1) {
1528 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1529 if (stage >= GL_LIMITS(sampler_stages)) {
1530 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1531 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1532 FIXME("Attempt to enable unsupported stage!\n");
1534 return;
1536 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1537 checkGLcall("glActiveTextureARB");
1538 } else if (stage > 0) {
1539 /* We can't do anything here */
1540 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1541 return;
1545 TRACE("Setting alpha op for stage %d\n", stage);
1546 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1547 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1548 stateblock->textureState[stage][WINED3DTSS_ALPHAOP],
1549 stateblock->textureState[stage][WINED3DTSS_ALPHAARG1],
1550 stateblock->textureState[stage][WINED3DTSS_ALPHAARG2],
1551 stateblock->textureState[stage][WINED3DTSS_ALPHAARG0],
1552 mapped_stage);
1553 } else {
1554 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage, stateblock->textureState[stage][WINED3DTSS_ALPHAOP],
1555 stateblock->textureState[stage][WINED3DTSS_ALPHAARG1],
1556 stateblock->textureState[stage][WINED3DTSS_ALPHAARG2],
1557 stateblock->textureState[stage][WINED3DTSS_ALPHAARG0]);
1561 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1562 DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1564 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1565 if(texUnit >= GL_LIMITS(sampler_stages)) {
1566 return;
1568 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stateblock->wineD3DDevice->texUnitMap[texUnit]));
1569 checkGLcall("glActiveTextureARB");
1570 } else if (texUnit > 0) {
1571 /* We can't do anything here */
1572 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1573 return;
1576 set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1577 stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1578 (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU);
1582 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd);
1584 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1585 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1586 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1588 if (mapped_stage == -1) {
1589 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
1590 return;
1593 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1594 if(stage >= GL_LIMITS(sampler_stages)) {
1595 return;
1597 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1598 checkGLcall("glActiveTextureARB");
1599 } else if (stage > 0) {
1600 /* We can't do anything here */
1601 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1602 return;
1605 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
1607 * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
1608 * one flag, you can still specify an index value, which the system uses to
1609 * determine the texture wrapping mode.
1610 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
1611 * means use the vertex position (camera-space) as the input texture coordinates
1612 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
1613 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
1614 * to the TEXCOORDINDEX value
1618 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
1620 switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
1621 case WINED3DTSS_TCI_PASSTHRU:
1622 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
1623 glDisable(GL_TEXTURE_GEN_S);
1624 glDisable(GL_TEXTURE_GEN_T);
1625 glDisable(GL_TEXTURE_GEN_R);
1626 glDisable(GL_TEXTURE_GEN_Q);
1627 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
1628 break;
1630 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
1631 /* CameraSpacePosition means use the vertex position, transformed to camera space,
1632 * as the input texture coordinates for this stage's texture transformation. This
1633 * equates roughly to EYE_LINEAR
1636 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1637 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1638 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1639 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1640 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
1642 glMatrixMode(GL_MODELVIEW);
1643 glPushMatrix();
1644 glLoadIdentity();
1645 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1646 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1647 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1648 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1649 glPopMatrix();
1651 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
1652 glEnable(GL_TEXTURE_GEN_S);
1653 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1654 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1655 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1656 glEnable(GL_TEXTURE_GEN_T);
1657 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1658 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1659 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1660 glEnable(GL_TEXTURE_GEN_R);
1661 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1662 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1663 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1665 break;
1667 case WINED3DTSS_TCI_CAMERASPACENORMAL:
1669 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1670 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1671 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1672 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1673 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1674 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
1676 glMatrixMode(GL_MODELVIEW);
1677 glPushMatrix();
1678 glLoadIdentity();
1679 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1680 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1681 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1682 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1683 glPopMatrix();
1685 glEnable(GL_TEXTURE_GEN_S);
1686 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1687 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1688 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1689 glEnable(GL_TEXTURE_GEN_T);
1690 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1691 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1692 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1693 glEnable(GL_TEXTURE_GEN_R);
1694 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1695 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1696 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1699 break;
1701 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
1703 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1704 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1705 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1706 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1707 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1708 TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
1710 glMatrixMode(GL_MODELVIEW);
1711 glPushMatrix();
1712 glLoadIdentity();
1713 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1714 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1715 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1716 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1717 glPopMatrix();
1719 glEnable(GL_TEXTURE_GEN_S);
1720 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1721 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1722 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1723 glEnable(GL_TEXTURE_GEN_T);
1724 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1725 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1726 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1727 glEnable(GL_TEXTURE_GEN_R);
1728 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1729 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1730 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1733 break;
1735 /* Unhandled types: */
1736 default:
1737 /* Todo: */
1738 /* ? disable GL_TEXTURE_GEN_n ? */
1739 glDisable(GL_TEXTURE_GEN_S);
1740 glDisable(GL_TEXTURE_GEN_T);
1741 glDisable(GL_TEXTURE_GEN_R);
1742 glDisable(GL_TEXTURE_GEN_Q);
1743 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
1744 break;
1747 /* Update the texture matrix */
1748 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
1749 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
1752 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
1753 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
1754 * source. Call loadVertexData directly because there is no need to reparse the vertex declaration
1755 * and do all the things linked to it
1756 * TODO: Tidy that up to reload only the arrays of the changed unit
1758 loadVertexData(stateblock, &stateblock->wineD3DDevice->strided_streams);
1762 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1763 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1764 union {
1765 DWORD d;
1766 float f;
1767 } tmpvalue;
1769 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
1770 if(tmpvalue.f != 0.0) {
1771 ERR("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
1775 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1776 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1777 union {
1778 DWORD d;
1779 float f;
1780 } tmpvalue;
1782 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
1783 if(tmpvalue.f != 0.0) {
1784 ERR("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
1788 static void tex_resultarg(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1789 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1791 if(stage >= GL_LIMITS(texture_stages)) {
1792 return;
1795 if(stateblock->textureState[stage][WINED3DTSS_RESULTARG] != D3DTA_CURRENT) {
1796 ERR("WINED3DTSS_RESULTARG not supported yet\n");
1800 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1801 DWORD sampler = state - STATE_SAMPLER(0);
1802 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
1803 union {
1804 float f;
1805 DWORD d;
1806 } tmpvalue;
1808 TRACE("Sampler: %d\n", sampler);
1809 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
1810 * only has to bind textures and set the per texture states
1813 if (mapped_stage == -1) {
1814 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
1815 return;
1818 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1819 if(sampler >= GL_LIMITS(sampler_stages)) {
1820 return;
1822 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1823 checkGLcall("glActiveTextureARB");
1824 } else if (sampler > 0) {
1825 /* We can't do anything here */
1826 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1827 return;
1830 if(stateblock->textures[sampler]) {
1831 BOOL texIsPow2 = FALSE;
1833 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
1834 * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
1835 * scaling is reapplied or removed, the texture matrix has to be reapplied
1837 if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
1838 if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
1839 if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
1840 ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
1841 texIsPow2 = TRUE;
1843 } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
1844 if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
1845 texIsPow2 = TRUE;
1849 if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
1850 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
1851 context->lastWasPow2Texture[sampler] = texIsPow2;
1855 IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
1856 IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
1858 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
1859 tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
1860 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
1861 GL_TEXTURE_LOD_BIAS_EXT,
1862 tmpvalue.f);
1863 checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
1866 if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
1867 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1868 /* Using a pixel shader? Verify the sampler types */
1870 /* Make sure that the texture dimensions are enabled. I don't have to disable the other
1871 * dimensions because the shader knows from which texture type to sample from. For the sake of
1872 * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
1873 * dimensions. This should make wrong sampling sources visible :-)
1875 glEnable(stateblock->textureDimensions[sampler]);
1876 checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
1877 } else if(sampler < stateblock->lowest_disabled_stage) {
1878 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1879 activate_dimensions(sampler, stateblock);
1882 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
1883 /* If color keying is enabled update the alpha test, it depends on the existence
1884 * of a color key in stage 0
1886 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
1889 } else if(sampler < GL_LIMITS(texture_stages)) {
1890 if(sampler < stateblock->lowest_disabled_stage) {
1891 /* TODO: What should I do with pixel shaders here ??? */
1892 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1893 activate_dimensions(sampler, stateblock);
1895 } /* Otherwise tex_colorop disables the stage */
1896 glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
1897 checkGLcall("glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
1901 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1902 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
1904 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
1905 * has an update pending
1907 if(isStateDirty(context, STATE_VDECL) ||
1908 isStateDirty(context, STATE_PIXELSHADER)) {
1909 return;
1912 device->shader_backend->shader_load_constants((IWineD3DDevice *) device,
1913 stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function,
1914 stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function);
1917 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1918 BOOL use_ps = stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function != NULL;
1919 BOOL use_vs = stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL;
1920 int i;
1922 if (use_ps) {
1923 if(!context->last_was_pshader) {
1924 /* Former draw without a pixel shader, some samplers
1925 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
1926 * make sure to enable them
1928 for(i=0; i < MAX_SAMPLERS; i++) {
1929 if(!isStateDirty(context, STATE_SAMPLER(i))) {
1930 sampler(STATE_SAMPLER(i), stateblock, context);
1933 } else {
1934 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
1935 * if a different texture was bound. I don't have to do anything.
1939 /* Compile and bind the shader */
1940 IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
1941 } else {
1942 /* Disabled the pixel shader - color ops weren't applied
1943 * while it was enabled, so re-apply them.
1945 for(i=0; i < MAX_TEXTURES; i++) {
1946 if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
1947 tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
1952 if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
1953 stateblock->wineD3DDevice->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_ps, use_vs);
1955 if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vs || use_ps)) {
1956 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
1960 context->last_was_pshader = use_ps;
1963 static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1964 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1966 if(stateblock->pixelShader && stage != 0 &&
1967 ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->needsbumpmat == stage) {
1968 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
1969 * anyway
1971 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
1972 !isStateDirty(context, STATE_PIXELSHADER)) {
1973 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
1978 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1979 /* This function is called by transform_view below if the view matrix was changed too
1981 * Deliberately no check if the vertex declaration is dirty because the vdecl state
1982 * does not always update the world matrix, only on a switch between transformed
1983 * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
1984 * draw, but that should be rather rare and cheaper in total.
1986 glMatrixMode(GL_MODELVIEW);
1987 checkGLcall("glMatrixMode");
1989 if(context->last_was_rhw) {
1990 glLoadIdentity();
1991 checkGLcall("glLoadIdentity()");
1992 } else {
1993 /* In the general case, the view matrix is the identity matrix */
1994 if (stateblock->wineD3DDevice->view_ident) {
1995 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
1996 checkGLcall("glLoadMatrixf");
1997 } else {
1998 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
1999 checkGLcall("glLoadMatrixf");
2000 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2001 checkGLcall("glMultMatrixf");
2006 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2007 unsigned int k;
2009 /* If we are changing the View matrix, reset the light and clipping planes to the new view
2010 * NOTE: We have to reset the positions even if the light/plane is not currently
2011 * enabled, since the call to enable it will not reset the position.
2012 * NOTE2: Apparently texture transforms do NOT need reapplying
2015 PLIGHTINFOEL *light = NULL;
2017 glMatrixMode(GL_MODELVIEW);
2018 checkGLcall("glMatrixMode(GL_MODELVIEW)");
2019 glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2020 checkGLcall("glLoadMatrixf(...)");
2022 /* Reset lights. TODO: Call light apply func */
2023 for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
2024 light = stateblock->activeLights[k];
2025 if(!light) continue;
2026 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
2027 checkGLcall("glLightfv posn");
2028 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
2029 checkGLcall("glLightfv dirn");
2032 /* Reset Clipping Planes if clipping is enabled. TODO: Call clipplane apply func */
2033 for (k = 0; k < GL_LIMITS(clipplanes); k++) {
2034 glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]);
2035 checkGLcall("glClipPlane");
2038 if(context->last_was_rhw) {
2039 glLoadIdentity();
2040 checkGLcall("glLoadIdentity()");
2041 /* No need to update the world matrix, the identity is fine */
2042 return;
2045 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
2046 * No need to do it here if the state is scheduled for update.
2048 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
2049 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2053 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2054 WARN("World matrix 1 - 255 not supported yet\n");
2057 static const GLfloat invymat[16] = {
2058 1.0f, 0.0f, 0.0f, 0.0f,
2059 0.0f, -1.0f, 0.0f, 0.0f,
2060 0.0f, 0.0f, 1.0f, 0.0f,
2061 0.0f, 0.0f, 0.0f, 1.0f};
2063 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2064 glMatrixMode(GL_PROJECTION);
2065 checkGLcall("glMatrixMode(GL_PROJECTION)");
2066 glLoadIdentity();
2067 checkGLcall("glLoadIdentity");
2069 if(context->last_was_rhw) {
2070 double X, Y, height, width, minZ, maxZ;
2072 X = stateblock->viewport.X;
2073 Y = stateblock->viewport.Y;
2074 height = stateblock->viewport.Height;
2075 width = stateblock->viewport.Width;
2076 minZ = stateblock->viewport.MinZ;
2077 maxZ = stateblock->viewport.MaxZ;
2079 if(!stateblock->wineD3DDevice->untransformed) {
2080 /* Transformed vertices are supposed to bypass the whole transform pipeline including
2081 * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2082 * suppress depth clipping. This can be done because it is an orthogonal projection and
2083 * the Z coordinate does not affect the size of the primitives
2085 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2086 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2087 } else {
2088 /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2089 * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2090 * unmodified to opengl.
2092 * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2093 * replacement shader.
2095 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2096 glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
2098 checkGLcall("glOrtho");
2100 /* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */
2101 glTranslatef(0.375, 0.375, 0);
2102 checkGLcall("glTranslatef(0.375, 0.375, 0)");
2103 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2104 * render everything upside down when rendering offscreen. */
2105 if (stateblock->wineD3DDevice->render_offscreen) {
2106 glMultMatrixf(invymat);
2107 checkGLcall("glMultMatrixf(invymat)");
2109 } else {
2110 /* The rule is that the window coordinate 0 does not correspond to the
2111 beginning of the first pixel, but the center of the first pixel.
2112 As a consequence if you want to correctly draw one line exactly from
2113 the left to the right end of the viewport (with all matrices set to
2114 be identity), the x coords of both ends of the line would be not
2115 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2116 instead. */
2117 glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
2118 checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
2120 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2121 * render everything upside down when rendering offscreen. */
2122 if (stateblock->wineD3DDevice->render_offscreen) {
2123 glMultMatrixf(invymat);
2124 checkGLcall("glMultMatrixf(invymat)");
2126 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2127 checkGLcall("glLoadMatrixf");
2131 /* This should match any arrays loaded in loadVertexData.
2132 * stateblock impl is required for GL_SUPPORT
2133 * TODO: Only load / unload arrays if we have to.
2135 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2136 int texture_idx;
2138 glDisableClientState(GL_VERTEX_ARRAY);
2139 glDisableClientState(GL_NORMAL_ARRAY);
2140 glDisableClientState(GL_COLOR_ARRAY);
2141 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2142 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2144 for (texture_idx = 0; texture_idx < GL_LIMITS(textures); ++texture_idx) {
2145 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2146 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2150 /* This should match any arrays loaded in loadNumberedArrays
2151 * TODO: Only load / unload arrays if we have to.
2153 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2154 /* disable any attribs (this is the same for both GLSL and ARB modes) */
2155 GLint maxAttribs;
2156 int i;
2158 /* Leave all the attribs disabled */
2159 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2160 /* MESA does not support it right not */
2161 if (glGetError() != GL_NO_ERROR)
2162 maxAttribs = 16;
2163 for (i = 0; i < maxAttribs; ++i) {
2164 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2165 checkGLcall("glDisableVertexAttribArrayARB(reg);");
2169 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2170 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2171 int i;
2172 UINT *offset = stateblock->streamOffset;
2174 /* Default to no instancing */
2175 stateblock->wineD3DDevice->instancedDraw = FALSE;
2177 for (i = 0; i < MAX_ATTRIBS; i++) {
2179 if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2180 continue;
2182 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
2183 if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) {
2184 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2185 stateblock->wineD3DDevice->instancedDraw = TRUE;
2186 continue;
2189 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2191 if(strided->u.input[i].dwStride) {
2192 if(curVBO != strided->u.input[i].VBO) {
2193 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2194 checkGLcall("glBindBufferARB");
2195 curVBO = strided->u.input[i].VBO;
2197 GL_EXTCALL(glVertexAttribPointerARB(i,
2198 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2199 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2200 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2201 strided->u.input[i].dwStride,
2202 strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + offset[strided->u.input[i].streamNo]) );
2203 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2204 } else {
2205 /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
2206 * set up the attribute statically. But we have to figure out the system memory address.
2208 BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
2209 if(strided->u.input[i].VBO) {
2210 IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2211 ptr += (long) vb->resource.allocatedMemory;
2213 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2215 switch(strided->u.input[i].dwType) {
2216 case WINED3DDECLTYPE_FLOAT1:
2217 GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
2218 break;
2219 case WINED3DDECLTYPE_FLOAT2:
2220 GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
2221 break;
2222 case WINED3DDECLTYPE_FLOAT3:
2223 GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
2224 break;
2225 case WINED3DDECLTYPE_FLOAT4:
2226 GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
2227 break;
2229 case WINED3DDECLTYPE_UBYTE4:
2230 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2231 break;
2232 case WINED3DDECLTYPE_UBYTE4N:
2233 case WINED3DDECLTYPE_D3DCOLOR:
2234 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2235 break;
2237 case WINED3DDECLTYPE_SHORT2:
2238 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2239 break;
2240 case WINED3DDECLTYPE_SHORT4:
2241 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2242 break;
2244 case WINED3DDECLTYPE_SHORT2N:
2246 GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
2247 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
2248 break;
2250 case WINED3DDECLTYPE_USHORT2N:
2252 GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
2253 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
2254 break;
2256 case WINED3DDECLTYPE_SHORT4N:
2257 GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
2258 break;
2259 case WINED3DDECLTYPE_USHORT4N:
2260 GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
2261 break;
2263 case WINED3DDECLTYPE_UDEC3:
2264 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
2265 /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
2266 break;
2267 case WINED3DDECLTYPE_DEC3N:
2268 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
2269 /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
2270 break;
2272 case WINED3DDECLTYPE_FLOAT16_2:
2273 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
2274 * byte float according to the IEEE standard
2276 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
2277 break;
2278 case WINED3DDECLTYPE_FLOAT16_4:
2279 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
2280 break;
2282 case WINED3DDECLTYPE_UNUSED:
2283 default:
2284 ERR("Unexpected declaration in stride 0 attributes\n");
2285 break;
2292 /* Used from 2 different functions, and too big to justify making it inlined */
2293 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
2294 unsigned int textureNo = 0;
2295 unsigned int texture_idx = 0;
2296 UINT *offset = stateblock->streamOffset;
2297 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2299 TRACE("Using fast vertex array code\n");
2301 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
2302 stateblock->wineD3DDevice->instancedDraw = FALSE;
2304 /* Blend Data ---------------------------------------------- */
2305 if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
2306 (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
2309 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2311 #if 1
2312 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
2313 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
2314 #endif
2316 TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2317 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2318 /* FIXME("TODO\n");*/
2319 /* Note dwType == float3 or float4 == 2 or 3 */
2321 #if 0
2322 /* with this on, the normals appear to be being modified,
2323 but the vertices aren't being translated as they should be
2324 Maybe the world matrix aren't being setup properly? */
2325 glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1);
2326 #endif
2329 VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
2330 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
2331 sd->u.s.blendWeights.dwStride,
2332 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
2334 if(curVBO != sd->u.s.blendWeights.VBO) {
2335 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
2336 checkGLcall("glBindBufferARB");
2337 curVBO = sd->u.s.blendWeights.VBO;
2340 GL_EXTCALL(glWeightPointerARB)(
2341 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2342 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2343 sd->u.s.blendWeights.dwStride,
2344 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2346 checkGLcall("glWeightPointerARB");
2348 if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
2349 static BOOL showfixme = TRUE;
2350 if(showfixme){
2351 FIXME("blendMatrixIndices support\n");
2352 showfixme = FALSE;
2356 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2357 /* FIXME("TODO\n");*/
2358 #if 0
2360 GL_EXTCALL(glVertexWeightPointerEXT)(
2361 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2362 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2363 sd->u.s.blendWeights.dwStride,
2364 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2365 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
2366 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2367 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2368 #endif
2370 } else {
2371 /* TODO: support blends in fixupVertices */
2372 FIXME("unsupported blending in openGl\n");
2374 } else {
2375 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2376 #if 0 /* TODO: Vertex blending */
2377 glDisable(GL_VERTEX_BLEND_ARB);
2378 #endif
2379 TRACE("ARB_VERTEX_BLEND\n");
2380 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2381 TRACE(" EXT_VERTEX_WEIGHTING\n");
2382 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2383 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2388 #if 0 /* FOG ----------------------------------------------*/
2389 if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
2390 /* TODO: fog*/
2391 if (GL_SUPPORT(EXT_FOG_COORD) {
2392 glEnableClientState(GL_FOG_COORDINATE_EXT);
2393 (GL_EXTCALL)(FogCoordPointerEXT)(
2394 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
2395 sd->u.s.fog.dwStride,
2396 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
2397 } else {
2398 /* don't bother falling back to 'slow' as we don't support software FOG yet. */
2399 /* FIXME: fixme once */
2400 TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
2402 } else {
2403 if (GL_SUPPRT(EXT_FOR_COORD) {
2404 /* make sure fog is disabled */
2405 glDisableClientState(GL_FOG_COORDINATE_EXT);
2408 #endif
2410 #if 0 /* tangents ----------------------------------------------*/
2411 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
2412 sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2413 /* TODO: tangents*/
2414 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2415 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
2416 glEnable(GL_TANGENT_ARRAY_EXT);
2417 (GL_EXTCALL)(TangentPointerEXT)(
2418 WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
2419 sd->u.s.tangent.dwStride,
2420 sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
2421 } else {
2422 glDisable(GL_TANGENT_ARRAY_EXT);
2424 if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2425 glEnable(GL_BINORMAL_ARRAY_EXT);
2426 (GL_EXTCALL)(BinormalPointerEXT)(
2427 WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
2428 sd->u.s.binormal.dwStride,
2429 sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
2430 } else{
2431 glDisable(GL_BINORMAL_ARRAY_EXT);
2434 } else {
2435 /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
2436 /* FIXME: fixme once */
2437 TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
2439 } else {
2440 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2441 /* make sure fog is disabled */
2442 glDisable(GL_TANGENT_ARRAY_EXT);
2443 glDisable(GL_BINORMAL_ARRAY_EXT);
2446 #endif
2448 /* Point Size ----------------------------------------------*/
2449 if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
2451 /* no such functionality in the fixed function GL pipeline */
2452 TRACE("Cannot change ptSize here in openGl\n");
2453 /* TODO: Implement this function in using shaders if they are available */
2457 /* Vertex Pointers -----------------------------------------*/
2458 if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
2459 /* Note dwType == float3 or float4 == 2 or 3 */
2460 VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
2461 sd->u.s.position.dwStride,
2462 sd->u.s.position.dwType + 1,
2463 sd->u.s.position.lpData));
2465 if(curVBO != sd->u.s.position.VBO) {
2466 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
2467 checkGLcall("glBindBufferARB");
2468 curVBO = sd->u.s.position.VBO;
2471 /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
2472 handling for rhw mode should not impact screen position whereas in GL it does.
2473 This may result in very slightly distored textures in rhw mode, but
2474 a very minimal different. There's always the other option of
2475 fixing the view matrix to prevent w from having any effect
2477 This only applies to user pointer sources, in VBOs the vertices are fixed up
2479 if(sd->u.s.position.VBO == 0) {
2480 glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
2481 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2482 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2483 } else {
2484 glVertexPointer(
2485 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
2486 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2487 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2489 checkGLcall("glVertexPointer(...)");
2490 glEnableClientState(GL_VERTEX_ARRAY);
2491 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
2493 } else {
2494 glDisableClientState(GL_VERTEX_ARRAY);
2495 checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
2498 /* Normals -------------------------------------------------*/
2499 if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
2500 /* Note dwType == float3 or float4 == 2 or 3 */
2501 VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
2502 sd->u.s.normal.dwStride,
2503 sd->u.s.normal.lpData));
2504 if(curVBO != sd->u.s.normal.VBO) {
2505 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
2506 checkGLcall("glBindBufferARB");
2507 curVBO = sd->u.s.normal.VBO;
2509 glNormalPointer(
2510 WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
2511 sd->u.s.normal.dwStride,
2512 sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
2513 checkGLcall("glNormalPointer(...)");
2514 glEnableClientState(GL_NORMAL_ARRAY);
2515 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
2517 } else {
2518 glDisableClientState(GL_NORMAL_ARRAY);
2519 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
2520 glNormal3f(0, 0, 1);
2521 checkGLcall("glNormal3f(0, 0, 1)");
2524 /* Diffuse Colour --------------------------------------------*/
2525 /* WARNING: Data here MUST be in RGBA format, so cannot */
2526 /* go directly into fast mode from app pgm, because */
2527 /* directx requires data in BGRA format. */
2528 /* currently fixupVertices swizels the format, but this isn't */
2529 /* very practical when using VBOS */
2530 /* NOTE: Unless we write a vertex shader to swizel the colour */
2531 /* , or the user doesn't care and wants the speed advantage */
2533 if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
2534 /* Note dwType == float3 or float4 == 2 or 3 */
2535 VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2536 sd->u.s.diffuse.dwStride,
2537 sd->u.s.diffuse.lpData));
2539 if(curVBO != sd->u.s.diffuse.VBO) {
2540 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
2541 checkGLcall("glBindBufferARB");
2542 curVBO = sd->u.s.diffuse.VBO;
2544 glColorPointer(4, GL_UNSIGNED_BYTE,
2545 sd->u.s.diffuse.dwStride,
2546 sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
2547 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
2548 glEnableClientState(GL_COLOR_ARRAY);
2549 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
2551 } else {
2552 glDisableClientState(GL_COLOR_ARRAY);
2553 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
2554 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2555 checkGLcall("glColor4f(1, 1, 1, 1)");
2558 /* Specular Colour ------------------------------------------*/
2559 if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
2560 TRACE("setting specular colour\n");
2561 /* Note dwType == float3 or float4 == 2 or 3 */
2562 VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2563 sd->u.s.specular.dwStride,
2564 sd->u.s.specular.lpData));
2565 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2566 if(curVBO != sd->u.s.specular.VBO) {
2567 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
2568 checkGLcall("glBindBufferARB");
2569 curVBO = sd->u.s.specular.VBO;
2571 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
2572 sd->u.s.specular.dwStride,
2573 sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
2574 vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
2575 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2576 vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2577 } else {
2579 /* Missing specular color is not critical, no warnings */
2580 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2583 } else {
2584 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2586 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2587 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2588 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
2589 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
2590 } else {
2592 /* Missing specular color is not critical, no warnings */
2593 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2597 /* Texture coords -------------------------------------------*/
2599 for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
2600 /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
2601 /* Abort if we don't support the extension. */
2602 if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
2603 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2604 continue;
2607 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) {
2608 /* Select the correct texture stage */
2609 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2612 if (stateblock->textures[textureNo] != NULL) {
2613 int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
2615 if (coordIdx >= MAX_TEXTURES) {
2616 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
2617 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2618 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2620 } else if (sd->u.s.texCoords[coordIdx].lpData == NULL && sd->u.s.texCoords[coordIdx].VBO == 0) {
2621 VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
2622 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2623 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2625 } else {
2626 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
2627 textureNo, texture_idx, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
2628 if(curVBO != sd->u.s.texCoords[coordIdx].VBO) {
2629 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
2630 checkGLcall("glBindBufferARB");
2631 curVBO = sd->u.s.texCoords[coordIdx].VBO;
2633 /* The coords to supply depend completely on the fvf / vertex shader */
2634 glTexCoordPointer(
2635 WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
2636 WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
2637 sd->u.s.texCoords[coordIdx].dwStride,
2638 sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
2639 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2641 } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2642 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2643 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2645 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) ++texture_idx;
2647 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2648 for (textureNo = texture_idx; textureNo < GL_LIMITS(textures); ++textureNo) {
2649 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
2650 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2651 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2656 inline void drawPrimitiveTraceDataLocations(
2657 WineDirect3DVertexStridedData *dataLocations) {
2659 /* Dump out what parts we have supplied */
2660 TRACE("Strided Data:\n");
2661 TRACE_STRIDED((dataLocations), position);
2662 TRACE_STRIDED((dataLocations), blendWeights);
2663 TRACE_STRIDED((dataLocations), blendMatrixIndices);
2664 TRACE_STRIDED((dataLocations), normal);
2665 TRACE_STRIDED((dataLocations), pSize);
2666 TRACE_STRIDED((dataLocations), diffuse);
2667 TRACE_STRIDED((dataLocations), specular);
2668 TRACE_STRIDED((dataLocations), texCoords[0]);
2669 TRACE_STRIDED((dataLocations), texCoords[1]);
2670 TRACE_STRIDED((dataLocations), texCoords[2]);
2671 TRACE_STRIDED((dataLocations), texCoords[3]);
2672 TRACE_STRIDED((dataLocations), texCoords[4]);
2673 TRACE_STRIDED((dataLocations), texCoords[5]);
2674 TRACE_STRIDED((dataLocations), texCoords[6]);
2675 TRACE_STRIDED((dataLocations), texCoords[7]);
2676 TRACE_STRIDED((dataLocations), position2);
2677 TRACE_STRIDED((dataLocations), normal2);
2678 TRACE_STRIDED((dataLocations), tangent);
2679 TRACE_STRIDED((dataLocations), binormal);
2680 TRACE_STRIDED((dataLocations), tessFactor);
2681 TRACE_STRIDED((dataLocations), fog);
2682 TRACE_STRIDED((dataLocations), depth);
2683 TRACE_STRIDED((dataLocations), sample);
2685 return;
2688 /* Helper for vertexdeclaration() */
2689 static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction, WineD3DContext *context) {
2690 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2691 BOOL fixup = FALSE;
2692 WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
2694 if(device->up_strided) {
2695 /* Note: this is a ddraw fixed-function code path */
2696 TRACE("================ Strided Input ===================\n");
2697 memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
2699 if(TRACE_ON(d3d)) {
2700 drawPrimitiveTraceDataLocations(dataLocations);
2702 } else if (stateblock->vertexDecl || stateblock->vertexShader) {
2703 /* Note: This is a fixed function or shader codepath.
2704 * This means it must handle both types of strided data.
2705 * Shaders must go through here to zero the strided data, even if they
2706 * don't set any declaration at all
2708 TRACE("================ Vertex Declaration ===================\n");
2709 memset(dataLocations, 0, sizeof(*dataLocations));
2711 if (stateblock->vertexDecl) {
2712 primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
2713 dataLocations, &fixup);
2715 } else {
2716 /* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
2717 * It is reachable through d3d8, but only for fixed-function.
2718 * It will not work properly for shaders.
2720 TRACE("================ FVF ===================\n");
2721 memset(dataLocations, 0, sizeof(*dataLocations));
2722 primitiveConvertToStridedData((IWineD3DDevice *) device, dataLocations, &fixup);
2723 if(TRACE_ON(d3d)) {
2724 drawPrimitiveTraceDataLocations(dataLocations);
2728 /* Unload the old arrays before loading the new ones to get old junk out */
2729 if(context->numberedArraysLoaded) {
2730 unloadNumberedArrays(stateblock);
2731 context->numberedArraysLoaded = FALSE;
2733 if(context->namedArraysLoaded) {
2734 unloadVertexData(stateblock);
2735 context->namedArraysLoaded = FALSE;
2738 if(useVertexShaderFunction) {
2739 TRACE("Loading numbered arrays\n");
2740 loadNumberedArrays(stateblock, dataLocations);
2741 device->useDrawStridedSlow = FALSE;
2742 context->numberedArraysLoaded = TRUE;
2743 } else if (fixup ||
2744 (dataLocations->u.s.pSize.lpData == NULL &&
2745 dataLocations->u.s.diffuse.lpData == NULL &&
2746 dataLocations->u.s.specular.lpData == NULL)) {
2747 /* Load the vertex data using named arrays */
2748 TRACE("Loading vertex data\n");
2749 loadVertexData(stateblock, dataLocations);
2750 device->useDrawStridedSlow = FALSE;
2751 context->namedArraysLoaded = TRUE;
2752 } else {
2753 TRACE("Not loading vertex data\n");
2754 device->useDrawStridedSlow = TRUE;
2757 /* Generate some fixme's if unsupported functionality is being used */
2758 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
2759 /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
2760 if (!useVertexShaderFunction && (BUFFER_OR_DATA(blendMatrixIndices) || BUFFER_OR_DATA(blendWeights))) {
2761 FIXME("Blending data is only valid with vertex shaders %p %p\n",dataLocations->u.s.blendWeights.lpData,dataLocations->u.s.blendWeights.lpData);
2763 if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
2764 FIXME("Tweening is only valid with vertex shaders\n");
2766 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
2767 FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
2769 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
2770 FIXME("Extended attributes are only valid with vertex shaders\n");
2772 #undef BUFFER_OR_DATA
2775 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2776 BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
2777 BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
2778 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
2779 BOOL transformed;
2780 /* Some stuff is in the device until we have per context tracking */
2781 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2782 BOOL wasrhw = context->last_was_rhw;
2784 /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
2785 * here simply check whether a shader was set, or the user disabled shaders
2787 if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
2788 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
2789 useVertexShaderFunction = TRUE;
2791 if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog != context->last_was_foggy_shader) {
2792 updateFog = TRUE;
2794 } else if(context->last_was_foggy_shader) {
2795 updateFog = TRUE;
2798 handleStreams(stateblock, useVertexShaderFunction, context);
2800 /* Do I have to use ? TRUE : FALSE ? Or can I rely on 15==15 being equal to TRUE(=1)? */
2801 transformed = ((device->strided_streams.u.s.position.lpData != NULL ||
2802 device->strided_streams.u.s.position.VBO != 0) &&
2803 device->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
2805 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
2806 updateFog = TRUE;
2809 /* Reapply lighting if it is not sheduled for reapplication already */
2810 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
2811 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
2814 if (!useVertexShaderFunction && transformed) {
2815 context->last_was_rhw = TRUE;
2816 } else {
2818 /* Untransformed, so relies on the view and projection matrices */
2819 context->last_was_rhw = FALSE;
2820 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
2821 device->untransformed = TRUE;
2823 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
2824 * Not needed as long as only hw shaders are supported
2827 /* This sets the shader output position correction constants.
2828 * TODO: Move to the viewport state
2830 if (useVertexShaderFunction) {
2831 device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
2835 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
2836 * off this function will be called again anyway to make sure they're properly set
2838 if(!useVertexShaderFunction) {
2839 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
2840 * or transformed / untransformed was switched
2842 if(wasrhw != context->last_was_rhw &&
2843 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
2844 !isStateDirty(context, STATE_VIEWPORT)) {
2845 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
2847 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
2848 * mode.
2850 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
2851 * this check will fail and the matrix not applied again. This is OK because a simple
2852 * world matrix change reapplies the matrix - These checks here are only to satisfy the
2853 * needs of the vertex declaration.
2855 * World and view matrix go into the same gl matrix, so only apply them when neither is
2856 * dirty
2858 if(transformed != wasrhw &&
2859 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
2860 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2861 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2864 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
2865 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
2867 } else {
2868 /* We compile the shader here because we need the vertex declaration
2869 * in order to determine if we need to do any swizzling for D3DCOLOR
2870 * registers. If the shader is already compiled this call will do nothing. */
2871 IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
2874 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
2875 * application
2877 if (!isStateDirty(context, STATE_PIXELSHADER)) {
2878 device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
2880 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
2881 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
2885 context->last_was_vshader = useVertexShaderFunction;
2887 if(updateFog) {
2888 state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
2892 static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2893 glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
2894 checkGLcall("glDepthRange");
2895 /* Note: GL requires lower left, DirectX supplies upper left */
2896 /* TODO: replace usage of renderTarget with context management */
2897 glViewport(stateblock->viewport.X,
2898 (((IWineD3DSurfaceImpl *)stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height - (stateblock->viewport.Y + stateblock->viewport.Height)),
2899 stateblock->viewport.Width, stateblock->viewport.Height);
2901 checkGLcall("glViewport");
2903 stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
2904 stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
2905 if(!isStateDirty(context, STATE_TRANSFORM(D3DTS_PROJECTION))) {
2906 transform_projection(STATE_TRANSFORM(D3DTS_PROJECTION), stateblock, context);
2911 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2912 UINT Index = state - STATE_ACTIVELIGHT(0);
2913 PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
2915 if(!lightInfo) {
2916 glDisable(GL_LIGHT0 + Index);
2917 checkGLcall("glDisable(GL_LIGHT0 + Index)");
2918 } else {
2919 float quad_att;
2920 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
2922 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2923 glMatrixMode(GL_MODELVIEW);
2924 glPushMatrix();
2925 glLoadMatrixf((float *)&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2927 /* Diffuse: */
2928 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
2929 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
2930 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
2931 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
2932 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
2933 checkGLcall("glLightfv");
2935 /* Specular */
2936 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
2937 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
2938 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
2939 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
2940 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
2941 checkGLcall("glLightfv");
2943 /* Ambient */
2944 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
2945 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
2946 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
2947 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
2948 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
2949 checkGLcall("glLightfv");
2951 /* Attenuation - Are these right? guessing... */
2952 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
2953 checkGLcall("glLightf");
2954 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
2955 checkGLcall("glLightf");
2957 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
2958 quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
2959 } else {
2960 quad_att = 0; /* 0 or MAX? (0 seems to be ok) */
2963 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
2964 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
2965 checkGLcall("glLightf");
2967 switch (lightInfo->OriginalParms.Type) {
2968 case WINED3DLIGHT_POINT:
2969 /* Position */
2970 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
2971 checkGLcall("glLightfv");
2972 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
2973 checkGLcall("glLightf");
2974 /* FIXME: Range */
2975 break;
2977 case WINED3DLIGHT_SPOT:
2978 /* Position */
2979 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
2980 checkGLcall("glLightfv");
2981 /* Direction */
2982 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
2983 checkGLcall("glLightfv");
2984 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
2985 checkGLcall("glLightf");
2986 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
2987 checkGLcall("glLightf");
2988 /* FIXME: Range */
2989 break;
2991 case WINED3DLIGHT_DIRECTIONAL:
2992 /* Direction */
2993 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
2994 checkGLcall("glLightfv");
2995 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
2996 checkGLcall("glLightf");
2997 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
2998 checkGLcall("glLightf");
2999 break;
3001 default:
3002 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
3005 /* Restore the modelview matrix */
3006 glPopMatrix();
3008 glEnable(GL_LIGHT0 + Index);
3009 checkGLcall("glEnable(GL_LIGHT0 + Index)");
3012 return;
3015 const struct StateEntry StateTable[] =
3017 /* State name representative, apply function */
3018 { /* 0, Undefined */ 0, state_undefined },
3019 { /* 1, WINED3DRS_TEXTUREHANDLE */ 0 /* Handled in ddraw */, state_undefined },
3020 { /* 2, WINED3DRS_ANTIALIAS */ STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias },
3021 { /* 3, WINED3DRS_TEXTUREADDRESS */ 0 /* Handled in ddraw */, state_undefined },
3022 { /* 4, WINED3DRS_TEXTUREPERSPECTIVE */ STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective },
3023 { /* 5, WINED3DRS_WRAPU */ STATE_RENDER(WINED3DRS_WRAPU), state_wrapu },
3024 { /* 6, WINED3DRS_WRAPV */ STATE_RENDER(WINED3DRS_WRAPV), state_wrapv },
3025 { /* 7, WINED3DRS_ZENABLE */ STATE_RENDER(WINED3DRS_ZENABLE), state_zenable },
3026 { /* 8, WINED3DRS_FILLMODE */ STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode },
3027 { /* 9, WINED3DRS_SHADEMODE */ STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode },
3028 { /* 10, WINED3DRS_LINEPATTERN */ STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern },
3029 { /* 11, WINED3DRS_MONOENABLE */ STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable },
3030 { /* 12, WINED3DRS_ROP2 */ STATE_RENDER(WINED3DRS_ROP2), state_rop2 },
3031 { /* 13, WINED3DRS_PLANEMASK */ STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask },
3032 { /* 14, WINED3DRS_ZWRITEENABLE */ STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable },
3033 { /* 15, WINED3DRS_ALPHATESTENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3034 { /* 16, WINED3DRS_LASTPIXEL */ STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel },
3035 { /* 17, WINED3DRS_TEXTUREMAG */ 0 /* Handled in ddraw */, state_undefined },
3036 { /* 18, WINED3DRS_TEXTUREMIN */ 0 /* Handled in ddraw */, state_undefined },
3037 { /* 19, WINED3DRS_SRCBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3038 { /* 20, WINED3DRS_DESTBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3039 { /* 21, WINED3DRS_TEXTUREMAPBLEND */ 0 /* Handled in ddraw */, state_undefined },
3040 { /* 22, WINED3DRS_CULLMODE */ STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode },
3041 { /* 23, WINED3DRS_ZFUNC */ STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc },
3042 { /* 24, WINED3DRS_ALPHAREF */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3043 { /* 25, WINED3DRS_ALPHAFUNC */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3044 { /* 26, WINED3DRS_DITHERENABLE */ STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable },
3045 { /* 27, WINED3DRS_ALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3046 { /* 28, WINED3DRS_FOGENABLE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3047 { /* 29, WINED3DRS_SPECULARENABLE */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},
3048 { /* 30, WINED3DRS_ZVISIBLE */ 0 /* Not supported according to the msdn */, state_nogl },
3049 { /* 31, WINED3DRS_SUBPIXEL */ STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel },
3050 { /* 32, WINED3DRS_SUBPIXELX */ STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx },
3051 { /* 33, WINED3DRS_STIPPLEDALPHA */ STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha },
3052 { /* 34, WINED3DRS_FOGCOLOR */ STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor },
3053 { /* 35, WINED3DRS_FOGTABLEMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3054 { /* 36, WINED3DRS_FOGSTART */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3055 { /* 37, WINED3DRS_FOGEND */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3056 { /* 38, WINED3DRS_FOGDENSITY */ STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity },
3057 { /* 39, WINED3DRS_STIPPLEENABLE */ STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable },
3058 { /* 40, WINED3DRS_EDGEANTIALIAS */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3059 { /* 41, WINED3DRS_COLORKEYENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3060 { /* 42, undefined */ 0, state_undefined },
3061 { /* 43, WINED3DRS_BORDERCOLOR */ STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor },
3062 { /* 44, WINED3DRS_TEXTUREADDRESSU */ 0, /* Handled in ddraw */ state_undefined },
3063 { /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined },
3064 { /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias },
3065 { /* 47, WINED3DRS_ZBIAS */ STATE_RENDER(WINED3DRS_ZBIAS), state_zbias },
3066 { /* 48, WINED3DRS_RANGEFOGENABLE */ 0, state_nogl },
3067 { /* 49, WINED3DRS_ANISOTROPY */ STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy },
3068 { /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch },
3069 { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT */ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
3070 { /* 52, WINED3DRS_STENCILENABLE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3071 { /* 53, WINED3DRS_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3072 { /* 54, WINED3DRS_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3073 { /* 55, WINED3DRS_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3074 { /* 56, WINED3DRS_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3075 { /* 57, WINED3DRS_STENCILREF */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3076 { /* 58, WINED3DRS_STENCILMASK */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3077 { /* 59, WINED3DRS_STENCILWRITEMASK */ STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite },
3078 { /* 60, WINED3DRS_TEXTUREFACTOR */ STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor },
3079 { /* 61, Undefined */ 0, state_undefined },
3080 { /* 62, Undefined */ 0, state_undefined },
3081 { /* 63, Undefined */ 0, state_undefined },
3082 { /* 64, WINED3DRS_STIPPLEPATTERN00 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3083 { /* 65, WINED3DRS_STIPPLEPATTERN01 */ 0 /* Obsolete, should he handled by ddraw */, state_undefined },
3084 { /* 66, WINED3DRS_STIPPLEPATTERN02 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3085 { /* 67, WINED3DRS_STIPPLEPATTERN03 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3086 { /* 68, WINED3DRS_STIPPLEPATTERN04 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3087 { /* 69, WINED3DRS_STIPPLEPATTERN05 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3088 { /* 70, WINED3DRS_STIPPLEPATTERN06 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3089 { /* 71, WINED3DRS_STIPPLEPATTERN07 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3090 { /* 72, WINED3DRS_STIPPLEPATTERN08 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3091 { /* 73, WINED3DRS_STIPPLEPATTERN09 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3092 { /* 74, WINED3DRS_STIPPLEPATTERN10 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3093 { /* 75, WINED3DRS_STIPPLEPATTERN11 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3094 { /* 76, WINED3DRS_STIPPLEPATTERN12 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3095 { /* 77, WINED3DRS_STIPPLEPATTERN13 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3096 { /* 78, WINED3DRS_STIPPLEPATTERN14 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3097 { /* 79, WINED3DRS_STIPPLEPATTERN15 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3098 { /* 80, WINED3DRS_STIPPLEPATTERN16 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3099 { /* 81, WINED3DRS_STIPPLEPATTERN17 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3100 { /* 82, WINED3DRS_STIPPLEPATTERN18 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3101 { /* 83, WINED3DRS_STIPPLEPATTERN19 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3102 { /* 84, WINED3DRS_STIPPLEPATTERN20 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3103 { /* 85, WINED3DRS_STIPPLEPATTERN21 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3104 { /* 86, WINED3DRS_STIPPLEPATTERN22 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3105 { /* 87, WINED3DRS_STIPPLEPATTERN23 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3106 { /* 88, WINED3DRS_STIPPLEPATTERN24 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3107 { /* 89, WINED3DRS_STIPPLEPATTERN25 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3108 { /* 90, WINED3DRS_STIPPLEPATTERN26 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3109 { /* 91, WINED3DRS_STIPPLEPATTERN27 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3110 { /* 92, WINED3DRS_STIPPLEPATTERN28 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3111 { /* 93, WINED3DRS_STIPPLEPATTERN29 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3112 { /* 94, WINED3DRS_STIPPLEPATTERN30 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3113 { /* 95, WINED3DRS_STIPPLEPATTERN31 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3114 { /* 96, Undefined */ 0, state_undefined },
3115 { /* 97, Undefined */ 0, state_undefined },
3116 { /* 98, Undefined */ 0, state_undefined },
3117 { /* 99, Undefined */ 0, state_undefined },
3118 { /*100, Undefined */ 0, state_undefined },
3119 { /*101, Undefined */ 0, state_undefined },
3120 { /*102, Undefined */ 0, state_undefined },
3121 { /*103, Undefined */ 0, state_undefined },
3122 { /*104, Undefined */ 0, state_undefined },
3123 { /*105, Undefined */ 0, state_undefined },
3124 { /*106, Undefined */ 0, state_undefined },
3125 { /*107, Undefined */ 0, state_undefined },
3126 { /*108, Undefined */ 0, state_undefined },
3127 { /*109, Undefined */ 0, state_undefined },
3128 { /*110, Undefined */ 0, state_undefined },
3129 { /*111, Undefined */ 0, state_undefined },
3130 { /*112, Undefined */ 0, state_undefined },
3131 { /*113, Undefined */ 0, state_undefined },
3132 { /*114, Undefined */ 0, state_undefined },
3133 { /*115, Undefined */ 0, state_undefined },
3134 { /*116, Undefined */ 0, state_undefined },
3135 { /*117, Undefined */ 0, state_undefined },
3136 { /*118, Undefined */ 0, state_undefined },
3137 { /*119, Undefined */ 0, state_undefined },
3138 { /*120, Undefined */ 0, state_undefined },
3139 { /*121, Undefined */ 0, state_undefined },
3140 { /*122, Undefined */ 0, state_undefined },
3141 { /*123, Undefined */ 0, state_undefined },
3142 { /*124, Undefined */ 0, state_undefined },
3143 { /*125, Undefined */ 0, state_undefined },
3144 { /*126, Undefined */ 0, state_undefined },
3145 { /*127, Undefined */ 0, state_undefined },
3146 /* Big hole ends */
3147 { /*128, WINED3DRS_WRAP0 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3148 { /*129, WINED3DRS_WRAP1 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3149 { /*130, WINED3DRS_WRAP2 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3150 { /*131, WINED3DRS_WRAP3 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3151 { /*132, WINED3DRS_WRAP4 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3152 { /*133, WINED3DRS_WRAP5 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3153 { /*134, WINED3DRS_WRAP6 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3154 { /*135, WINED3DRS_WRAP7 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3155 { /*136, WINED3DRS_CLIPPING */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3156 { /*137, WINED3DRS_LIGHTING */ STATE_RENDER(WINED3DRS_LIGHTING), state_lighting },
3157 { /*138, WINED3DRS_EXTENTS */ STATE_RENDER(WINED3DRS_EXTENTS), state_extents },
3158 { /*139, WINED3DRS_AMBIENT */ STATE_RENDER(WINED3DRS_AMBIENT), state_ambient },
3159 { /*140, WINED3DRS_FOGVERTEXMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3160 { /*141, WINED3DRS_COLORVERTEX */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3161 { /*142, WINED3DRS_LOCALVIEWER */ STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer },
3162 { /*143, WINED3DRS_NORMALIZENORMALS */ STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize },
3163 { /*144, WINED3DRS_COLORKEYBLENDENABLE */ STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend },
3164 { /*145, WINED3DRS_DIFFUSEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3165 { /*146, WINED3DRS_SPECULARMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3166 { /*147, WINED3DRS_AMBIENTMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3167 { /*148, WINED3DRS_EMISSIVEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3168 { /*149, Undefined */ 0, state_undefined },
3169 { /*150, Undefined */ 0, state_undefined },
3170 { /*151, WINED3DRS_VERTEXBLEND */ 0, state_nogl },
3171 { /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3172 { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING */ 0, state_nogl },
3173 { /*154, WINED3DRS_POINTSIZE */ STATE_RENDER(WINED3DRS_POINTSIZE), state_psize },
3174 { /*155, WINED3DRS_POINTSIZE_MIN */ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin },
3175 { /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite },
3176 { /*157, WINED3DRS_POINTSCALEENABLE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3177 { /*158, WINED3DRS_POINTSCALE_A */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3178 { /*159, WINED3DRS_POINTSCALE_B */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3179 { /*160, WINED3DRS_POINTSCALE_C */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3180 { /*161, WINED3DRS_MULTISAMPLEANTIALIAS */ STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_multisampleaa },
3181 { /*162, WINED3DRS_MULTISAMPLEMASK */ STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask },
3182 { /*163, WINED3DRS_PATCHEDGESTYLE */ STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle},
3183 { /*164, WINED3DRS_PATCHSEGMENTS */ STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments },
3184 { /*165, WINED3DRS_DEBUGMONITORTOKEN */ STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_nogl },
3185 { /*166, WINED3DRS_POINTSIZE_MAX */ STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax },
3186 { /*167, WINED3DRS_INDEXEDVERTEXBLENDENABLE */ 0, state_nogl },
3187 { /*168, WINED3DRS_COLORWRITEENABLE */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3188 { /*169, Undefined */ 0, state_undefined },
3189 { /*170, WINED3DRS_TWEENFACTOR */ 0, state_nogl },
3190 { /*171, WINED3DRS_BLENDOP */ STATE_RENDER(WINED3DRS_BLENDOP), state_blendop },
3191 { /*172, WINED3DRS_POSITIONDEGREE */ STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree},
3192 { /*173, WINED3DRS_NORMALDEGREE */ STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree },
3193 /*172, WINED3DRS_POSITIONORDER */ /* Value assigned to 2 state names */
3194 /*173, WINED3DRS_NORMALORDER */ /* Value assigned to 2 state names */
3195 { /*174, WINED3DRS_SCISSORTESTENABLE */ STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor },
3196 { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3197 { /*176, WINED3DRS_ANTIALIASEDLINEENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3198 { /*177, undefined */ 0, state_undefined },
3199 { /*178, WINED3DRS_MINTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3200 { /*179, WINED3DRS_MAXTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3201 { /*180, WINED3DRS_ADAPTIVETESS_X */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3202 { /*181, WINED3DRS_ADAPTIVETESS_Y */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3203 { /*182, WINED3DRS_ADAPTIVETESS_Z */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3204 { /*183, WINED3DRS_ADAPTIVETESS_W */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3205 { /*184, WINED3DRS_ENABLEADAPTIVETESSELLATION */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3206 { /*185, WINED3DRS_TWOSIDEDSTENCILMODE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3207 { /*186, WINED3DRS_CCW_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3208 { /*187, WINED3DRS_CCW_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3209 { /*188, WINED3DRS_CCW_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3210 { /*189, WINED3DRS_CCW_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3211 { /*190, WINED3DRS_COLORWRITEENABLE1 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3212 { /*191, WINED3DRS_COLORWRITEENABLE2 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3213 { /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3214 { /*193, WINED3DRS_BLENDFACTOR */ STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor },
3215 { /*194, WINED3DRS_SRGBWRITEENABLE */ STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), state_srgbwrite },
3216 { /*195, WINED3DRS_DEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3217 { /*196, undefined */ 0, state_undefined },
3218 { /*197, undefined */ 0, state_undefined },
3219 { /*198, WINED3DRS_WRAP8 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3220 { /*199, WINED3DRS_WRAP9 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3221 { /*200, WINED3DRS_WRAP10 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3222 { /*201, WINED3DRS_WRAP11 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3223 { /*202, WINED3DRS_WRAP12 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3224 { /*203, WINED3DRS_WRAP13 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3225 { /*204, WINED3DRS_WRAP14 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3226 { /*205, WINED3DRS_WRAP15 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3227 { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3228 { /*207, WINED3DRS_SRCBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3229 { /*208, WINED3DRS_DESTBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3230 { /*209, WINED3DRS_BLENDOPALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3231 /* Texture stage states */
3232 { /*0, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3233 { /*0, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3234 { /*0, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3235 { /*0, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3236 { /*0, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3237 { /*0, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3238 { /*0, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3239 { /*0, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3240 { /*0, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3241 { /*0, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3242 { /*0, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3243 { /*0, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3244 { /*0, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3245 { /*0, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3246 { /*0, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3247 { /*0, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3248 { /*0, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3249 { /*0, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3250 { /*0, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3251 { /*0, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3252 { /*0, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3253 { /*0, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3254 { /*0, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3255 { /*0, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3256 { /*0, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3257 { /*0, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3258 { /*0, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3259 { /*0, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), tex_resultarg },
3260 { /*0, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3261 { /*0, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3262 { /*0, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3263 { /*0, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3265 { /*1, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3266 { /*1, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3267 { /*1, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3268 { /*1, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3269 { /*1, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3270 { /*1, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3271 { /*1, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3272 { /*1, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3273 { /*1, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3274 { /*1, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3275 { /*1, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3276 { /*1, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3277 { /*1, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3278 { /*1, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3279 { /*1, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3280 { /*1, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3281 { /*1, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3282 { /*1, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3283 { /*1, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3284 { /*1, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3285 { /*1, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3286 { /*1, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3287 { /*1, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3288 { /*1, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3289 { /*1, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3290 { /*1, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3291 { /*1, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3292 { /*1, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), tex_resultarg },
3293 { /*1, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3294 { /*1, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3295 { /*1, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3296 { /*1, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3298 { /*2, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3299 { /*2, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3300 { /*2, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3301 { /*2, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3302 { /*2, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3303 { /*2, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3304 { /*2, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3305 { /*2, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3306 { /*2, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3307 { /*2, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3308 { /*2, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3309 { /*2, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3310 { /*2, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3311 { /*2, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3312 { /*2, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3313 { /*2, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3314 { /*2, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3315 { /*2, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3316 { /*2, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3317 { /*2, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3318 { /*2, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3319 { /*2, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3320 { /*2, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3321 { /*2, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3322 { /*2, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3323 { /*2, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3324 { /*2, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3325 { /*2, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), tex_resultarg },
3326 { /*2, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3327 { /*2, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3328 { /*2, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3329 { /*2, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3331 { /*3, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3332 { /*3, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3333 { /*3, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3334 { /*3, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3335 { /*3, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3336 { /*3, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3337 { /*3, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3338 { /*3, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3339 { /*3, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3340 { /*3, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3341 { /*3, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3342 { /*3, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3343 { /*3, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3344 { /*3, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3345 { /*3, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3346 { /*3, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3347 { /*3, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3348 { /*3, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3349 { /*3, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3350 { /*3, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3351 { /*3, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3352 { /*3, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3353 { /*3, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3354 { /*3, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3355 { /*3, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3356 { /*3, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3357 { /*3, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3358 { /*3, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), tex_resultarg },
3359 { /*3, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3360 { /*3, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3361 { /*3, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3362 { /*3, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3364 { /*4, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3365 { /*4, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3366 { /*4, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3367 { /*4, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3368 { /*4, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3369 { /*4, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3370 { /*4, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3371 { /*4, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3372 { /*4, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3373 { /*4, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3374 { /*4, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3375 { /*4, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3376 { /*4, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3377 { /*4, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3378 { /*4, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3379 { /*4, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3380 { /*4, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3381 { /*4, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3382 { /*4, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3383 { /*4, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3384 { /*4, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3385 { /*4, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3386 { /*4, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3387 { /*4, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3388 { /*4, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3389 { /*4, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3390 { /*4, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3391 { /*4, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), tex_resultarg },
3392 { /*4, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3393 { /*4, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3394 { /*4, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3395 { /*4, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3397 { /*5, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3398 { /*5, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3399 { /*5, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3400 { /*5, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3401 { /*5, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3402 { /*5, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3403 { /*5, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3404 { /*5, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3405 { /*5, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3406 { /*5, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3407 { /*5, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3408 { /*5, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3409 { /*5, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3410 { /*5, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3411 { /*5, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3412 { /*5, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3413 { /*5, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3414 { /*5, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3415 { /*5, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3416 { /*5, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3417 { /*5, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3418 { /*5, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3419 { /*5, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3420 { /*5, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3421 { /*5, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3422 { /*5, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3423 { /*5, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3424 { /*5, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), tex_resultarg },
3425 { /*5, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3426 { /*5, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3427 { /*5, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3428 { /*5, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3430 { /*6, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3431 { /*6, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3432 { /*6, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3433 { /*6, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3434 { /*6, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3435 { /*6, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3436 { /*6, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3437 { /*6, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3438 { /*6, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3439 { /*6, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3440 { /*6, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3441 { /*6, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3442 { /*6, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3443 { /*6, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3444 { /*6, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3445 { /*6, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3446 { /*6, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3447 { /*6, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3448 { /*6, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3449 { /*6, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3450 { /*6, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3451 { /*6, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3452 { /*6, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3453 { /*6, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3454 { /*6, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3455 { /*6, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3456 { /*6, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3457 { /*6, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), tex_resultarg },
3458 { /*6, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3459 { /*6, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3460 { /*6, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3461 { /*6, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3463 { /*7, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3464 { /*7, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3465 { /*7, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3466 { /*7, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3467 { /*7, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3468 { /*7, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3469 { /*7, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3470 { /*7, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3471 { /*7, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3472 { /*7, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3473 { /*7, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3474 { /*7, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3475 { /*7, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3476 { /*7, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3477 { /*7, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3478 { /*7, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3479 { /*7, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3480 { /*7, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3481 { /*7, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3482 { /*7, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3483 { /*7, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3484 { /*7, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3485 { /*7, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3486 { /*7, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3487 { /*7, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3488 { /*7, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3489 { /*7, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3490 { /*7, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), tex_resultarg },
3491 { /*7, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3492 { /*7, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3493 { /*7, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3494 { /*7, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3495 /* Sampler states */
3496 { /* 0, Sampler 0 */ STATE_SAMPLER(0), sampler },
3497 { /* 1, Sampler 1 */ STATE_SAMPLER(1), sampler },
3498 { /* 2, Sampler 2 */ STATE_SAMPLER(2), sampler },
3499 { /* 3, Sampler 3 */ STATE_SAMPLER(3), sampler },
3500 { /* 4, Sampler 3 */ STATE_SAMPLER(4), sampler },
3501 { /* 5, Sampler 5 */ STATE_SAMPLER(5), sampler },
3502 { /* 6, Sampler 6 */ STATE_SAMPLER(6), sampler },
3503 { /* 7, Sampler 7 */ STATE_SAMPLER(7), sampler },
3504 { /* 8, Sampler 8 */ STATE_SAMPLER(8), sampler },
3505 { /* 9, Sampler 9 */ STATE_SAMPLER(9), sampler },
3506 { /*10, Sampler 10 */ STATE_SAMPLER(10), sampler },
3507 { /*11, Sampler 11 */ STATE_SAMPLER(11), sampler },
3508 { /*12, Sampler 12 */ STATE_SAMPLER(12), sampler },
3509 { /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
3510 { /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
3511 { /*15, Sampler 15 */ STATE_SAMPLER(15), sampler },
3512 /* Pixel shader */
3513 { /* , Pixel Shader */ STATE_PIXELSHADER, pixelshader },
3514 /* Transform states follow */
3515 { /* 1, undefined */ 0, state_undefined },
3516 { /* 2, WINED3DTS_VIEW */ STATE_TRANSFORM(WINED3DTS_VIEW), transform_view },
3517 { /* 3, WINED3DTS_PROJECTION */ STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection},
3518 { /* 4, undefined */ 0, state_undefined },
3519 { /* 5, undefined */ 0, state_undefined },
3520 { /* 6, undefined */ 0, state_undefined },
3521 { /* 7, undefined */ 0, state_undefined },
3522 { /* 8, undefined */ 0, state_undefined },
3523 { /* 9, undefined */ 0, state_undefined },
3524 { /* 10, undefined */ 0, state_undefined },
3525 { /* 11, undefined */ 0, state_undefined },
3526 { /* 12, undefined */ 0, state_undefined },
3527 { /* 13, undefined */ 0, state_undefined },
3528 { /* 14, undefined */ 0, state_undefined },
3529 { /* 15, undefined */ 0, state_undefined },
3530 { /* 16, WINED3DTS_TEXTURE0 */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3531 { /* 17, WINED3DTS_TEXTURE1 */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3532 { /* 18, WINED3DTS_TEXTURE2 */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3533 { /* 19, WINED3DTS_TEXTURE3 */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3534 { /* 20, WINED3DTS_TEXTURE4 */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3535 { /* 21, WINED3DTS_TEXTURE5 */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3536 { /* 22, WINED3DTS_TEXTURE6 */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3537 { /* 23, WINED3DTS_TEXTURE7 */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3538 /* A huge gap between TEXTURE7 and WORLDMATRIX(0) :-( But entries are needed to catch then if a broken app sets them */
3539 { /* 24, undefined */ 0, state_undefined },
3540 { /* 25, undefined */ 0, state_undefined },
3541 { /* 26, undefined */ 0, state_undefined },
3542 { /* 27, undefined */ 0, state_undefined },
3543 { /* 28, undefined */ 0, state_undefined },
3544 { /* 29, undefined */ 0, state_undefined },
3545 { /* 30, undefined */ 0, state_undefined },
3546 { /* 31, undefined */ 0, state_undefined },
3547 { /* 32, undefined */ 0, state_undefined },
3548 { /* 33, undefined */ 0, state_undefined },
3549 { /* 34, undefined */ 0, state_undefined },
3550 { /* 35, undefined */ 0, state_undefined },
3551 { /* 36, undefined */ 0, state_undefined },
3552 { /* 37, undefined */ 0, state_undefined },
3553 { /* 38, undefined */ 0, state_undefined },
3554 { /* 39, undefined */ 0, state_undefined },
3555 { /* 40, undefined */ 0, state_undefined },
3556 { /* 41, undefined */ 0, state_undefined },
3557 { /* 42, undefined */ 0, state_undefined },
3558 { /* 43, undefined */ 0, state_undefined },
3559 { /* 44, undefined */ 0, state_undefined },
3560 { /* 45, undefined */ 0, state_undefined },
3561 { /* 46, undefined */ 0, state_undefined },
3562 { /* 47, undefined */ 0, state_undefined },
3563 { /* 48, undefined */ 0, state_undefined },
3564 { /* 49, undefined */ 0, state_undefined },
3565 { /* 50, undefined */ 0, state_undefined },
3566 { /* 51, undefined */ 0, state_undefined },
3567 { /* 52, undefined */ 0, state_undefined },
3568 { /* 53, undefined */ 0, state_undefined },
3569 { /* 54, undefined */ 0, state_undefined },
3570 { /* 55, undefined */ 0, state_undefined },
3571 { /* 56, undefined */ 0, state_undefined },
3572 { /* 57, undefined */ 0, state_undefined },
3573 { /* 58, undefined */ 0, state_undefined },
3574 { /* 59, undefined */ 0, state_undefined },
3575 { /* 60, undefined */ 0, state_undefined },
3576 { /* 61, undefined */ 0, state_undefined },
3577 { /* 62, undefined */ 0, state_undefined },
3578 { /* 63, undefined */ 0, state_undefined },
3579 { /* 64, undefined */ 0, state_undefined },
3580 { /* 65, undefined */ 0, state_undefined },
3581 { /* 66, undefined */ 0, state_undefined },
3582 { /* 67, undefined */ 0, state_undefined },
3583 { /* 68, undefined */ 0, state_undefined },
3584 { /* 69, undefined */ 0, state_undefined },
3585 { /* 70, undefined */ 0, state_undefined },
3586 { /* 71, undefined */ 0, state_undefined },
3587 { /* 72, undefined */ 0, state_undefined },
3588 { /* 73, undefined */ 0, state_undefined },
3589 { /* 74, undefined */ 0, state_undefined },
3590 { /* 75, undefined */ 0, state_undefined },
3591 { /* 76, undefined */ 0, state_undefined },
3592 { /* 77, undefined */ 0, state_undefined },
3593 { /* 78, undefined */ 0, state_undefined },
3594 { /* 79, undefined */ 0, state_undefined },
3595 { /* 80, undefined */ 0, state_undefined },
3596 { /* 81, undefined */ 0, state_undefined },
3597 { /* 82, undefined */ 0, state_undefined },
3598 { /* 83, undefined */ 0, state_undefined },
3599 { /* 84, undefined */ 0, state_undefined },
3600 { /* 85, undefined */ 0, state_undefined },
3601 { /* 86, undefined */ 0, state_undefined },
3602 { /* 87, undefined */ 0, state_undefined },
3603 { /* 88, undefined */ 0, state_undefined },
3604 { /* 89, undefined */ 0, state_undefined },
3605 { /* 90, undefined */ 0, state_undefined },
3606 { /* 91, undefined */ 0, state_undefined },
3607 { /* 92, undefined */ 0, state_undefined },
3608 { /* 93, undefined */ 0, state_undefined },
3609 { /* 94, undefined */ 0, state_undefined },
3610 { /* 95, undefined */ 0, state_undefined },
3611 { /* 96, undefined */ 0, state_undefined },
3612 { /* 97, undefined */ 0, state_undefined },
3613 { /* 98, undefined */ 0, state_undefined },
3614 { /* 99, undefined */ 0, state_undefined },
3615 { /*100, undefined */ 0, state_undefined },
3616 { /*101, undefined */ 0, state_undefined },
3617 { /*102, undefined */ 0, state_undefined },
3618 { /*103, undefined */ 0, state_undefined },
3619 { /*104, undefined */ 0, state_undefined },
3620 { /*105, undefined */ 0, state_undefined },
3621 { /*106, undefined */ 0, state_undefined },
3622 { /*107, undefined */ 0, state_undefined },
3623 { /*108, undefined */ 0, state_undefined },
3624 { /*109, undefined */ 0, state_undefined },
3625 { /*110, undefined */ 0, state_undefined },
3626 { /*111, undefined */ 0, state_undefined },
3627 { /*112, undefined */ 0, state_undefined },
3628 { /*113, undefined */ 0, state_undefined },
3629 { /*114, undefined */ 0, state_undefined },
3630 { /*115, undefined */ 0, state_undefined },
3631 { /*116, undefined */ 0, state_undefined },
3632 { /*117, undefined */ 0, state_undefined },
3633 { /*118, undefined */ 0, state_undefined },
3634 { /*119, undefined */ 0, state_undefined },
3635 { /*120, undefined */ 0, state_undefined },
3636 { /*121, undefined */ 0, state_undefined },
3637 { /*122, undefined */ 0, state_undefined },
3638 { /*123, undefined */ 0, state_undefined },
3639 { /*124, undefined */ 0, state_undefined },
3640 { /*125, undefined */ 0, state_undefined },
3641 { /*126, undefined */ 0, state_undefined },
3642 { /*127, undefined */ 0, state_undefined },
3643 { /*128, undefined */ 0, state_undefined },
3644 { /*129, undefined */ 0, state_undefined },
3645 { /*130, undefined */ 0, state_undefined },
3646 { /*131, undefined */ 0, state_undefined },
3647 { /*132, undefined */ 0, state_undefined },
3648 { /*133, undefined */ 0, state_undefined },
3649 { /*134, undefined */ 0, state_undefined },
3650 { /*135, undefined */ 0, state_undefined },
3651 { /*136, undefined */ 0, state_undefined },
3652 { /*137, undefined */ 0, state_undefined },
3653 { /*138, undefined */ 0, state_undefined },
3654 { /*139, undefined */ 0, state_undefined },
3655 { /*140, undefined */ 0, state_undefined },
3656 { /*141, undefined */ 0, state_undefined },
3657 { /*142, undefined */ 0, state_undefined },
3658 { /*143, undefined */ 0, state_undefined },
3659 { /*144, undefined */ 0, state_undefined },
3660 { /*145, undefined */ 0, state_undefined },
3661 { /*146, undefined */ 0, state_undefined },
3662 { /*147, undefined */ 0, state_undefined },
3663 { /*148, undefined */ 0, state_undefined },
3664 { /*149, undefined */ 0, state_undefined },
3665 { /*150, undefined */ 0, state_undefined },
3666 { /*151, undefined */ 0, state_undefined },
3667 { /*152, undefined */ 0, state_undefined },
3668 { /*153, undefined */ 0, state_undefined },
3669 { /*154, undefined */ 0, state_undefined },
3670 { /*155, undefined */ 0, state_undefined },
3671 { /*156, undefined */ 0, state_undefined },
3672 { /*157, undefined */ 0, state_undefined },
3673 { /*158, undefined */ 0, state_undefined },
3674 { /*159, undefined */ 0, state_undefined },
3675 { /*160, undefined */ 0, state_undefined },
3676 { /*161, undefined */ 0, state_undefined },
3677 { /*162, undefined */ 0, state_undefined },
3678 { /*163, undefined */ 0, state_undefined },
3679 { /*164, undefined */ 0, state_undefined },
3680 { /*165, undefined */ 0, state_undefined },
3681 { /*166, undefined */ 0, state_undefined },
3682 { /*167, undefined */ 0, state_undefined },
3683 { /*168, undefined */ 0, state_undefined },
3684 { /*169, undefined */ 0, state_undefined },
3685 { /*170, undefined */ 0, state_undefined },
3686 { /*171, undefined */ 0, state_undefined },
3687 { /*172, undefined */ 0, state_undefined },
3688 { /*173, undefined */ 0, state_undefined },
3689 { /*174, undefined */ 0, state_undefined },
3690 { /*175, undefined */ 0, state_undefined },
3691 { /*176, undefined */ 0, state_undefined },
3692 { /*177, undefined */ 0, state_undefined },
3693 { /*178, undefined */ 0, state_undefined },
3694 { /*179, undefined */ 0, state_undefined },
3695 { /*180, undefined */ 0, state_undefined },
3696 { /*181, undefined */ 0, state_undefined },
3697 { /*182, undefined */ 0, state_undefined },
3698 { /*183, undefined */ 0, state_undefined },
3699 { /*184, undefined */ 0, state_undefined },
3700 { /*185, undefined */ 0, state_undefined },
3701 { /*186, undefined */ 0, state_undefined },
3702 { /*187, undefined */ 0, state_undefined },
3703 { /*188, undefined */ 0, state_undefined },
3704 { /*189, undefined */ 0, state_undefined },
3705 { /*190, undefined */ 0, state_undefined },
3706 { /*191, undefined */ 0, state_undefined },
3707 { /*192, undefined */ 0, state_undefined },
3708 { /*193, undefined */ 0, state_undefined },
3709 { /*194, undefined */ 0, state_undefined },
3710 { /*195, undefined */ 0, state_undefined },
3711 { /*196, undefined */ 0, state_undefined },
3712 { /*197, undefined */ 0, state_undefined },
3713 { /*198, undefined */ 0, state_undefined },
3714 { /*199, undefined */ 0, state_undefined },
3715 { /*200, undefined */ 0, state_undefined },
3716 { /*201, undefined */ 0, state_undefined },
3717 { /*202, undefined */ 0, state_undefined },
3718 { /*203, undefined */ 0, state_undefined },
3719 { /*204, undefined */ 0, state_undefined },
3720 { /*205, undefined */ 0, state_undefined },
3721 { /*206, undefined */ 0, state_undefined },
3722 { /*207, undefined */ 0, state_undefined },
3723 { /*208, undefined */ 0, state_undefined },
3724 { /*209, undefined */ 0, state_undefined },
3725 { /*210, undefined */ 0, state_undefined },
3726 { /*211, undefined */ 0, state_undefined },
3727 { /*212, undefined */ 0, state_undefined },
3728 { /*213, undefined */ 0, state_undefined },
3729 { /*214, undefined */ 0, state_undefined },
3730 { /*215, undefined */ 0, state_undefined },
3731 { /*216, undefined */ 0, state_undefined },
3732 { /*217, undefined */ 0, state_undefined },
3733 { /*218, undefined */ 0, state_undefined },
3734 { /*219, undefined */ 0, state_undefined },
3735 { /*220, undefined */ 0, state_undefined },
3736 { /*221, undefined */ 0, state_undefined },
3737 { /*222, undefined */ 0, state_undefined },
3738 { /*223, undefined */ 0, state_undefined },
3739 { /*224, undefined */ 0, state_undefined },
3740 { /*225, undefined */ 0, state_undefined },
3741 { /*226, undefined */ 0, state_undefined },
3742 { /*227, undefined */ 0, state_undefined },
3743 { /*228, undefined */ 0, state_undefined },
3744 { /*229, undefined */ 0, state_undefined },
3745 { /*230, undefined */ 0, state_undefined },
3746 { /*231, undefined */ 0, state_undefined },
3747 { /*232, undefined */ 0, state_undefined },
3748 { /*233, undefined */ 0, state_undefined },
3749 { /*234, undefined */ 0, state_undefined },
3750 { /*235, undefined */ 0, state_undefined },
3751 { /*236, undefined */ 0, state_undefined },
3752 { /*237, undefined */ 0, state_undefined },
3753 { /*238, undefined */ 0, state_undefined },
3754 { /*239, undefined */ 0, state_undefined },
3755 { /*240, undefined */ 0, state_undefined },
3756 { /*241, undefined */ 0, state_undefined },
3757 { /*242, undefined */ 0, state_undefined },
3758 { /*243, undefined */ 0, state_undefined },
3759 { /*244, undefined */ 0, state_undefined },
3760 { /*245, undefined */ 0, state_undefined },
3761 { /*246, undefined */ 0, state_undefined },
3762 { /*247, undefined */ 0, state_undefined },
3763 { /*248, undefined */ 0, state_undefined },
3764 { /*249, undefined */ 0, state_undefined },
3765 { /*250, undefined */ 0, state_undefined },
3766 { /*251, undefined */ 0, state_undefined },
3767 { /*252, undefined */ 0, state_undefined },
3768 { /*253, undefined */ 0, state_undefined },
3769 { /*254, undefined */ 0, state_undefined },
3770 { /*255, undefined */ 0, state_undefined },
3771 /* End huge gap */
3772 { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), transform_world },
3773 { /*257, WINED3DTS_WORLDMATRIX(1) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)), transform_worldex },
3774 { /*258, WINED3DTS_WORLDMATRIX(2) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)), transform_worldex },
3775 { /*259, WINED3DTS_WORLDMATRIX(3) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)), transform_worldex },
3776 { /*260, WINED3DTS_WORLDMATRIX(4) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(4)), transform_worldex },
3777 { /*261, WINED3DTS_WORLDMATRIX(5) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(5)), transform_worldex },
3778 { /*262, WINED3DTS_WORLDMATRIX(6) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(6)), transform_worldex },
3779 { /*263, WINED3DTS_WORLDMATRIX(7) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(7)), transform_worldex },
3780 { /*264, WINED3DTS_WORLDMATRIX(8) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(8)), transform_worldex },
3781 { /*265, WINED3DTS_WORLDMATRIX(9) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(9)), transform_worldex },
3782 { /*266, WINED3DTS_WORLDMATRIX(10) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(10)), transform_worldex },
3783 { /*267, WINED3DTS_WORLDMATRIX(11) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(11)), transform_worldex },
3784 { /*268, WINED3DTS_WORLDMATRIX(12) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(12)), transform_worldex },
3785 { /*269, WINED3DTS_WORLDMATRIX(13) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(13)), transform_worldex },
3786 { /*270, WINED3DTS_WORLDMATRIX(14) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(14)), transform_worldex },
3787 { /*271, WINED3DTS_WORLDMATRIX(15) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(15)), transform_worldex },
3788 { /*272, WINED3DTS_WORLDMATRIX(16) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(16)), transform_worldex },
3789 { /*273, WINED3DTS_WORLDMATRIX(17) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(17)), transform_worldex },
3790 { /*274, WINED3DTS_WORLDMATRIX(18) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(18)), transform_worldex },
3791 { /*275, WINED3DTS_WORLDMATRIX(19) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(19)), transform_worldex },
3792 { /*276, WINED3DTS_WORLDMATRIX(20) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(20)), transform_worldex },
3793 { /*277, WINED3DTS_WORLDMATRIX(21) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(21)), transform_worldex },
3794 { /*278, WINED3DTS_WORLDMATRIX(22) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(22)), transform_worldex },
3795 { /*279, WINED3DTS_WORLDMATRIX(23) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(23)), transform_worldex },
3796 { /*280, WINED3DTS_WORLDMATRIX(24) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(24)), transform_worldex },
3797 { /*281, WINED3DTS_WORLDMATRIX(25) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(25)), transform_worldex },
3798 { /*282, WINED3DTS_WORLDMATRIX(26) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(26)), transform_worldex },
3799 { /*283, WINED3DTS_WORLDMATRIX(27) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(27)), transform_worldex },
3800 { /*284, WINED3DTS_WORLDMATRIX(28) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(28)), transform_worldex },
3801 { /*285, WINED3DTS_WORLDMATRIX(29) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(29)), transform_worldex },
3802 { /*286, WINED3DTS_WORLDMATRIX(30) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(30)), transform_worldex },
3803 { /*287, WINED3DTS_WORLDMATRIX(31) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(31)), transform_worldex },
3804 { /*288, WINED3DTS_WORLDMATRIX(32) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(32)), transform_worldex },
3805 { /*289, WINED3DTS_WORLDMATRIX(33) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(33)), transform_worldex },
3806 { /*290, WINED3DTS_WORLDMATRIX(34) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(34)), transform_worldex },
3807 { /*291, WINED3DTS_WORLDMATRIX(35) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(35)), transform_worldex },
3808 { /*292, WINED3DTS_WORLDMATRIX(36) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(36)), transform_worldex },
3809 { /*293, WINED3DTS_WORLDMATRIX(37) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(37)), transform_worldex },
3810 { /*294, WINED3DTS_WORLDMATRIX(38) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(38)), transform_worldex },
3811 { /*295, WINED3DTS_WORLDMATRIX(39) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(39)), transform_worldex },
3812 { /*296, WINED3DTS_WORLDMATRIX(40) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(40)), transform_worldex },
3813 { /*297, WINED3DTS_WORLDMATRIX(41) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(41)), transform_worldex },
3814 { /*298, WINED3DTS_WORLDMATRIX(42) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(42)), transform_worldex },
3815 { /*299, WINED3DTS_WORLDMATRIX(43) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(43)), transform_worldex },
3816 { /*300, WINED3DTS_WORLDMATRIX(44) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(44)), transform_worldex },
3817 { /*301, WINED3DTS_WORLDMATRIX(45) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(45)), transform_worldex },
3818 { /*302, WINED3DTS_WORLDMATRIX(46) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(46)), transform_worldex },
3819 { /*303, WINED3DTS_WORLDMATRIX(47) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(47)), transform_worldex },
3820 { /*304, WINED3DTS_WORLDMATRIX(48) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(48)), transform_worldex },
3821 { /*305, WINED3DTS_WORLDMATRIX(49) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(49)), transform_worldex },
3822 { /*306, WINED3DTS_WORLDMATRIX(50) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(50)), transform_worldex },
3823 { /*307, WINED3DTS_WORLDMATRIX(51) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(51)), transform_worldex },
3824 { /*308, WINED3DTS_WORLDMATRIX(52) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(52)), transform_worldex },
3825 { /*309, WINED3DTS_WORLDMATRIX(53) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(53)), transform_worldex },
3826 { /*310, WINED3DTS_WORLDMATRIX(54) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(54)), transform_worldex },
3827 { /*311, WINED3DTS_WORLDMATRIX(55) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(55)), transform_worldex },
3828 { /*312, WINED3DTS_WORLDMATRIX(56) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(56)), transform_worldex },
3829 { /*313, WINED3DTS_WORLDMATRIX(57) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(57)), transform_worldex },
3830 { /*314, WINED3DTS_WORLDMATRIX(58) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(58)), transform_worldex },
3831 { /*315, WINED3DTS_WORLDMATRIX(59) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(59)), transform_worldex },
3832 { /*316, WINED3DTS_WORLDMATRIX(60) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(60)), transform_worldex },
3833 { /*317, WINED3DTS_WORLDMATRIX(61) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(61)), transform_worldex },
3834 { /*318, WINED3DTS_WORLDMATRIX(62) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(62)), transform_worldex },
3835 { /*319, WINED3DTS_WORLDMATRIX(63) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(63)), transform_worldex },
3836 { /*320, WINED3DTS_WORLDMATRIX(64) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(64)), transform_worldex },
3837 { /*321, WINED3DTS_WORLDMATRIX(65) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(65)), transform_worldex },
3838 { /*322, WINED3DTS_WORLDMATRIX(66) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(66)), transform_worldex },
3839 { /*323, WINED3DTS_WORLDMATRIX(67) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(67)), transform_worldex },
3840 { /*324, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(68)), transform_worldex },
3841 { /*325, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(69)), transform_worldex },
3842 { /*326, WINED3DTS_WORLDMATRIX(70) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(70)), transform_worldex },
3843 { /*327, WINED3DTS_WORLDMATRIX(71) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(71)), transform_worldex },
3844 { /*328, WINED3DTS_WORLDMATRIX(72) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(72)), transform_worldex },
3845 { /*329, WINED3DTS_WORLDMATRIX(73) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(73)), transform_worldex },
3846 { /*330, WINED3DTS_WORLDMATRIX(74) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(74)), transform_worldex },
3847 { /*331, WINED3DTS_WORLDMATRIX(75) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(75)), transform_worldex },
3848 { /*332, WINED3DTS_WORLDMATRIX(76) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(76)), transform_worldex },
3849 { /*333, WINED3DTS_WORLDMATRIX(77) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(77)), transform_worldex },
3850 { /*334, WINED3DTS_WORLDMATRIX(78) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(78)), transform_worldex },
3851 { /*335, WINED3DTS_WORLDMATRIX(79) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(79)), transform_worldex },
3852 { /*336, WINED3DTS_WORLDMATRIX(80) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(80)), transform_worldex },
3853 { /*337, WINED3DTS_WORLDMATRIX(81) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(81)), transform_worldex },
3854 { /*338, WINED3DTS_WORLDMATRIX(82) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(82)), transform_worldex },
3855 { /*339, WINED3DTS_WORLDMATRIX(83) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(83)), transform_worldex },
3856 { /*340, WINED3DTS_WORLDMATRIX(84) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(84)), transform_worldex },
3857 { /*341, WINED3DTS_WORLDMATRIX(85) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(85)), transform_worldex },
3858 { /*341, WINED3DTS_WORLDMATRIX(86) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(86)), transform_worldex },
3859 { /*343, WINED3DTS_WORLDMATRIX(87) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(87)), transform_worldex },
3860 { /*344, WINED3DTS_WORLDMATRIX(88) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(88)), transform_worldex },
3861 { /*345, WINED3DTS_WORLDMATRIX(89) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(89)), transform_worldex },
3862 { /*346, WINED3DTS_WORLDMATRIX(90) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(90)), transform_worldex },
3863 { /*347, WINED3DTS_WORLDMATRIX(91) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(91)), transform_worldex },
3864 { /*348, WINED3DTS_WORLDMATRIX(92) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(92)), transform_worldex },
3865 { /*349, WINED3DTS_WORLDMATRIX(93) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(93)), transform_worldex },
3866 { /*350, WINED3DTS_WORLDMATRIX(94) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(94)), transform_worldex },
3867 { /*351, WINED3DTS_WORLDMATRIX(95) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(95)), transform_worldex },
3868 { /*352, WINED3DTS_WORLDMATRIX(96) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(96)), transform_worldex },
3869 { /*353, WINED3DTS_WORLDMATRIX(97) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(97)), transform_worldex },
3870 { /*354, WINED3DTS_WORLDMATRIX(98) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(98)), transform_worldex },
3871 { /*355, WINED3DTS_WORLDMATRIX(99) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(99)), transform_worldex },
3872 { /*356, WINED3DTS_WORLDMATRIX(100) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex },
3873 { /*357, WINED3DTS_WORLDMATRIX(101) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex },
3874 { /*358, WINED3DTS_WORLDMATRIX(102) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex },
3875 { /*359, WINED3DTS_WORLDMATRIX(103) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex },
3876 { /*360, WINED3DTS_WORLDMATRIX(104) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex },
3877 { /*361, WINED3DTS_WORLDMATRIX(105) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex },
3878 { /*362, WINED3DTS_WORLDMATRIX(106) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex },
3879 { /*363, WINED3DTS_WORLDMATRIX(107) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex },
3880 { /*364, WINED3DTS_WORLDMATRIX(108) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex },
3881 { /*365, WINED3DTS_WORLDMATRIX(109) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex },
3882 { /*366, WINED3DTS_WORLDMATRIX(110) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex },
3883 { /*367, WINED3DTS_WORLDMATRIX(111) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex },
3884 { /*368, WINED3DTS_WORLDMATRIX(112) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex },
3885 { /*369, WINED3DTS_WORLDMATRIX(113) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex },
3886 { /*370, WINED3DTS_WORLDMATRIX(114) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex },
3887 { /*371, WINED3DTS_WORLDMATRIX(115) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex },
3888 { /*372, WINED3DTS_WORLDMATRIX(116) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex },
3889 { /*373, WINED3DTS_WORLDMATRIX(117) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex },
3890 { /*374, WINED3DTS_WORLDMATRIX(118) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex },
3891 { /*375, WINED3DTS_WORLDMATRIX(119) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex },
3892 { /*376, WINED3DTS_WORLDMATRIX(120) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex },
3893 { /*377, WINED3DTS_WORLDMATRIX(121) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex },
3894 { /*378, WINED3DTS_WORLDMATRIX(122) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex },
3895 { /*379, WINED3DTS_WORLDMATRIX(123) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex },
3896 { /*380, WINED3DTS_WORLDMATRIX(124) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex },
3897 { /*381, WINED3DTS_WORLDMATRIX(125) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex },
3898 { /*382, WINED3DTS_WORLDMATRIX(126) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex },
3899 { /*383, WINED3DTS_WORLDMATRIX(127) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex },
3900 { /*384, WINED3DTS_WORLDMATRIX(128) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex },
3901 { /*385, WINED3DTS_WORLDMATRIX(129) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex },
3902 { /*386, WINED3DTS_WORLDMATRIX(130) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex },
3903 { /*387, WINED3DTS_WORLDMATRIX(131) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex },
3904 { /*388, WINED3DTS_WORLDMATRIX(132) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex },
3905 { /*389, WINED3DTS_WORLDMATRIX(133) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex },
3906 { /*390, WINED3DTS_WORLDMATRIX(134) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex },
3907 { /*391, WINED3DTS_WORLDMATRIX(135) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex },
3908 { /*392, WINED3DTS_WORLDMATRIX(136) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex },
3909 { /*393, WINED3DTS_WORLDMATRIX(137) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex },
3910 { /*394, WINED3DTS_WORLDMATRIX(138) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex },
3911 { /*395, WINED3DTS_WORLDMATRIX(139) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex },
3912 { /*396, WINED3DTS_WORLDMATRIX(140) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex },
3913 { /*397, WINED3DTS_WORLDMATRIX(141) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex },
3914 { /*398, WINED3DTS_WORLDMATRIX(142) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex },
3915 { /*399, WINED3DTS_WORLDMATRIX(143) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex },
3916 { /*400, WINED3DTS_WORLDMATRIX(144) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex },
3917 { /*401, WINED3DTS_WORLDMATRIX(145) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex },
3918 { /*402, WINED3DTS_WORLDMATRIX(146) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex },
3919 { /*403, WINED3DTS_WORLDMATRIX(147) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex },
3920 { /*404, WINED3DTS_WORLDMATRIX(148) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex },
3921 { /*405, WINED3DTS_WORLDMATRIX(149) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex },
3922 { /*406, WINED3DTS_WORLDMATRIX(150) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex },
3923 { /*407, WINED3DTS_WORLDMATRIX(151) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex },
3924 { /*408, WINED3DTS_WORLDMATRIX(152) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex },
3925 { /*409, WINED3DTS_WORLDMATRIX(153) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex },
3926 { /*410, WINED3DTS_WORLDMATRIX(154) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex },
3927 { /*411, WINED3DTS_WORLDMATRIX(155) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex },
3928 { /*412, WINED3DTS_WORLDMATRIX(156) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex },
3929 { /*413, WINED3DTS_WORLDMATRIX(157) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex },
3930 { /*414, WINED3DTS_WORLDMATRIX(158) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex },
3931 { /*415, WINED3DTS_WORLDMATRIX(159) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex },
3932 { /*416, WINED3DTS_WORLDMATRIX(160) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex },
3933 { /*417, WINED3DTS_WORLDMATRIX(161) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex },
3934 { /*418, WINED3DTS_WORLDMATRIX(162) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex },
3935 { /*419, WINED3DTS_WORLDMATRIX(163) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex },
3936 { /*420, WINED3DTS_WORLDMATRIX(164) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex },
3937 { /*421, WINED3DTS_WORLDMATRIX(165) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex },
3938 { /*422, WINED3DTS_WORLDMATRIX(166) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex },
3939 { /*423, WINED3DTS_WORLDMATRIX(167) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex },
3940 { /*424, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex },
3941 { /*425, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex },
3942 { /*426, WINED3DTS_WORLDMATRIX(170) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex },
3943 { /*427, WINED3DTS_WORLDMATRIX(171) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex },
3944 { /*428, WINED3DTS_WORLDMATRIX(172) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex },
3945 { /*429, WINED3DTS_WORLDMATRIX(173) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex },
3946 { /*430, WINED3DTS_WORLDMATRIX(174) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex },
3947 { /*431, WINED3DTS_WORLDMATRIX(175) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex },
3948 { /*432, WINED3DTS_WORLDMATRIX(176) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex },
3949 { /*433, WINED3DTS_WORLDMATRIX(177) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex },
3950 { /*434, WINED3DTS_WORLDMATRIX(178) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex },
3951 { /*435, WINED3DTS_WORLDMATRIX(179) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex },
3952 { /*436, WINED3DTS_WORLDMATRIX(180) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex },
3953 { /*437, WINED3DTS_WORLDMATRIX(181) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex },
3954 { /*438, WINED3DTS_WORLDMATRIX(182) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex },
3955 { /*439, WINED3DTS_WORLDMATRIX(183) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex },
3956 { /*440, WINED3DTS_WORLDMATRIX(184) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex },
3957 { /*441, WINED3DTS_WORLDMATRIX(185) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex },
3958 { /*441, WINED3DTS_WORLDMATRIX(186) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex },
3959 { /*443, WINED3DTS_WORLDMATRIX(187) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex },
3960 { /*444, WINED3DTS_WORLDMATRIX(188) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex },
3961 { /*445, WINED3DTS_WORLDMATRIX(189) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex },
3962 { /*446, WINED3DTS_WORLDMATRIX(190) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex },
3963 { /*447, WINED3DTS_WORLDMATRIX(191) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex },
3964 { /*448, WINED3DTS_WORLDMATRIX(192) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex },
3965 { /*449, WINED3DTS_WORLDMATRIX(193) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex },
3966 { /*450, WINED3DTS_WORLDMATRIX(194) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex },
3967 { /*451, WINED3DTS_WORLDMATRIX(195) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex },
3968 { /*452, WINED3DTS_WORLDMATRIX(196) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex },
3969 { /*453, WINED3DTS_WORLDMATRIX(197) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex },
3970 { /*454, WINED3DTS_WORLDMATRIX(198) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex },
3971 { /*455, WINED3DTS_WORLDMATRIX(199) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex },
3972 { /*356, WINED3DTS_WORLDMATRIX(200) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex },
3973 { /*457, WINED3DTS_WORLDMATRIX(201) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex },
3974 { /*458, WINED3DTS_WORLDMATRIX(202) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex },
3975 { /*459, WINED3DTS_WORLDMATRIX(203) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex },
3976 { /*460, WINED3DTS_WORLDMATRIX(204) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex },
3977 { /*461, WINED3DTS_WORLDMATRIX(205) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex },
3978 { /*462, WINED3DTS_WORLDMATRIX(206) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex },
3979 { /*463, WINED3DTS_WORLDMATRIX(207) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex },
3980 { /*464, WINED3DTS_WORLDMATRIX(208) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex },
3981 { /*465, WINED3DTS_WORLDMATRIX(209) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex },
3982 { /*466, WINED3DTS_WORLDMATRIX(210) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex },
3983 { /*467, WINED3DTS_WORLDMATRIX(211) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex },
3984 { /*468, WINED3DTS_WORLDMATRIX(212) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex },
3985 { /*469, WINED3DTS_WORLDMATRIX(213) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex },
3986 { /*470, WINED3DTS_WORLDMATRIX(214) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex },
3987 { /*471, WINED3DTS_WORLDMATRIX(215) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex },
3988 { /*472, WINED3DTS_WORLDMATRIX(216) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex },
3989 { /*473, WINED3DTS_WORLDMATRIX(217) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex },
3990 { /*474, WINED3DTS_WORLDMATRIX(218) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex },
3991 { /*475, WINED3DTS_WORLDMATRIX(219) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex },
3992 { /*476, WINED3DTS_WORLDMATRIX(220) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex },
3993 { /*477, WINED3DTS_WORLDMATRIX(221) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex },
3994 { /*478, WINED3DTS_WORLDMATRIX(222) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex },
3995 { /*479, WINED3DTS_WORLDMATRIX(223) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex },
3996 { /*480, WINED3DTS_WORLDMATRIX(224) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex },
3997 { /*481, WINED3DTS_WORLDMATRIX(225) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex },
3998 { /*482, WINED3DTS_WORLDMATRIX(226) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex },
3999 { /*483, WINED3DTS_WORLDMATRIX(227) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex },
4000 { /*484, WINED3DTS_WORLDMATRIX(228) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex },
4001 { /*485, WINED3DTS_WORLDMATRIX(229) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex },
4002 { /*486, WINED3DTS_WORLDMATRIX(230) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex },
4003 { /*487, WINED3DTS_WORLDMATRIX(231) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex },
4004 { /*488, WINED3DTS_WORLDMATRIX(232) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex },
4005 { /*489, WINED3DTS_WORLDMATRIX(233) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex },
4006 { /*490, WINED3DTS_WORLDMATRIX(234) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex },
4007 { /*491, WINED3DTS_WORLDMATRIX(235) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex },
4008 { /*492, WINED3DTS_WORLDMATRIX(236) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex },
4009 { /*493, WINED3DTS_WORLDMATRIX(237) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex },
4010 { /*494, WINED3DTS_WORLDMATRIX(238) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex },
4011 { /*495, WINED3DTS_WORLDMATRIX(239) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex },
4012 { /*496, WINED3DTS_WORLDMATRIX(240) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex },
4013 { /*497, WINED3DTS_WORLDMATRIX(241) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex },
4014 { /*498, WINED3DTS_WORLDMATRIX(242) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex },
4015 { /*499, WINED3DTS_WORLDMATRIX(243) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex },
4016 { /*500, WINED3DTS_WORLDMATRIX(244) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex },
4017 { /*501, WINED3DTS_WORLDMATRIX(245) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex },
4018 { /*502, WINED3DTS_WORLDMATRIX(246) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex },
4019 { /*503, WINED3DTS_WORLDMATRIX(247) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex },
4020 { /*504, WINED3DTS_WORLDMATRIX(248) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex },
4021 { /*505, WINED3DTS_WORLDMATRIX(249) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex },
4022 { /*506, WINED3DTS_WORLDMATRIX(250) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex },
4023 { /*507, WINED3DTS_WORLDMATRIX(251) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex },
4024 { /*508, WINED3DTS_WORLDMATRIX(252) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex },
4025 { /*509, WINED3DTS_WORLDMATRIX(253) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex },
4026 { /*510, WINED3DTS_WORLDMATRIX(254) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex },
4027 { /*511, WINED3DTS_WORLDMATRIX(255) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex },
4028 /* Various Vertex states follow */
4029 { /* , STATE_STREAMSRC */ STATE_VDECL, vertexdeclaration },
4030 { /* , STATE_VDECL */ STATE_VDECL, vertexdeclaration },
4031 { /* , STATE_VSHADER */ STATE_VDECL, vertexdeclaration },
4032 { /* , STATE_VIEWPORT */ STATE_VIEWPORT, viewport },
4033 { /* , STATE_VERTEXSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4034 { /* , STATE_PIXELSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4035 /* Lights */
4036 { /* , STATE_ACTIVELIGHT(0) */ STATE_ACTIVELIGHT(0), light },
4037 { /* , STATE_ACTIVELIGHT(1) */ STATE_ACTIVELIGHT(1), light },
4038 { /* , STATE_ACTIVELIGHT(2) */ STATE_ACTIVELIGHT(2), light },
4039 { /* , STATE_ACTIVELIGHT(3) */ STATE_ACTIVELIGHT(3), light },
4040 { /* , STATE_ACTIVELIGHT(4) */ STATE_ACTIVELIGHT(4), light },
4041 { /* , STATE_ACTIVELIGHT(5) */ STATE_ACTIVELIGHT(5), light },
4042 { /* , STATE_ACTIVELIGHT(6) */ STATE_ACTIVELIGHT(6), light },
4043 { /* , STATE_ACTIVELIGHT(7) */ STATE_ACTIVELIGHT(7), light },