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
32 #include "wined3d_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
35 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
37 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->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]);
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 WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
64 case WINED3DFILL_POINT:
65 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
66 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
68 case WINED3DFILL_WIREFRAME:
69 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
70 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
72 case WINED3DFILL_SOLID:
73 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
74 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
77 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
81 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
84 /* Lighting is not enabled if transformed vertices are drawn
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)) {
94 transformed = ((stateblock->wineD3DDevice->strided_streams.u.s.position.lpData != NULL ||
95 stateblock->wineD3DDevice->strided_streams.u.s.position.VBO != 0) &&
96 stateblock->wineD3DDevice->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
98 if (stateblock->renderState[WINED3DRS_LIGHTING] && !transformed) {
99 glEnable(GL_LIGHTING);
100 checkGLcall("glEnable GL_LIGHTING");
102 glDisable(GL_LIGHTING);
103 checkGLcall("glDisable GL_LIGHTING");
107 static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
108 /* No z test without depth stencil buffers */
109 if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
110 glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
111 checkGLcall("glDisable GL_DEPTH_TEST");
115 switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
116 case WINED3DZB_FALSE:
117 glDisable(GL_DEPTH_TEST);
118 checkGLcall("glDisable GL_DEPTH_TEST");
121 glEnable(GL_DEPTH_TEST);
122 checkGLcall("glEnable GL_DEPTH_TEST");
125 glEnable(GL_DEPTH_TEST);
126 checkGLcall("glEnable GL_DEPTH_TEST");
127 FIXME("W buffer is not well handled\n");
130 FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]);
134 static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
135 /* TODO: Put this into the offscreen / onscreen rendering block due to device->render_offscreen */
137 /* If we are culling "back faces with clockwise vertices" then
138 set front faces to be counter clockwise and enable culling
140 switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
141 case WINED3DCULL_NONE:
142 glDisable(GL_CULL_FACE);
143 checkGLcall("glDisable GL_CULL_FACE");
146 glEnable(GL_CULL_FACE);
147 checkGLcall("glEnable GL_CULL_FACE");
148 if (stateblock->wineD3DDevice->render_offscreen) {
150 checkGLcall("glFrontFace GL_CW");
153 checkGLcall("glFrontFace GL_CCW");
157 case WINED3DCULL_CCW:
158 glEnable(GL_CULL_FACE);
159 checkGLcall("glEnable GL_CULL_FACE");
160 if (stateblock->wineD3DDevice->render_offscreen) {
162 checkGLcall("glFrontFace GL_CCW");
165 checkGLcall("glFrontFace GL_CW");
170 FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
174 static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
175 switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
176 case WINED3DSHADE_FLAT:
177 glShadeModel(GL_FLAT);
178 checkGLcall("glShadeModel(GL_FLAT)");
180 case WINED3DSHADE_GOURAUD:
181 glShadeModel(GL_SMOOTH);
182 checkGLcall("glShadeModel(GL_SMOOTH)");
184 case WINED3DSHADE_PHONG:
185 FIXME("WINED3DSHADE_PHONG isn't supported\n");
188 FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]);
192 static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
193 if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
195 checkGLcall("glEnable GL_DITHER");
197 glDisable(GL_DITHER);
198 checkGLcall("glDisable GL_DITHER");
202 static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
203 /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
204 * this has to be merged with ZENABLE and ZFUNC
206 if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) {
208 checkGLcall("glDepthMask(1)");
211 checkGLcall("glDepthMask(0)");
215 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
216 int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
220 checkGLcall("glDepthFunc");
224 static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
226 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
228 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
229 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
230 checkGLcall("glLightModel for MODEL_AMBIENT");
233 static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
234 int srcBlend = GL_ZERO;
235 int dstBlend = GL_ZERO;
237 /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */
238 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE] ||
239 stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
240 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
242 checkGLcall("glEnable GL_BLEND");
245 checkGLcall("glDisable GL_BLEND");
246 /* Nothing more to do - get out */
250 switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
251 case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
252 case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
253 case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
254 case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
255 case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
256 case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
257 case WINED3DBLEND_DESTALPHA : srcBlend = GL_DST_ALPHA; break;
258 case WINED3DBLEND_INVDESTALPHA : srcBlend = GL_ONE_MINUS_DST_ALPHA; break;
259 case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
260 case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
261 case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
263 case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
264 dstBlend = GL_SRC_ALPHA;
267 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
268 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
271 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
272 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
274 FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
277 switch (stateblock->renderState[WINED3DRS_DESTBLEND]) {
278 case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break;
279 case WINED3DBLEND_ONE : dstBlend = GL_ONE; break;
280 case WINED3DBLEND_SRCCOLOR : dstBlend = GL_SRC_COLOR; break;
281 case WINED3DBLEND_INVSRCCOLOR : dstBlend = GL_ONE_MINUS_SRC_COLOR; break;
282 case WINED3DBLEND_SRCALPHA : dstBlend = GL_SRC_ALPHA; break;
283 case WINED3DBLEND_INVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA; break;
284 case WINED3DBLEND_DESTALPHA : dstBlend = GL_DST_ALPHA; break;
285 case WINED3DBLEND_INVDESTALPHA : dstBlend = GL_ONE_MINUS_DST_ALPHA; break;
286 case WINED3DBLEND_DESTCOLOR : dstBlend = GL_DST_COLOR; break;
287 case WINED3DBLEND_INVDESTCOLOR : dstBlend = GL_ONE_MINUS_DST_COLOR; break;
288 case WINED3DBLEND_SRCALPHASAT : dstBlend = GL_SRC_ALPHA_SATURATE; break;
290 case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA;
291 srcBlend = GL_SRC_ALPHA;
294 case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
295 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
298 case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
299 case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
301 FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
304 if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
305 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
306 glEnable(GL_LINE_SMOOTH);
307 checkGLcall("glEnable(GL_LINE_SMOOTH)");
308 if(srcBlend != GL_SRC_ALPHA) {
309 FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible src blending param - what to do?\n");
310 srcBlend = GL_SRC_ALPHA;
312 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA) {
313 FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible dst blending param - what to do?\n");
314 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
317 glDisable(GL_LINE_SMOOTH);
318 checkGLcall("glDisable(GL_LINE_SMOOTH)");
321 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
322 glBlendFunc(srcBlend, dstBlend);
323 checkGLcall("glBlendFunc");
326 static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
329 TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
330 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
331 glBlendColor (col[0],col[1],col[2],col[3]);
332 checkGLcall("glBlendColor");
335 static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
338 BOOL enable_ckey = FALSE;
340 IWineD3DSurfaceImpl *surf;
342 /* Find out if the texture on the first stage has a ckey set
343 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
344 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
345 * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
346 * in case it finds some texture+colorkeyenable combination which needs extra care.
348 if(stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
349 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
351 if(surf->CKeyFlags & WINEDDSD_CKSRCBLT) {
352 const PixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format);
353 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
354 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
355 * surface has alpha bits
357 if(fmt->alphaMask == 0x00000000) {
363 if(enable_ckey || context->last_was_ckey) {
364 StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
366 context->last_was_ckey = enable_ckey;
368 if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
369 (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
370 glEnable(GL_ALPHA_TEST);
371 checkGLcall("glEnable GL_ALPHA_TEST");
373 glDisable(GL_ALPHA_TEST);
374 checkGLcall("glDisable GL_ALPHA_TEST");
375 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
381 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
382 glParm = GL_NOTEQUAL;
385 ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
386 glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
389 glAlphaFunc(glParm, ref);
390 checkGLcall("glAlphaFunc");
394 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
395 DWORD enable = 0xFFFFFFFF;
396 DWORD disable = 0x00000000;
398 if (use_vs(stateblock->wineD3DDevice)) {
399 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
400 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
401 * contitions I got sick of tracking down. The shader state handler disables all clip planes because
402 * of that - don't do anything here and keep them disabled
404 if(stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
405 static BOOL warned = FALSE;
407 FIXME("Clipping not supported with vertex shaders\n");
414 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
415 * of already set values
418 /* If enabling / disabling all
419 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
421 if (stateblock->renderState[WINED3DRS_CLIPPING]) {
422 enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
423 disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
425 disable = 0xffffffff;
429 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
430 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
431 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
432 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
433 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
434 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
436 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
437 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
438 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
439 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
440 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
441 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
443 /** update clipping status */
445 stateblock->clip_status.ClipUnion = 0;
446 stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
448 stateblock->clip_status.ClipUnion = 0;
449 stateblock->clip_status.ClipIntersection = 0;
453 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
454 int glParm = GL_FUNC_ADD;
456 if(!GL_SUPPORT(EXT_BLEND_MINMAX)) {
457 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
461 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
462 case WINED3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
463 case WINED3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
464 case WINED3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
465 case WINED3DBLENDOP_MIN : glParm = GL_MIN; break;
466 case WINED3DBLENDOP_MAX : glParm = GL_MAX; break;
468 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
471 TRACE("glBlendEquation(%x)\n", glParm);
472 GL_EXTCALL(glBlendEquation(glParm));
473 checkGLcall("glBlendEquation");
477 state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
478 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
479 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
480 * specular color. This is wrong:
481 * Separate specular color means the specular colour is maintained separately, whereas
482 * single color means it is merged in. However in both cases they are being used to
484 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
485 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
489 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
490 * Instead, we need to setup the FinalCombiner properly.
492 * The default setup for the FinalCombiner is:
494 * <variable> <input> <mapping> <usage>
495 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
496 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
497 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
498 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
499 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
500 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
501 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
503 * That's pretty much fine as it is, except for variable B, which needs to take
504 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
505 * whether WINED3DRS_SPECULARENABLE is enabled or not.
508 TRACE("Setting specular enable state and materials\n");
509 if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
510 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
511 checkGLcall("glMaterialfv");
513 if(stateblock->material.Power > 128.0) {
514 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
515 * and 128.0, although in d3d neither -1 nor 129 produce an error. For values > 128 clamp
516 * them, since 128 results in a hardly visible specular highlight, so it should be safe to
519 WARN("Material power > 128\n");
520 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128.0);
522 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stateblock->material.Power);
524 checkGLcall("glMaterialf(GL_SHININESS");
526 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
527 glEnable(GL_COLOR_SUM_EXT);
529 TRACE("Specular colors cannot be enabled in this version of opengl\n");
531 checkGLcall("glEnable(GL_COLOR_SUM)");
533 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
534 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
535 checkGLcall("glFinalCombinerInputNV()");
538 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
540 /* for the case of enabled lighting: */
541 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
542 checkGLcall("glMaterialfv");
544 /* for the case of disabled lighting: */
545 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
546 glDisable(GL_COLOR_SUM_EXT);
548 TRACE("Specular colors cannot be disabled in this version of opengl\n");
550 checkGLcall("glDisable(GL_COLOR_SUM)");
552 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
553 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
554 checkGLcall("glFinalCombinerInputNV()");
558 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Diffuse.r, stateblock->material.Diffuse.g,
559 stateblock->material.Diffuse.b, stateblock->material.Diffuse.a);
560 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Ambient.r, stateblock->material.Ambient.g,
561 stateblock->material.Ambient.b, stateblock->material.Ambient.a);
562 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Specular.r, stateblock->material.Specular.g,
563 stateblock->material.Specular.b, stateblock->material.Specular.a);
564 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Emissive.r, stateblock->material.Emissive.g,
565 stateblock->material.Emissive.b, stateblock->material.Emissive.a);
567 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &stateblock->material.Ambient);
568 checkGLcall("glMaterialfv(GL_AMBIENT)");
569 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &stateblock->material.Diffuse);
570 checkGLcall("glMaterialfv(GL_DIFFUSE)");
571 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &stateblock->material.Emissive);
572 checkGLcall("glMaterialfv(GL_EMISSION)");
575 static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
578 /* Note the texture color applies to all textures whereas
579 * GL_TEXTURE_ENV_COLOR applies to active only
582 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
584 if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
585 /* And now the default texture color as well */
586 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
587 /* Note the WINED3DRS value applies to all textures, but GL has one
588 * per texture, so apply it now ready to be used!
590 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
591 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
592 checkGLcall("glActiveTextureARB");
594 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
597 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
598 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
601 GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
606 renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass ) {
607 #if 0 /* Don't use OpenGL 2.0 calls for now */
608 if(GL_EXTCALL(glStencilFuncSeparate) && GL_EXTCALL(glStencilOpSeparate)) {
609 GL_EXTCALL(glStencilFuncSeparate(face, func, ref, mask));
610 checkGLcall("glStencilFuncSeparate(...)");
611 GL_EXTCALL(glStencilOpSeparate(face, stencilFail, depthFail, stencilPass));
612 checkGLcall("glStencilOpSeparate(...)");
616 if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
617 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
618 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
619 GL_EXTCALL(glActiveStencilFaceEXT(face));
620 checkGLcall("glActiveStencilFaceEXT(...)");
621 glStencilFunc(func, ref, mask);
622 checkGLcall("glStencilFunc(...)");
623 glStencilOp(stencilFail, depthFail, stencilPass);
624 checkGLcall("glStencilOp(...)");
625 } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
626 GL_EXTCALL(glStencilFuncSeparateATI(face, func, ref, mask));
627 checkGLcall("glStencilFuncSeparateATI(...)");
628 GL_EXTCALL(glStencilOpSeparateATI(face, stencilFail, depthFail, stencilPass));
629 checkGLcall("glStencilOpSeparateATI(...)");
631 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
636 state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
637 DWORD onesided_enable = FALSE;
638 DWORD twosided_enable = FALSE;
639 GLint func = GL_ALWAYS;
640 GLint func_ccw = GL_ALWAYS;
643 GLint stencilFail = GL_KEEP;
644 GLint depthFail = GL_KEEP;
645 GLint stencilPass = GL_KEEP;
646 GLint stencilFail_ccw = GL_KEEP;
647 GLint depthFail_ccw = GL_KEEP;
648 GLint stencilPass_ccw = GL_KEEP;
650 /* No stencil test without a stencil buffer */
651 if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
652 glDisable(GL_STENCIL_TEST);
653 checkGLcall("glDisable GL_STENCIL_TEST");
657 if( stateblock->set.renderState[WINED3DRS_STENCILENABLE] )
658 onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
659 if( stateblock->set.renderState[WINED3DRS_TWOSIDEDSTENCILMODE] )
660 twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
661 if( stateblock->set.renderState[WINED3DRS_STENCILFUNC] )
662 if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
664 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFUNC] )
665 if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
667 if( stateblock->set.renderState[WINED3DRS_STENCILREF] )
668 ref = stateblock->renderState[WINED3DRS_STENCILREF];
669 if( stateblock->set.renderState[WINED3DRS_STENCILMASK] )
670 mask = stateblock->renderState[WINED3DRS_STENCILMASK];
671 if( stateblock->set.renderState[WINED3DRS_STENCILFAIL] )
672 stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
673 if( stateblock->set.renderState[WINED3DRS_STENCILZFAIL] )
674 depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
675 if( stateblock->set.renderState[WINED3DRS_STENCILPASS] )
676 stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
677 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFAIL] )
678 stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
679 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILZFAIL] )
680 depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
681 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILPASS] )
682 stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
684 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
685 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
686 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
687 onesided_enable, twosided_enable, ref, mask,
688 func, stencilFail, depthFail, stencilPass,
689 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
691 if (twosided_enable) {
692 renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
693 renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
695 if (onesided_enable) {
696 glEnable(GL_STENCIL_TEST);
697 checkGLcall("glEnable GL_STENCIL_TEST");
698 glStencilFunc(func, ref, mask);
699 checkGLcall("glStencilFunc(...)");
700 glStencilOp(stencilFail, depthFail, stencilPass);
701 checkGLcall("glStencilOp(...)");
703 glDisable(GL_STENCIL_TEST);
704 checkGLcall("glDisable GL_STENCIL_TEST");
709 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
710 if(stateblock->wineD3DDevice->stencilBufferTarget) {
711 glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]);
715 checkGLcall("glStencilMask");
718 static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
719 /* TODO: Put this into the vertex type block once that is in the state table */
720 BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
721 BOOL is_ps3 = use_ps(stateblock->wineD3DDevice)
722 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version >= WINED3DPS_VERSION(3,0);
723 float fogstart, fogend;
731 /* No fog? Disable it, and we're done :-) */
733 checkGLcall("glDisable GL_FOG");
734 if( use_ps(stateblock->wineD3DDevice)
735 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version < WINED3DPS_VERSION(3,0) ) {
736 /* disable fog in the pixel shader
737 * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
738 * -1/(e-s) and e/(e-s) respectively.
740 glFogf(GL_FOG_START, 0.0f);
741 checkGLcall("glFogf(GL_FOG_START, fogstart");
742 glFogf(GL_FOG_END, 1.0f);
743 checkGLcall("glFogf(GL_FOG_END, fogend");
748 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
749 fogstart = tmpvalue.f;
750 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
755 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
756 * It can use the Z value of the vertex, or the alpha component of the specular color.
757 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
758 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
759 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
761 * FOGTABLEMODE != NONE:
762 * The Z value is used, with the equation specified, no matter what vertex type.
764 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
765 * Per vertex fog is calculated using the specified fog equation and the parameters
767 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
768 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
769 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
772 * Rules for vertex fog with shaders:
774 * When mixing fixed function functionality with the programmable pipeline, D3D expects
775 * the fog computation to happen during transformation while openGL expects it to happen
776 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
777 * the pixel shader while openGL always expects the pixel shader to handle the blending.
778 * To solve this problem, WineD3D does:
779 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
781 * and 2) disables the fog computation (in either the fixed function or programmable
782 * rasterizer) if using a vertex program.
785 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
790 if( !use_vs(stateblock->wineD3DDevice)
791 && stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ) {
792 FIXME("Implement vertex fog for pixel shader >= 3.0 and fixed function pipeline\n");
796 if (use_vs(stateblock->wineD3DDevice)
797 && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
798 if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
799 if(!is_ps3) FIXME("Implement table fog for foggy vertex shader\n");
803 /* Set fog computation in the rasterizer to pass through the value (just blend it) */
804 glFogi(GL_FOG_MODE, GL_LINEAR);
805 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
809 context->last_was_foggy_shader = TRUE;
811 else if( use_ps(stateblock->wineD3DDevice) ) {
812 /* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
813 * -1/(e-s) and e/(e-s) respectively to simplify fog computation in the shader.
816 context->last_was_foggy_shader = FALSE;
818 /* If both fogmodes are set use the table fog mode */
819 if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
820 mode = stateblock->renderState[WINED3DRS_FOGVERTEXMODE];
822 mode = stateblock->renderState[WINED3DRS_FOGTABLEMODE];
826 case WINED3DFOG_EXP2:
827 if(!is_ps3) FIXME("Implement non linear fog for pixel shader < 3.0\n");
832 case WINED3DFOG_LINEAR:
833 fogstart = -1.0f/(fogend-fogstart);
837 case WINED3DFOG_NONE:
838 if(!is_ps3) FIXME("Implement software vertex fog for pixel shader < 3.0\n");
842 default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
845 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
846 * the system will apply only pixel(=table) fog effects."
848 else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
849 glHint(GL_FOG_HINT, GL_FASTEST);
850 checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
851 context->last_was_foggy_shader = FALSE;
853 switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
854 /* If processed vertices are used, fall through to the NONE case */
855 case WINED3DFOG_EXP: {
856 if(!context->last_was_rhw) {
857 glFogi(GL_FOG_MODE, GL_EXP);
858 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
859 if(GL_SUPPORT(EXT_FOG_COORD)) {
860 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
861 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
866 case WINED3DFOG_EXP2: {
867 if(!context->last_was_rhw) {
868 glFogi(GL_FOG_MODE, GL_EXP2);
869 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
870 if(GL_SUPPORT(EXT_FOG_COORD)) {
871 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
872 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
877 case WINED3DFOG_LINEAR: {
878 if(!context->last_was_rhw) {
879 glFogi(GL_FOG_MODE, GL_LINEAR);
880 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
881 if(GL_SUPPORT(EXT_FOG_COORD)) {
882 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
883 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
888 case WINED3DFOG_NONE: {
889 /* Both are none? According to msdn the alpha channel of the specular
890 * color contains a fog factor. Set it in drawStridedSlow.
891 * Same happens with Vertexfog on transformed vertices
893 if(GL_SUPPORT(EXT_FOG_COORD)) {
894 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
895 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
896 glFogi(GL_FOG_MODE, GL_LINEAR);
897 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
901 /* Disable GL fog, handle this in software in drawStridedSlow */
906 default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
909 glHint(GL_FOG_HINT, GL_NICEST);
910 checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
911 context->last_was_foggy_shader = FALSE;
913 switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
915 glFogi(GL_FOG_MODE, GL_EXP);
916 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
917 if(GL_SUPPORT(EXT_FOG_COORD)) {
918 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
919 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
923 case WINED3DFOG_EXP2:
924 glFogi(GL_FOG_MODE, GL_EXP2);
925 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
926 if(GL_SUPPORT(EXT_FOG_COORD)) {
927 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
928 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
932 case WINED3DFOG_LINEAR:
933 glFogi(GL_FOG_MODE, GL_LINEAR);
934 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
935 if(GL_SUPPORT(EXT_FOG_COORD)) {
936 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
937 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
941 case WINED3DFOG_NONE: /* Won't happen */
943 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
949 checkGLcall("glEnable GL_FOG");
951 glFogfv(GL_FOG_START, &fogstart);
952 checkGLcall("glFogf(GL_FOG_START, fogstart");
953 TRACE("Fog Start == %f\n", fogstart);
955 glFogfv(GL_FOG_END, &fogend);
956 checkGLcall("glFogf(GL_FOG_END, fogend");
957 TRACE("Fog End == %f\n", fogend);
960 checkGLcall("glDisable GL_FOG");
961 if( use_ps(stateblock->wineD3DDevice) ) {
962 /* disable fog in the pixel shader
963 * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
964 * -1/(e-s) and e/(e-s) respectively.
966 glFogf(GL_FOG_START, 0.0f);
967 checkGLcall("glFogf(GL_FOG_START, fogstart");
968 glFogf(GL_FOG_END, 1.0f);
969 checkGLcall("glFogf(GL_FOG_END, fogend");
973 if (GL_SUPPORT(NV_FOG_DISTANCE)) {
974 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
978 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
980 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
981 glFogfv(GL_FOG_COLOR, &col[0]);
982 checkGLcall("glFog GL_FOG_COLOR");
985 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
990 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
991 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
992 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
995 /* TODO: Merge with primitive type + init_materials()!! */
996 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
997 IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)stateblock->wineD3DDevice;
999 WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
1000 BOOL isDiffuseSupplied;
1002 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1003 * The vertex declaration will call this function if the fixed function pipeline is used.
1006 if(isStateDirty(context, STATE_VDECL)) {
1010 isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
1012 context->num_untracked_materials = 0;
1013 if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
1014 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1015 stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
1016 stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
1017 stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
1018 stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
1020 if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1021 if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1022 Parm = GL_AMBIENT_AND_DIFFUSE;
1026 if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1027 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1028 context->num_untracked_materials++;
1030 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1031 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1032 context->num_untracked_materials++;
1034 } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1036 if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1037 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1038 context->num_untracked_materials++;
1040 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1041 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1042 context->num_untracked_materials++;
1044 } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1046 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1047 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1048 context->num_untracked_materials++;
1050 } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1055 /* Nothing changed, return. */
1056 if (Parm == context->tracking_parm) return;
1059 glDisable(GL_COLOR_MATERIAL);
1060 checkGLcall("glDisable GL_COLOR_MATERIAL");
1062 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1063 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1064 glEnable(GL_COLOR_MATERIAL);
1065 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1068 /* Apparently calls to glMaterialfv are ignored for properties we're
1069 * tracking with glColorMaterial, so apply those here. */
1070 switch (context->tracking_parm) {
1071 case GL_AMBIENT_AND_DIFFUSE:
1072 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1073 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1074 checkGLcall("glMaterialfv");
1078 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1079 checkGLcall("glMaterialfv");
1083 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1084 checkGLcall("glMaterialfv");
1088 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
1089 checkGLcall("glMaterialfv");
1093 /* Only change material color if specular is enabled, otherwise it is set to black */
1094 if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
1095 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
1096 checkGLcall("glMaterialfv");
1098 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1099 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1100 checkGLcall("glMaterialfv");
1105 context->tracking_parm = Parm;
1108 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1111 WINED3DLINEPATTERN lp;
1113 tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
1115 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1117 if (tmppattern.lp.wRepeatFactor) {
1118 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1119 checkGLcall("glLineStipple(repeat, linepattern)");
1120 glEnable(GL_LINE_STIPPLE);
1121 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1123 glDisable(GL_LINE_STIPPLE);
1124 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1128 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1134 if (stateblock->renderState[WINED3DRS_ZBIAS]) {
1135 tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
1136 TRACE("ZBias value %f\n", tmpvalue.f);
1137 glPolygonOffset(0, -tmpvalue.f);
1138 checkGLcall("glPolygonOffset(0, -Value)");
1139 glEnable(GL_POLYGON_OFFSET_FILL);
1140 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
1141 glEnable(GL_POLYGON_OFFSET_LINE);
1142 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
1143 glEnable(GL_POLYGON_OFFSET_POINT);
1144 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
1146 glDisable(GL_POLYGON_OFFSET_FILL);
1147 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
1148 glDisable(GL_POLYGON_OFFSET_LINE);
1149 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
1150 glDisable(GL_POLYGON_OFFSET_POINT);
1151 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
1156 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1157 if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
1158 glEnable(GL_NORMALIZE);
1159 checkGLcall("glEnable(GL_NORMALIZE);");
1161 glDisable(GL_NORMALIZE);
1162 checkGLcall("glDisable(GL_NORMALIZE);");
1166 static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1172 /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
1173 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
1174 TRACE("Set point size to %f\n", tmpvalue.f);
1175 glPointSize(tmpvalue.f);
1176 checkGLcall("glPointSize(...);");
1179 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1185 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1186 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1187 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
1188 checkGLcall("glPointParameterfARB(...");
1190 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1191 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
1192 checkGLcall("glPointParameterfEXT(...);");
1193 } else if(tmpvalue.f != 1.0) {
1194 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1198 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1204 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1205 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1206 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
1207 checkGLcall("glPointParameterfARB(...");
1209 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1210 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
1211 checkGLcall("glPointParameterfEXT(...);");
1212 } else if(tmpvalue.f != 64.0) {
1213 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1217 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1218 /* TODO: Group this with the viewport */
1220 * POINTSCALEENABLE controls how point size value is treated. If set to
1221 * true, the point size is scaled with respect to height of viewport.
1222 * When set to false point size is in pixels.
1224 * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
1227 /* Default values */
1228 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1231 * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
1232 * This means that OpenGL will clamp really small point sizes to 1.0f.
1233 * To correct for this we need to multiply by the scale factor when sizes
1234 * are less than 1.0f. scale_factor = 1.0f / point_size.
1236 GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
1237 if(pointSize > 0.0f) {
1238 GLfloat scaleFactor;
1240 if(pointSize < 1.0f) {
1241 scaleFactor = pointSize * pointSize;
1246 if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1247 att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
1248 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1249 att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
1250 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1251 att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
1252 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1256 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1257 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1258 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
1260 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1261 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1262 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
1264 TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
1268 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1269 DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1271 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1272 Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1273 Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1274 Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1275 Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1276 glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1277 Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1278 Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1279 Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1280 checkGLcall("glColorMask(...)");
1282 /* depends on WINED3DRS_COLORWRITEENABLE. */
1283 if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1284 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1285 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1286 ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1287 stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1288 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1289 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1293 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1294 if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1295 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1296 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1298 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1299 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1303 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1304 if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1305 TRACE("Last Pixel Drawing Enabled\n");
1307 static BOOL first = TRUE;
1309 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1312 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1317 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1318 /* TODO: NV_POINT_SPRITE */
1319 if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1320 TRACE("Point sprites not supported\n");
1324 if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1325 glEnable(GL_POINT_SPRITE_ARB);
1326 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)\n");
1328 glDisable(GL_POINT_SPRITE_ARB);
1329 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)\n");
1333 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1335 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1336 http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/FixedFunction/Textures/texturewrapping.asp
1337 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1338 Descussion that ways to turn on WRAPing to solve an opengl conversion problem.
1339 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1341 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1344 if(stateblock->renderState[WINED3DRS_WRAP0] ||
1345 stateblock->renderState[WINED3DRS_WRAP1] ||
1346 stateblock->renderState[WINED3DRS_WRAP2] ||
1347 stateblock->renderState[WINED3DRS_WRAP3] ||
1348 stateblock->renderState[WINED3DRS_WRAP4] ||
1349 stateblock->renderState[WINED3DRS_WRAP5] ||
1350 stateblock->renderState[WINED3DRS_WRAP6] ||
1351 stateblock->renderState[WINED3DRS_WRAP7] ||
1352 stateblock->renderState[WINED3DRS_WRAP8] ||
1353 stateblock->renderState[WINED3DRS_WRAP9] ||
1354 stateblock->renderState[WINED3DRS_WRAP10] ||
1355 stateblock->renderState[WINED3DRS_WRAP11] ||
1356 stateblock->renderState[WINED3DRS_WRAP12] ||
1357 stateblock->renderState[WINED3DRS_WRAP13] ||
1358 stateblock->renderState[WINED3DRS_WRAP14] ||
1359 stateblock->renderState[WINED3DRS_WRAP15] ) {
1360 FIXME("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1364 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1365 if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1366 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1367 glEnable(GL_MULTISAMPLE_ARB);
1368 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1370 glDisable(GL_MULTISAMPLE_ARB);
1371 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1374 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1375 ERR("Multisample antialiasing not supported by gl\n");
1380 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1381 if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1382 glEnable(GL_SCISSOR_TEST);
1383 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1385 glDisable(GL_SCISSOR_TEST);
1386 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1390 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1396 if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1397 stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1398 tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1399 glEnable(GL_POLYGON_OFFSET_FILL);
1400 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1401 glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1402 checkGLcall("glPolygonOffset(...)");
1404 glDisable(GL_POLYGON_OFFSET_FILL);
1405 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1409 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1410 if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1411 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1412 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1414 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1415 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1419 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1421 if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1422 FIXME(" Stippled Alpha not supported yet.\n");
1425 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1427 if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1428 FIXME(" Antialias not supported yet.\n");
1431 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1433 if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1434 FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1437 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1439 if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1440 FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1443 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1451 if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1453 static BOOL displayed = FALSE;
1455 tmpvalue.d = stateblock->renderState[WINED3DRS_PATCHSEGMENTS];
1457 FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1463 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1465 if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1466 FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1469 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1471 if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1472 FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1475 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1477 if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1478 FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1482 static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1483 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
1484 FIXME("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
1487 static void state_separateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1489 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
1490 FIXME("(WINED3DRS_SEPARATEALPHABLENDENABLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]);
1493 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1494 if(stateblock->renderState[WINED3DRS_WRAPU]) {
1495 FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1499 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1500 if(stateblock->renderState[WINED3DRS_WRAPV]) {
1501 FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1505 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1506 if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1507 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1511 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1512 if(stateblock->renderState[WINED3DRS_ROP2]) {
1513 FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1517 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1518 if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1519 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1523 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1524 if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1525 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1529 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1530 if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1531 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1535 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1536 if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1537 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1541 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1542 if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1543 FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1547 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1548 if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1549 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1553 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1554 if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1555 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1559 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1560 if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1561 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1565 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1566 if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1567 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1571 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1572 if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1573 FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1577 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1578 if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1579 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1583 /* Activates the texture dimension according to the bound D3D texture.
1584 * Does not care for the colorop or correct gl texture unit(when using nvrc)
1585 * Requires the caller to activate the correct unit before
1587 static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1588 BOOL bumpmap = FALSE;
1590 if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
1591 stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP)) {
1593 context->texShaderBumpMap |= (1 << stage);
1595 context->texShaderBumpMap &= ~(1 << stage);
1598 if(stateblock->textures[stage]) {
1599 switch(stateblock->textureDimensions[stage]) {
1601 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1602 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
1604 glDisable(GL_TEXTURE_3D);
1605 checkGLcall("glDisable(GL_TEXTURE_3D)");
1606 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1607 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1608 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1610 glEnable(GL_TEXTURE_2D);
1611 checkGLcall("glEnable(GL_TEXTURE_2D)");
1615 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1616 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
1618 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1619 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1620 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1622 glDisable(GL_TEXTURE_2D);
1623 checkGLcall("glDisable(GL_TEXTURE_2D)");
1624 glEnable(GL_TEXTURE_3D);
1625 checkGLcall("glEnable(GL_TEXTURE_3D)");
1628 case GL_TEXTURE_CUBE_MAP_ARB:
1629 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1630 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
1632 glDisable(GL_TEXTURE_2D);
1633 checkGLcall("glDisable(GL_TEXTURE_2D)");
1634 glDisable(GL_TEXTURE_3D);
1635 checkGLcall("glDisable(GL_TEXTURE_3D)");
1636 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
1637 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
1642 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1643 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
1645 glEnable(GL_TEXTURE_2D);
1646 checkGLcall("glEnable(GL_TEXTURE_2D)");
1647 glDisable(GL_TEXTURE_3D);
1648 checkGLcall("glDisable(GL_TEXTURE_3D)");
1649 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1650 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1651 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1653 /* Binding textures is done by samplers. A dummy texture will be bound */
1658 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1659 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1660 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1662 TRACE("Setting color op for stage %d\n", stage);
1664 if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1665 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1666 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1670 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1672 if (mapped_stage != -1) {
1673 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1674 if (mapped_stage >= GL_LIMITS(textures)) {
1675 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1676 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1677 FIXME("Attempt to enable unsupported stage!\n");
1681 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1682 checkGLcall("glActiveTextureARB");
1683 } else if (stage > 0) {
1684 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1689 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1690 if(stateblock->lowest_disabled_stage > 0) {
1691 glEnable(GL_REGISTER_COMBINERS_NV);
1692 GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, stateblock->lowest_disabled_stage));
1694 glDisable(GL_REGISTER_COMBINERS_NV);
1697 if(stage >= stateblock->lowest_disabled_stage) {
1698 TRACE("Stage disabled\n");
1699 if (mapped_stage != -1) {
1700 /* Disable everything here */
1701 glDisable(GL_TEXTURE_2D);
1702 checkGLcall("glDisable(GL_TEXTURE_2D)");
1703 glDisable(GL_TEXTURE_3D);
1704 checkGLcall("glDisable(GL_TEXTURE_3D)");
1705 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1706 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1707 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1709 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1710 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
1717 /* The sampler will also activate the correct texture dimensions, so no need to do it here
1718 * if the sampler for this stage is dirty
1720 if(!isStateDirty(context, STATE_SAMPLER(stage))) {
1721 if (mapped_stage != -1) activate_dimensions(stage, stateblock, context);
1724 /* Set the texture combiners */
1725 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1726 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1727 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1728 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1729 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1730 stateblock->textureState[stage][WINED3DTSS_COLORARG0],
1733 /* In register combiners bump mapping is done in the stage AFTER the one that has the bump map operation set,
1734 * thus the texture shader may have to be updated
1736 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1737 BOOL usesBump = (stateblock->textureState[stage][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
1738 stateblock->textureState[stage][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP) ? TRUE : FALSE;
1739 BOOL usedBump = (context->texShaderBumpMap & 1 << (stage + 1)) ? TRUE : FALSE;
1740 if(usesBump != usedBump) {
1741 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage + 1));
1742 checkGLcall("glActiveTextureARB");
1743 activate_dimensions(stage + 1, stateblock, context);
1744 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1745 checkGLcall("glActiveTextureARB");
1749 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1750 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1751 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1752 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1753 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1757 static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1758 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1759 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1760 DWORD op, arg1, arg2, arg0;
1762 TRACE("Setting alpha op for stage %d\n", stage);
1763 /* Do not care for enabled / disabled stages, just assign the settigns. colorop disables / enables required stuff */
1764 if (mapped_stage != -1) {
1765 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1766 if (stage >= GL_LIMITS(textures)) {
1767 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1768 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1769 FIXME("Attempt to enable unsupported stage!\n");
1773 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1774 checkGLcall("glActiveTextureARB");
1775 } else if (stage > 0) {
1776 /* We can't do anything here */
1777 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1782 op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
1783 arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
1784 arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
1785 arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
1787 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 &&
1788 stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
1789 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
1791 if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
1792 getFormatDescEntry(surf->resource.format)->alphaMask == 0x00000000) {
1794 /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
1795 * On the other hand applications can still use texture combiners apparently. This code takes care that apps
1796 * cannot remove the texture's alpha channel entirely.
1798 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work
1799 * on color keyed surfaces.
1801 * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing
1803 if(op == WINED3DTOP_DISABLE) op = WINED3DTOP_SELECTARG1;
1804 if(op == WINED3DTOP_SELECTARG1) arg1 = WINED3DTA_TEXTURE;
1805 else if(op == WINED3DTOP_SELECTARG2) arg2 = WINED3DTA_TEXTURE;
1809 TRACE("Setting alpha op for stage %d\n", stage);
1810 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1811 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1812 op, arg1, arg2, arg0,
1815 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1816 op, arg1, arg2, arg0);
1820 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1821 DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1822 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
1824 if (mapped_stage < 0) return;
1826 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1827 if(mapped_stage >= GL_LIMITS(textures)) {
1830 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1831 checkGLcall("glActiveTextureARB");
1832 } else if (mapped_stage > 0) {
1833 /* We can't do anything here */
1834 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1838 set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1839 stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1840 (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU);
1844 static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
1847 for (texture_idx = 0; texture_idx < GL_LIMITS(texture_stages); ++texture_idx) {
1848 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
1849 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1853 static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd, GLint *curVBO) {
1854 UINT *offset = stateblock->streamOffset;
1855 unsigned int mapped_stage = 0;
1856 unsigned int textureNo = 0;
1858 /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
1859 /* Abort if we don't support the extension. */
1860 if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
1861 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1865 for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
1866 int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
1868 mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo];
1869 if (mapped_stage == -1) continue;
1871 if (coordIdx < MAX_TEXTURES && (sd->u.s.texCoords[coordIdx].lpData || sd->u.s.texCoords[coordIdx].VBO)) {
1872 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
1873 textureNo, mapped_stage, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
1875 if (*curVBO != sd->u.s.texCoords[coordIdx].VBO) {
1876 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
1877 checkGLcall("glBindBufferARB");
1878 *curVBO = sd->u.s.texCoords[coordIdx].VBO;
1881 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1882 checkGLcall("glClientActiveTextureARB");
1884 /* The coords to supply depend completely on the fvf / vertex shader */
1886 WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
1887 WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
1888 sd->u.s.texCoords[coordIdx].dwStride,
1889 sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
1890 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1892 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
1895 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1896 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one */
1897 for (textureNo = mapped_stage + 1; textureNo < GL_LIMITS(textures); ++textureNo) {
1898 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
1903 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1904 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1905 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1907 if (mapped_stage == -1) {
1908 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
1912 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1913 if(mapped_stage >= GL_LIMITS(fragment_samplers)) {
1916 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1917 checkGLcall("glActiveTextureARB");
1918 } else if (stage > 0) {
1919 /* We can't do anything here */
1920 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1924 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
1926 * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
1927 * one flag, you can still specify an index value, which the system uses to
1928 * determine the texture wrapping mode.
1929 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
1930 * means use the vertex position (camera-space) as the input texture coordinates
1931 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
1932 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
1933 * to the TEXCOORDINDEX value
1937 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
1939 switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
1940 case WINED3DTSS_TCI_PASSTHRU:
1941 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
1942 glDisable(GL_TEXTURE_GEN_S);
1943 glDisable(GL_TEXTURE_GEN_T);
1944 glDisable(GL_TEXTURE_GEN_R);
1945 glDisable(GL_TEXTURE_GEN_Q);
1946 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
1949 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
1950 /* CameraSpacePosition means use the vertex position, transformed to camera space,
1951 * as the input texture coordinates for this stage's texture transformation. This
1952 * equates roughly to EYE_LINEAR
1955 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1956 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1957 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1958 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1959 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
1961 glMatrixMode(GL_MODELVIEW);
1964 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1965 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1966 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1967 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1970 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
1971 glEnable(GL_TEXTURE_GEN_S);
1972 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1973 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1974 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1975 glEnable(GL_TEXTURE_GEN_T);
1976 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1977 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1978 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1979 glEnable(GL_TEXTURE_GEN_R);
1980 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1981 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1982 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1986 case WINED3DTSS_TCI_CAMERASPACENORMAL:
1988 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1989 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1990 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1991 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1992 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1993 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
1995 glMatrixMode(GL_MODELVIEW);
1998 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1999 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2000 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2001 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2004 glEnable(GL_TEXTURE_GEN_S);
2005 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
2006 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2007 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2008 glEnable(GL_TEXTURE_GEN_T);
2009 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
2010 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2011 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2012 glEnable(GL_TEXTURE_GEN_R);
2013 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
2014 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2015 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2020 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
2022 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
2023 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
2024 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
2025 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
2026 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
2027 TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
2029 glMatrixMode(GL_MODELVIEW);
2032 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
2033 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2034 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2035 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2038 glEnable(GL_TEXTURE_GEN_S);
2039 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
2040 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2041 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2042 glEnable(GL_TEXTURE_GEN_T);
2043 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
2044 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2045 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2046 glEnable(GL_TEXTURE_GEN_R);
2047 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
2048 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2049 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2054 /* Unhandled types: */
2057 /* ? disable GL_TEXTURE_GEN_n ? */
2058 glDisable(GL_TEXTURE_GEN_S);
2059 glDisable(GL_TEXTURE_GEN_T);
2060 glDisable(GL_TEXTURE_GEN_R);
2061 glDisable(GL_TEXTURE_GEN_Q);
2062 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
2066 /* Update the texture matrix */
2067 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
2068 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
2071 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
2072 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
2073 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
2074 * and do all the things linked to it
2075 * TODO: Tidy that up to reload only the arrays of the changed unit
2077 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2079 unloadTexCoords(stateblock);
2080 loadTexCoords(stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
2084 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2085 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2091 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
2092 if(tmpvalue.f != 0.0) {
2093 FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
2097 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2098 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2104 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
2105 if(tmpvalue.f != 0.0) {
2106 FIXME("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
2110 static void tex_resultarg(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2111 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2113 if(stage >= GL_LIMITS(texture_stages)) {
2117 if(stateblock->textureState[stage][WINED3DTSS_RESULTARG] != WINED3DTA_CURRENT) {
2118 FIXME("WINED3DTSS_RESULTARG not supported yet\n");
2122 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2123 DWORD sampler = state - STATE_SAMPLER(0);
2124 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2130 TRACE("Sampler: %d\n", sampler);
2131 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
2132 * only has to bind textures and set the per texture states
2135 if (mapped_stage == -1) {
2136 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
2140 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2141 if (mapped_stage >= GL_LIMITS(combined_samplers)) {
2144 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2145 checkGLcall("glActiveTextureARB");
2146 } else if (sampler > 0) {
2147 /* We can't do anything here */
2148 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2152 if(stateblock->textures[sampler]) {
2153 BOOL texIsPow2 = FALSE;
2155 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
2156 * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
2157 * scaling is reapplied or removed, the texture matrix has to be reapplied
2159 if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
2160 if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
2161 if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
2162 ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
2165 } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
2166 if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
2171 if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
2172 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
2173 context->lastWasPow2Texture[sampler] = texIsPow2;
2177 IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
2178 IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
2180 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
2181 tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
2182 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
2183 GL_TEXTURE_LOD_BIAS_EXT,
2185 checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
2188 if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
2189 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
2190 /* Using a pixel shader? Verify the sampler types */
2192 /* Make sure that the texture dimensions are enabled. I don't have to disable the other
2193 * dimensions because the shader knows from which texture type to sample from. For the sake of
2194 * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
2195 * dimensions. This should make wrong sampling sources visible :-)
2197 glEnable(stateblock->textureDimensions[sampler]);
2198 checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
2199 } else if(sampler < stateblock->lowest_disabled_stage) {
2200 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
2201 activate_dimensions(sampler, stateblock, context);
2204 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
2205 /* If color keying is enabled update the alpha test, it depends on the existence
2206 * of a color key in stage 0
2208 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
2211 } else if(sampler < GL_LIMITS(texture_stages)) {
2212 if(sampler < stateblock->lowest_disabled_stage) {
2213 /* TODO: What should I do with pixel shaders here ??? */
2214 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
2215 activate_dimensions(sampler, stateblock, context);
2217 } /* Otherwise tex_colorop disables the stage */
2218 glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
2219 checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
2223 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2224 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2226 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
2227 * has an update pending
2229 if(isStateDirty(context, STATE_VDECL) ||
2230 isStateDirty(context, STATE_PIXELSHADER)) {
2234 device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
2237 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2238 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2239 BOOL use_pshader = use_ps(device);
2240 BOOL use_vshader = use_vs(device);
2241 BOOL update_fog = FALSE;
2245 if(!context->last_was_pshader) {
2246 /* Former draw without a pixel shader, some samplers
2247 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
2248 * make sure to enable them
2250 for(i=0; i < MAX_SAMPLERS; i++) {
2251 if(!isStateDirty(context, STATE_SAMPLER(i))) {
2252 sampler(STATE_SAMPLER(i), stateblock, context);
2257 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
2258 * if a different texture was bound. I don't have to do anything.
2262 /* Compile and bind the shader */
2263 IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
2265 /* Disabled the pixel shader - color ops weren't applied
2266 * while it was enabled, so re-apply them.
2268 for(i=0; i < MAX_TEXTURES; i++) {
2269 if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
2270 tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
2273 if(context->last_was_pshader)
2277 if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
2278 device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
2280 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
2281 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
2286 state_fog(state, stateblock, context);
2288 context->last_was_pshader = use_pshader;
2291 static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2292 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2294 if(stateblock->pixelShader && stage != 0 &&
2295 ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->needsbumpmat == stage) {
2296 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
2299 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
2300 !isStateDirty(context, STATE_PIXELSHADER)) {
2301 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
2305 if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2306 if(stage >= GL_LIMITS(texture_stages)) {
2307 WARN("Bump env matrix of unsupported stage set\n");
2308 } else if(GL_SUPPORT(ARB_MULTITEXTURE)) {
2309 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage));
2310 checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage))");
2312 GL_EXTCALL(glTexBumpParameterfvATI(GL_BUMP_ROT_MATRIX_ATI,
2313 (float *) &(stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00])));
2314 checkGLcall("glTexBumpParameterfvATI");
2316 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2317 /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to
2318 * offset the destination stage(always stage + 1 in d3d). In GL_NV_texture_shader, the bump
2319 * map offseting is done in the stage reading the bump mapped texture, and the perturbation
2320 * map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix
2321 * for stage + 1. Keep the nvrc tex unit mapping in mind too
2323 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage + 1];
2325 if(mapped_stage < GL_LIMITS(textures)) {
2326 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2327 checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage))");
2329 glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV,
2330 (float *) &(stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]));
2331 checkGLcall("glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat)\n");
2336 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2337 /* This function is called by transform_view below if the view matrix was changed too
2339 * Deliberately no check if the vertex declaration is dirty because the vdecl state
2340 * does not always update the world matrix, only on a switch between transformed
2341 * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
2342 * draw, but that should be rather rare and cheaper in total.
2344 glMatrixMode(GL_MODELVIEW);
2345 checkGLcall("glMatrixMode");
2347 if(context->last_was_rhw) {
2349 checkGLcall("glLoadIdentity()");
2351 /* In the general case, the view matrix is the identity matrix */
2352 if (stateblock->wineD3DDevice->view_ident) {
2353 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2354 checkGLcall("glLoadMatrixf");
2356 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2357 checkGLcall("glLoadMatrixf");
2358 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2359 checkGLcall("glMultMatrixf");
2364 static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2365 UINT index = state - STATE_CLIPPLANE(0);
2367 if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= GL_LIMITS(clipplanes)) {
2371 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2372 glMatrixMode(GL_MODELVIEW);
2374 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2376 TRACE("Clipplane [%f,%f,%f,%f]\n",
2377 stateblock->clipplane[index][0],
2378 stateblock->clipplane[index][1],
2379 stateblock->clipplane[index][2],
2380 stateblock->clipplane[index][3]);
2381 glClipPlane(GL_CLIP_PLANE0 + index, stateblock->clipplane[index]);
2382 checkGLcall("glClipPlane");
2387 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2388 UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
2390 TRACE("Setting world matrix %d\n", matrix);
2392 if(matrix >= GL_LIMITS(blends)) {
2393 WARN("Unsupported blend matrix set\n");
2395 } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2399 /* GL_MODELVIEW0_ARB: 0x1700
2400 * GL_MODELVIEW1_ARB: 0x0x850a
2401 * GL_MODELVIEW2_ARB: 0x8722
2402 * GL_MODELVIEW3_ARB: 0x8723
2404 * GL_MODELVIEW31_ARB: 0x873F
2406 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
2407 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
2409 glMatrixMode(glMat);
2410 checkGLcall("glMatrixMode(glMat)");
2412 /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
2413 * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
2415 if(stateblock->wineD3DDevice->view_ident) {
2416 glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
2417 checkGLcall("glLoadMatrixf")
2419 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2420 checkGLcall("glLoadMatrixf")
2421 glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
2422 checkGLcall("glMultMatrixf")
2426 static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2427 WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
2430 case WINED3DVBF_1WEIGHTS:
2431 case WINED3DVBF_2WEIGHTS:
2432 case WINED3DVBF_3WEIGHTS:
2433 if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
2434 glEnable(GL_VERTEX_BLEND_ARB);
2435 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
2437 /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
2438 * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
2440 GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1));
2442 if(!stateblock->wineD3DDevice->vertexBlendUsed) {
2444 for(i = 1; i < GL_LIMITS(blends); i++) {
2445 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) {
2446 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
2449 stateblock->wineD3DDevice->vertexBlendUsed = TRUE;
2452 /* TODO: Implement vertex blending in drawStridedSlow */
2453 FIXME("Vertex blending enabled, but not supported by hardware\n");
2457 case WINED3DVBF_DISABLE:
2458 case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */
2459 if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
2460 glDisable(GL_VERTEX_BLEND_ARB);
2461 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
2463 TRACE("Vertex blending disabled\n");
2467 case WINED3DVBF_TWEENING:
2468 /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have
2469 * vertex weights in the vertices?
2470 * For now we don't report that as supported, so a warn should suffice
2472 WARN("Tweening not supported yet\n");
2477 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2480 /* If we are changing the View matrix, reset the light and clipping planes to the new view
2481 * NOTE: We have to reset the positions even if the light/plane is not currently
2482 * enabled, since the call to enable it will not reset the position.
2483 * NOTE2: Apparently texture transforms do NOT need reapplying
2486 PLIGHTINFOEL *light = NULL;
2488 glMatrixMode(GL_MODELVIEW);
2489 checkGLcall("glMatrixMode(GL_MODELVIEW)");
2490 glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2491 checkGLcall("glLoadMatrixf(...)");
2493 /* Reset lights. TODO: Call light apply func */
2494 for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
2495 light = stateblock->activeLights[k];
2496 if(!light) continue;
2497 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
2498 checkGLcall("glLightfv posn");
2499 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
2500 checkGLcall("glLightfv dirn");
2503 /* Reset Clipping Planes */
2504 for (k = 0; k < GL_LIMITS(clipplanes); k++) {
2505 if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
2506 clipplane(STATE_CLIPPLANE(k), stateblock, context);
2510 if(context->last_was_rhw) {
2512 checkGLcall("glLoadIdentity()");
2513 /* No need to update the world matrix, the identity is fine */
2517 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
2518 * No need to do it here if the state is scheduled for update.
2520 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
2521 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2524 /* Avoid looping over a number of matrices if the app never used the functionality */
2525 if(stateblock->wineD3DDevice->vertexBlendUsed) {
2526 for(k = 1; k < GL_LIMITS(blends); k++) {
2527 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
2528 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
2534 static const GLfloat invymat[16] = {
2535 1.0f, 0.0f, 0.0f, 0.0f,
2536 0.0f, -1.0f, 0.0f, 0.0f,
2537 0.0f, 0.0f, 1.0f, 0.0f,
2538 0.0f, 0.0f, 0.0f, 1.0f};
2540 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2541 glMatrixMode(GL_PROJECTION);
2542 checkGLcall("glMatrixMode(GL_PROJECTION)");
2544 checkGLcall("glLoadIdentity");
2546 if(context->last_was_rhw) {
2547 double X, Y, height, width, minZ, maxZ;
2549 X = stateblock->viewport.X;
2550 Y = stateblock->viewport.Y;
2551 height = stateblock->viewport.Height;
2552 width = stateblock->viewport.Width;
2553 minZ = stateblock->viewport.MinZ;
2554 maxZ = stateblock->viewport.MaxZ;
2556 if(!stateblock->wineD3DDevice->untransformed) {
2557 /* Transformed vertices are supposed to bypass the whole transform pipeline including
2558 * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2559 * suppress depth clipping. This can be done because it is an orthogonal projection and
2560 * the Z coordinate does not affect the size of the primitives
2562 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2563 if(stateblock->wineD3DDevice->render_offscreen) {
2564 glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
2566 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2569 /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2570 * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2571 * unmodified to opengl.
2573 * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2574 * replacement shader.
2576 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2577 if(stateblock->wineD3DDevice->render_offscreen) {
2578 glOrtho(X, X + width, -Y, -Y - height, 1.0, -1.0);
2580 glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
2583 checkGLcall("glOrtho");
2585 /* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */
2586 glTranslatef(0.375, 0.375, 0);
2587 checkGLcall("glTranslatef(0.375, 0.375, 0)");
2588 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2589 * render everything upside down when rendering offscreen. */
2590 if (stateblock->wineD3DDevice->render_offscreen) {
2591 glMultMatrixf(invymat);
2592 checkGLcall("glMultMatrixf(invymat)");
2595 /* The rule is that the window coordinate 0 does not correspond to the
2596 beginning of the first pixel, but the center of the first pixel.
2597 As a consequence if you want to correctly draw one line exactly from
2598 the left to the right end of the viewport (with all matrices set to
2599 be identity), the x coords of both ends of the line would be not
2600 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2602 glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
2603 checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
2605 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2606 * render everything upside down when rendering offscreen. */
2607 if (stateblock->wineD3DDevice->render_offscreen) {
2608 glMultMatrixf(invymat);
2609 checkGLcall("glMultMatrixf(invymat)");
2611 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2612 checkGLcall("glLoadMatrixf");
2616 /* This should match any arrays loaded in loadVertexData.
2617 * stateblock impl is required for GL_SUPPORT
2618 * TODO: Only load / unload arrays if we have to.
2620 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2621 glDisableClientState(GL_VERTEX_ARRAY);
2622 glDisableClientState(GL_NORMAL_ARRAY);
2623 glDisableClientState(GL_COLOR_ARRAY);
2624 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2625 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2627 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2628 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
2629 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2630 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2632 unloadTexCoords(stateblock);
2635 /* This should match any arrays loaded in loadNumberedArrays
2636 * TODO: Only load / unload arrays if we have to.
2638 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2639 /* disable any attribs (this is the same for both GLSL and ARB modes) */
2643 /* Leave all the attribs disabled */
2644 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2645 /* MESA does not support it right not */
2646 if (glGetError() != GL_NO_ERROR)
2648 for (i = 0; i < maxAttribs; ++i) {
2649 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2650 checkGLcall("glDisableVertexAttribArrayARB(reg);");
2654 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2655 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2657 UINT *offset = stateblock->streamOffset;
2659 /* Default to no instancing */
2660 stateblock->wineD3DDevice->instancedDraw = FALSE;
2662 for (i = 0; i < MAX_ATTRIBS; i++) {
2664 if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2667 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
2668 if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) {
2669 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2670 stateblock->wineD3DDevice->instancedDraw = TRUE;
2674 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2676 if(strided->u.input[i].dwStride) {
2677 if(curVBO != strided->u.input[i].VBO) {
2678 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2679 checkGLcall("glBindBufferARB");
2680 curVBO = strided->u.input[i].VBO;
2682 GL_EXTCALL(glVertexAttribPointerARB(i,
2683 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2684 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2685 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2686 strided->u.input[i].dwStride,
2687 strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + offset[strided->u.input[i].streamNo]) );
2688 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2690 /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
2691 * set up the attribute statically. But we have to figure out the system memory address.
2693 BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
2694 if(strided->u.input[i].VBO) {
2695 IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2696 ptr += (long) vb->resource.allocatedMemory;
2698 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2700 switch(strided->u.input[i].dwType) {
2701 case WINED3DDECLTYPE_FLOAT1:
2702 GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
2704 case WINED3DDECLTYPE_FLOAT2:
2705 GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
2707 case WINED3DDECLTYPE_FLOAT3:
2708 GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
2710 case WINED3DDECLTYPE_FLOAT4:
2711 GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
2714 case WINED3DDECLTYPE_UBYTE4:
2715 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2717 case WINED3DDECLTYPE_UBYTE4N:
2718 case WINED3DDECLTYPE_D3DCOLOR:
2719 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2722 case WINED3DDECLTYPE_SHORT2:
2723 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2725 case WINED3DDECLTYPE_SHORT4:
2726 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2729 case WINED3DDECLTYPE_SHORT2N:
2731 GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
2732 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
2735 case WINED3DDECLTYPE_USHORT2N:
2737 GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
2738 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
2741 case WINED3DDECLTYPE_SHORT4N:
2742 GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
2744 case WINED3DDECLTYPE_USHORT4N:
2745 GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
2748 case WINED3DDECLTYPE_UDEC3:
2749 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
2750 /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
2752 case WINED3DDECLTYPE_DEC3N:
2753 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
2754 /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
2757 case WINED3DDECLTYPE_FLOAT16_2:
2758 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
2759 * byte float according to the IEEE standard
2761 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
2763 case WINED3DDECLTYPE_FLOAT16_4:
2764 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
2767 case WINED3DDECLTYPE_UNUSED:
2769 ERR("Unexpected declaration in stride 0 attributes\n");
2777 /* Used from 2 different functions, and too big to justify making it inlined */
2778 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
2779 UINT *offset = stateblock->streamOffset;
2780 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2782 TRACE("Using fast vertex array code\n");
2784 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
2785 stateblock->wineD3DDevice->instancedDraw = FALSE;
2787 /* Blend Data ---------------------------------------------- */
2788 if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
2789 (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
2791 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2792 TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2793 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2795 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
2796 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
2798 GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1));
2800 VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
2801 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
2802 sd->u.s.blendWeights.dwStride,
2803 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
2805 if(curVBO != sd->u.s.blendWeights.VBO) {
2806 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
2807 checkGLcall("glBindBufferARB");
2808 curVBO = sd->u.s.blendWeights.VBO;
2811 GL_EXTCALL(glWeightPointerARB)(
2812 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2813 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2814 sd->u.s.blendWeights.dwStride,
2815 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2817 checkGLcall("glWeightPointerARB");
2819 if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
2820 static BOOL showfixme = TRUE;
2822 FIXME("blendMatrixIndices support\n");
2826 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2827 /* FIXME("TODO\n");*/
2830 GL_EXTCALL(glVertexWeightPointerEXT)(
2831 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2832 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2833 sd->u.s.blendWeights.dwStride,
2834 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2835 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
2836 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2837 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2841 /* TODO: support blends in drawStridedSlow
2842 * No need to write a FIXME here, this is done after the general vertex decl decoding
2844 WARN("unsupported blending in openGl\n");
2847 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2848 static const GLbyte one = 1;
2849 GL_EXTCALL(glWeightbvARB(1, &one));
2850 checkGLcall("glWeightivARB(GL_LIMITS(blends), weights)");
2854 #if 0 /* FOG ----------------------------------------------*/
2855 if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
2857 if (GL_SUPPORT(EXT_FOG_COORD) {
2858 glEnableClientState(GL_FOG_COORDINATE_EXT);
2859 (GL_EXTCALL)(FogCoordPointerEXT)(
2860 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
2861 sd->u.s.fog.dwStride,
2862 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
2864 /* don't bother falling back to 'slow' as we don't support software FOG yet. */
2865 /* FIXME: fixme once */
2866 TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
2869 if (GL_SUPPRT(EXT_FOR_COORD) {
2870 /* make sure fog is disabled */
2871 glDisableClientState(GL_FOG_COORDINATE_EXT);
2876 #if 0 /* tangents ----------------------------------------------*/
2877 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
2878 sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2880 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2881 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
2882 glEnable(GL_TANGENT_ARRAY_EXT);
2883 (GL_EXTCALL)(TangentPointerEXT)(
2884 WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
2885 sd->u.s.tangent.dwStride,
2886 sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
2888 glDisable(GL_TANGENT_ARRAY_EXT);
2890 if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2891 glEnable(GL_BINORMAL_ARRAY_EXT);
2892 (GL_EXTCALL)(BinormalPointerEXT)(
2893 WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
2894 sd->u.s.binormal.dwStride,
2895 sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
2897 glDisable(GL_BINORMAL_ARRAY_EXT);
2901 /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
2902 /* FIXME: fixme once */
2903 TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
2906 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2907 /* make sure fog is disabled */
2908 glDisable(GL_TANGENT_ARRAY_EXT);
2909 glDisable(GL_BINORMAL_ARRAY_EXT);
2914 /* Point Size ----------------------------------------------*/
2915 if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
2917 /* no such functionality in the fixed function GL pipeline */
2918 TRACE("Cannot change ptSize here in openGl\n");
2919 /* TODO: Implement this function in using shaders if they are available */
2923 /* Vertex Pointers -----------------------------------------*/
2924 if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
2925 /* Note dwType == float3 or float4 == 2 or 3 */
2926 VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
2927 sd->u.s.position.dwStride,
2928 sd->u.s.position.dwType + 1,
2929 sd->u.s.position.lpData));
2931 if(curVBO != sd->u.s.position.VBO) {
2932 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
2933 checkGLcall("glBindBufferARB");
2934 curVBO = sd->u.s.position.VBO;
2937 /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
2938 handling for rhw mode should not impact screen position whereas in GL it does.
2939 This may result in very slightly distored textures in rhw mode, but
2940 a very minimal different. There's always the other option of
2941 fixing the view matrix to prevent w from having any effect
2943 This only applies to user pointer sources, in VBOs the vertices are fixed up
2945 if(sd->u.s.position.VBO == 0) {
2946 glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
2947 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2948 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2951 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
2952 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2953 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2955 checkGLcall("glVertexPointer(...)");
2956 glEnableClientState(GL_VERTEX_ARRAY);
2957 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
2960 /* Normals -------------------------------------------------*/
2961 if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
2962 /* Note dwType == float3 or float4 == 2 or 3 */
2963 VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
2964 sd->u.s.normal.dwStride,
2965 sd->u.s.normal.lpData));
2966 if(curVBO != sd->u.s.normal.VBO) {
2967 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
2968 checkGLcall("glBindBufferARB");
2969 curVBO = sd->u.s.normal.VBO;
2972 WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
2973 sd->u.s.normal.dwStride,
2974 sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
2975 checkGLcall("glNormalPointer(...)");
2976 glEnableClientState(GL_NORMAL_ARRAY);
2977 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
2980 glNormal3f(0, 0, 1);
2981 checkGLcall("glNormal3f(0, 0, 1)");
2984 /* Diffuse Colour --------------------------------------------*/
2985 /* WARNING: Data here MUST be in RGBA format, so cannot */
2986 /* go directly into fast mode from app pgm, because */
2987 /* directx requires data in BGRA format. */
2988 /* currently fixupVertices swizels the format, but this isn't */
2989 /* very practical when using VBOS */
2990 /* NOTE: Unless we write a vertex shader to swizel the colour */
2991 /* , or the user doesn't care and wants the speed advantage */
2993 if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
2994 /* Note dwType == float3 or float4 == 2 or 3 */
2995 VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2996 sd->u.s.diffuse.dwStride,
2997 sd->u.s.diffuse.lpData));
2999 if(curVBO != sd->u.s.diffuse.VBO) {
3000 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
3001 checkGLcall("glBindBufferARB");
3002 curVBO = sd->u.s.diffuse.VBO;
3004 glColorPointer(4, GL_UNSIGNED_BYTE,
3005 sd->u.s.diffuse.dwStride,
3006 sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
3007 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
3008 glEnableClientState(GL_COLOR_ARRAY);
3009 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
3012 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
3013 checkGLcall("glColor4f(1, 1, 1, 1)");
3016 /* Specular Colour ------------------------------------------*/
3017 if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
3018 TRACE("setting specular colour\n");
3019 /* Note dwType == float3 or float4 == 2 or 3 */
3020 VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
3021 sd->u.s.specular.dwStride,
3022 sd->u.s.specular.lpData));
3023 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3024 if(curVBO != sd->u.s.specular.VBO) {
3025 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
3026 checkGLcall("glBindBufferARB");
3027 curVBO = sd->u.s.specular.VBO;
3029 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
3030 sd->u.s.specular.dwStride,
3031 sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
3032 vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
3033 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
3034 vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
3037 /* Missing specular color is not critical, no warnings */
3038 VTRACE(("Specular colour is not supported in this GL implementation\n"));
3042 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3043 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
3044 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
3047 /* Missing specular color is not critical, no warnings */
3048 VTRACE(("Specular colour is not supported in this GL implementation\n"));
3052 /* Texture coords -------------------------------------------*/
3053 loadTexCoords(stateblock, sd, &curVBO);
3056 static inline void drawPrimitiveTraceDataLocations(
3057 WineDirect3DVertexStridedData *dataLocations) {
3059 /* Dump out what parts we have supplied */
3060 TRACE("Strided Data:\n");
3061 TRACE_STRIDED((dataLocations), position);
3062 TRACE_STRIDED((dataLocations), blendWeights);
3063 TRACE_STRIDED((dataLocations), blendMatrixIndices);
3064 TRACE_STRIDED((dataLocations), normal);
3065 TRACE_STRIDED((dataLocations), pSize);
3066 TRACE_STRIDED((dataLocations), diffuse);
3067 TRACE_STRIDED((dataLocations), specular);
3068 TRACE_STRIDED((dataLocations), texCoords[0]);
3069 TRACE_STRIDED((dataLocations), texCoords[1]);
3070 TRACE_STRIDED((dataLocations), texCoords[2]);
3071 TRACE_STRIDED((dataLocations), texCoords[3]);
3072 TRACE_STRIDED((dataLocations), texCoords[4]);
3073 TRACE_STRIDED((dataLocations), texCoords[5]);
3074 TRACE_STRIDED((dataLocations), texCoords[6]);
3075 TRACE_STRIDED((dataLocations), texCoords[7]);
3076 TRACE_STRIDED((dataLocations), position2);
3077 TRACE_STRIDED((dataLocations), normal2);
3078 TRACE_STRIDED((dataLocations), tangent);
3079 TRACE_STRIDED((dataLocations), binormal);
3080 TRACE_STRIDED((dataLocations), tessFactor);
3081 TRACE_STRIDED((dataLocations), fog);
3082 TRACE_STRIDED((dataLocations), depth);
3083 TRACE_STRIDED((dataLocations), sample);
3088 /* Helper for vertexdeclaration() */
3089 static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction, WineD3DContext *context) {
3090 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3092 WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
3094 if(device->up_strided) {
3095 /* Note: this is a ddraw fixed-function code path */
3096 TRACE("================ Strided Input ===================\n");
3097 memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
3100 drawPrimitiveTraceDataLocations(dataLocations);
3103 /* Note: This is a fixed function or shader codepath.
3104 * This means it must handle both types of strided data.
3105 * Shaders must go through here to zero the strided data, even if they
3106 * don't set any declaration at all
3108 TRACE("================ Vertex Declaration ===================\n");
3109 memset(dataLocations, 0, sizeof(*dataLocations));
3110 primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device,
3111 useVertexShaderFunction, dataLocations, &fixup);
3114 if (dataLocations->u.s.position_transformed) {
3115 useVertexShaderFunction = FALSE;
3118 /* Unload the old arrays before loading the new ones to get old junk out */
3119 if(context->numberedArraysLoaded) {
3120 unloadNumberedArrays(stateblock);
3121 context->numberedArraysLoaded = FALSE;
3123 if(context->namedArraysLoaded) {
3124 unloadVertexData(stateblock);
3125 context->namedArraysLoaded = FALSE;
3128 if(useVertexShaderFunction) {
3129 TRACE("Loading numbered arrays\n");
3130 loadNumberedArrays(stateblock, dataLocations);
3131 device->useDrawStridedSlow = FALSE;
3132 context->numberedArraysLoaded = TRUE;
3134 (dataLocations->u.s.pSize.lpData == NULL &&
3135 dataLocations->u.s.diffuse.lpData == NULL &&
3136 dataLocations->u.s.specular.lpData == NULL)) {
3137 /* Load the vertex data using named arrays */
3138 TRACE("Loading vertex data\n");
3139 loadVertexData(stateblock, dataLocations);
3140 device->useDrawStridedSlow = FALSE;
3141 context->namedArraysLoaded = TRUE;
3143 TRACE("Not loading vertex data\n");
3144 device->useDrawStridedSlow = TRUE;
3147 /* Generate some fixme's if unsupported functionality is being used */
3148 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
3149 /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
3150 if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
3151 FIXME("Tweening is only valid with vertex shaders\n");
3153 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
3154 FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
3156 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
3157 FIXME("Extended attributes are only valid with vertex shaders\n");
3159 #undef BUFFER_OR_DATA
3162 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3163 BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
3164 BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
3165 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
3167 /* Some stuff is in the device until we have per context tracking */
3168 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3169 BOOL wasrhw = context->last_was_rhw;
3171 /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
3172 * here simply check whether a shader was set, or the user disabled shaders
3174 if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
3175 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
3176 useVertexShaderFunction = TRUE;
3178 if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
3181 } else if(context->last_was_foggy_shader) {
3185 handleStreams(stateblock, useVertexShaderFunction, context);
3187 transformed = device->strided_streams.u.s.position_transformed;
3188 if (transformed) useVertexShaderFunction = FALSE;
3190 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
3194 /* Reapply lighting if it is not scheduled for reapplication already */
3195 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
3196 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
3200 context->last_was_rhw = TRUE;
3203 /* Untransformed, so relies on the view and projection matrices */
3204 context->last_was_rhw = FALSE;
3205 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
3206 device->untransformed = TRUE;
3208 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
3209 * Not needed as long as only hw shaders are supported
3212 /* This sets the shader output position correction constants.
3213 * TODO: Move to the viewport state
3215 if (useVertexShaderFunction) {
3216 device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
3220 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
3221 * off this function will be called again anyway to make sure they're properly set
3223 if(!useVertexShaderFunction) {
3224 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
3225 * or transformed / untransformed was switched
3227 if(wasrhw != context->last_was_rhw &&
3228 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
3229 !isStateDirty(context, STATE_VIEWPORT)) {
3230 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
3232 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
3235 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
3236 * this check will fail and the matrix not applied again. This is OK because a simple
3237 * world matrix change reapplies the matrix - These checks here are only to satisfy the
3238 * needs of the vertex declaration.
3240 * World and view matrix go into the same gl matrix, so only apply them when neither is
3243 if(transformed != wasrhw &&
3244 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
3245 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3246 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3249 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
3250 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
3253 if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
3254 state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
3257 /* We compile the shader here because we need the vertex declaration
3258 * in order to determine if we need to do any swizzling for D3DCOLOR
3259 * registers. If the shader is already compiled this call will do nothing. */
3260 IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
3262 if(!context->last_was_vshader) {
3264 static BOOL warned = FALSE;
3265 /* Disable all clip planes to get defined results on all drivers. See comment in the
3266 * state_clipping state handler
3268 for(i = 0; i < GL_LIMITS(clipplanes); i++) {
3269 glDisable(GL_CLIP_PLANE0 + i);
3270 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
3273 if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
3274 FIXME("Clipping not supported with vertex shaders\n");
3280 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
3283 if (!isStateDirty(context, STATE_PIXELSHADER)) {
3284 device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
3286 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
3287 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3291 context->last_was_vshader = useVertexShaderFunction;
3294 state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
3298 static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3299 glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
3300 checkGLcall("glDepthRange");
3301 /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
3303 if(stateblock->wineD3DDevice->render_offscreen) {
3304 glViewport(stateblock->viewport.X,
3305 stateblock->viewport.Y,
3306 stateblock->viewport.Width, stateblock->viewport.Height);
3308 glViewport(stateblock->viewport.X,
3309 (((IWineD3DSurfaceImpl *)stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height - (stateblock->viewport.Y + stateblock->viewport.Height)),
3310 stateblock->viewport.Width, stateblock->viewport.Height);
3313 checkGLcall("glViewport");
3315 stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
3316 stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
3317 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
3318 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
3323 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3324 UINT Index = state - STATE_ACTIVELIGHT(0);
3325 PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
3328 glDisable(GL_LIGHT0 + Index);
3329 checkGLcall("glDisable(GL_LIGHT0 + Index)");
3332 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
3334 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
3335 glMatrixMode(GL_MODELVIEW);
3337 glLoadMatrixf((float *)&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3340 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
3341 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
3342 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
3343 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
3344 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
3345 checkGLcall("glLightfv");
3348 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
3349 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
3350 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
3351 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
3352 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
3353 checkGLcall("glLightfv");
3356 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
3357 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
3358 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
3359 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
3360 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
3361 checkGLcall("glLightfv");
3363 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
3364 quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
3366 quad_att = 0; /* 0 or MAX? (0 seems to be ok) */
3369 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
3370 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
3371 * Attenuation0 to NaN and crashes in the gl lib
3374 switch (lightInfo->OriginalParms.Type) {
3375 case WINED3DLIGHT_POINT:
3377 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3378 checkGLcall("glLightfv");
3379 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3380 checkGLcall("glLightf");
3381 /* Attenuation - Are these right? guessing... */
3382 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
3383 checkGLcall("glLightf");
3384 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
3385 checkGLcall("glLightf");
3386 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3387 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3388 checkGLcall("glLightf");
3392 case WINED3DLIGHT_SPOT:
3394 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3395 checkGLcall("glLightfv");
3397 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
3398 checkGLcall("glLightfv");
3399 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
3400 checkGLcall("glLightf");
3401 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3402 checkGLcall("glLightf");
3403 /* Attenuation - Are these right? guessing... */
3404 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
3405 checkGLcall("glLightf");
3406 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
3407 checkGLcall("glLightf");
3408 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3409 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3410 checkGLcall("glLightf");
3414 case WINED3DLIGHT_DIRECTIONAL:
3416 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
3417 checkGLcall("glLightfv");
3418 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3419 checkGLcall("glLightf");
3420 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
3421 checkGLcall("glLightf");
3425 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
3428 /* Restore the modelview matrix */
3431 glEnable(GL_LIGHT0 + Index);
3432 checkGLcall("glEnable(GL_LIGHT0 + Index)");
3438 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3439 IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) stateblock->wineD3DDevice->swapchains[0];
3440 RECT *pRect = &stateblock->scissorRect;
3444 GetClientRect(swapchain->win_handle, &windowRect);
3445 /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
3446 * Warning2: Even in windowed mode the coords are relative to the window, not the screen
3448 winHeight = windowRect.bottom - windowRect.top;
3449 TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - winHeight,
3450 pRect->right - pRect->left, pRect->bottom - pRect->top);
3451 glScissor(pRect->left, winHeight - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
3452 checkGLcall("glScissor");
3455 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3456 if(GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
3457 if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
3458 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
3460 IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData;
3461 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo));
3466 const struct StateEntry StateTable[] =
3468 /* State name representative, apply function */
3469 { /* 0, Undefined */ 0, state_undefined },
3470 { /* 1, WINED3DRS_TEXTUREHANDLE */ 0 /* Handled in ddraw */, state_undefined },
3471 { /* 2, WINED3DRS_ANTIALIAS */ STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias },
3472 { /* 3, WINED3DRS_TEXTUREADDRESS */ 0 /* Handled in ddraw */, state_undefined },
3473 { /* 4, WINED3DRS_TEXTUREPERSPECTIVE */ STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective },
3474 { /* 5, WINED3DRS_WRAPU */ STATE_RENDER(WINED3DRS_WRAPU), state_wrapu },
3475 { /* 6, WINED3DRS_WRAPV */ STATE_RENDER(WINED3DRS_WRAPV), state_wrapv },
3476 { /* 7, WINED3DRS_ZENABLE */ STATE_RENDER(WINED3DRS_ZENABLE), state_zenable },
3477 { /* 8, WINED3DRS_FILLMODE */ STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode },
3478 { /* 9, WINED3DRS_SHADEMODE */ STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode },
3479 { /* 10, WINED3DRS_LINEPATTERN */ STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern },
3480 { /* 11, WINED3DRS_MONOENABLE */ STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable },
3481 { /* 12, WINED3DRS_ROP2 */ STATE_RENDER(WINED3DRS_ROP2), state_rop2 },
3482 { /* 13, WINED3DRS_PLANEMASK */ STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask },
3483 { /* 14, WINED3DRS_ZWRITEENABLE */ STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable },
3484 { /* 15, WINED3DRS_ALPHATESTENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3485 { /* 16, WINED3DRS_LASTPIXEL */ STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel },
3486 { /* 17, WINED3DRS_TEXTUREMAG */ 0 /* Handled in ddraw */, state_undefined },
3487 { /* 18, WINED3DRS_TEXTUREMIN */ 0 /* Handled in ddraw */, state_undefined },
3488 { /* 19, WINED3DRS_SRCBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3489 { /* 20, WINED3DRS_DESTBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3490 { /* 21, WINED3DRS_TEXTUREMAPBLEND */ 0 /* Handled in ddraw */, state_undefined },
3491 { /* 22, WINED3DRS_CULLMODE */ STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode },
3492 { /* 23, WINED3DRS_ZFUNC */ STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc },
3493 { /* 24, WINED3DRS_ALPHAREF */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3494 { /* 25, WINED3DRS_ALPHAFUNC */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3495 { /* 26, WINED3DRS_DITHERENABLE */ STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable },
3496 { /* 27, WINED3DRS_ALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3497 { /* 28, WINED3DRS_FOGENABLE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3498 { /* 29, WINED3DRS_SPECULARENABLE */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},
3499 { /* 30, WINED3DRS_ZVISIBLE */ 0 /* Not supported according to the msdn */, state_nogl },
3500 { /* 31, WINED3DRS_SUBPIXEL */ STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel },
3501 { /* 32, WINED3DRS_SUBPIXELX */ STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx },
3502 { /* 33, WINED3DRS_STIPPLEDALPHA */ STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha },
3503 { /* 34, WINED3DRS_FOGCOLOR */ STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor },
3504 { /* 35, WINED3DRS_FOGTABLEMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3505 { /* 36, WINED3DRS_FOGSTART */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3506 { /* 37, WINED3DRS_FOGEND */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3507 { /* 38, WINED3DRS_FOGDENSITY */ STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity },
3508 { /* 39, WINED3DRS_STIPPLEENABLE */ STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable },
3509 { /* 40, WINED3DRS_EDGEANTIALIAS */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3510 { /* 41, WINED3DRS_COLORKEYENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3511 { /* 42, undefined */ 0, state_undefined },
3512 { /* 43, WINED3DRS_BORDERCOLOR */ STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor },
3513 { /* 44, WINED3DRS_TEXTUREADDRESSU */ 0, /* Handled in ddraw */ state_undefined },
3514 { /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined },
3515 { /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias },
3516 { /* 47, WINED3DRS_ZBIAS */ STATE_RENDER(WINED3DRS_ZBIAS), state_zbias },
3517 { /* 48, WINED3DRS_RANGEFOGENABLE */ 0, state_nogl },
3518 { /* 49, WINED3DRS_ANISOTROPY */ STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy },
3519 { /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch },
3520 { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT */ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
3521 { /* 52, WINED3DRS_STENCILENABLE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3522 { /* 53, WINED3DRS_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3523 { /* 54, WINED3DRS_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3524 { /* 55, WINED3DRS_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3525 { /* 56, WINED3DRS_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3526 { /* 57, WINED3DRS_STENCILREF */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3527 { /* 58, WINED3DRS_STENCILMASK */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3528 { /* 59, WINED3DRS_STENCILWRITEMASK */ STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite },
3529 { /* 60, WINED3DRS_TEXTUREFACTOR */ STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor },
3530 { /* 61, Undefined */ 0, state_undefined },
3531 { /* 62, Undefined */ 0, state_undefined },
3532 { /* 63, Undefined */ 0, state_undefined },
3533 { /* 64, WINED3DRS_STIPPLEPATTERN00 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3534 { /* 65, WINED3DRS_STIPPLEPATTERN01 */ 0 /* Obsolete, should he handled by ddraw */, state_undefined },
3535 { /* 66, WINED3DRS_STIPPLEPATTERN02 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3536 { /* 67, WINED3DRS_STIPPLEPATTERN03 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3537 { /* 68, WINED3DRS_STIPPLEPATTERN04 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3538 { /* 69, WINED3DRS_STIPPLEPATTERN05 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3539 { /* 70, WINED3DRS_STIPPLEPATTERN06 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3540 { /* 71, WINED3DRS_STIPPLEPATTERN07 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3541 { /* 72, WINED3DRS_STIPPLEPATTERN08 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3542 { /* 73, WINED3DRS_STIPPLEPATTERN09 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3543 { /* 74, WINED3DRS_STIPPLEPATTERN10 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3544 { /* 75, WINED3DRS_STIPPLEPATTERN11 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3545 { /* 76, WINED3DRS_STIPPLEPATTERN12 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3546 { /* 77, WINED3DRS_STIPPLEPATTERN13 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3547 { /* 78, WINED3DRS_STIPPLEPATTERN14 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3548 { /* 79, WINED3DRS_STIPPLEPATTERN15 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3549 { /* 80, WINED3DRS_STIPPLEPATTERN16 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3550 { /* 81, WINED3DRS_STIPPLEPATTERN17 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3551 { /* 82, WINED3DRS_STIPPLEPATTERN18 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3552 { /* 83, WINED3DRS_STIPPLEPATTERN19 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3553 { /* 84, WINED3DRS_STIPPLEPATTERN20 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3554 { /* 85, WINED3DRS_STIPPLEPATTERN21 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3555 { /* 86, WINED3DRS_STIPPLEPATTERN22 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3556 { /* 87, WINED3DRS_STIPPLEPATTERN23 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3557 { /* 88, WINED3DRS_STIPPLEPATTERN24 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3558 { /* 89, WINED3DRS_STIPPLEPATTERN25 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3559 { /* 90, WINED3DRS_STIPPLEPATTERN26 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3560 { /* 91, WINED3DRS_STIPPLEPATTERN27 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3561 { /* 92, WINED3DRS_STIPPLEPATTERN28 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3562 { /* 93, WINED3DRS_STIPPLEPATTERN29 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3563 { /* 94, WINED3DRS_STIPPLEPATTERN30 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3564 { /* 95, WINED3DRS_STIPPLEPATTERN31 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3565 { /* 96, Undefined */ 0, state_undefined },
3566 { /* 97, Undefined */ 0, state_undefined },
3567 { /* 98, Undefined */ 0, state_undefined },
3568 { /* 99, Undefined */ 0, state_undefined },
3569 { /*100, Undefined */ 0, state_undefined },
3570 { /*101, Undefined */ 0, state_undefined },
3571 { /*102, Undefined */ 0, state_undefined },
3572 { /*103, Undefined */ 0, state_undefined },
3573 { /*104, Undefined */ 0, state_undefined },
3574 { /*105, Undefined */ 0, state_undefined },
3575 { /*106, Undefined */ 0, state_undefined },
3576 { /*107, Undefined */ 0, state_undefined },
3577 { /*108, Undefined */ 0, state_undefined },
3578 { /*109, Undefined */ 0, state_undefined },
3579 { /*110, Undefined */ 0, state_undefined },
3580 { /*111, Undefined */ 0, state_undefined },
3581 { /*112, Undefined */ 0, state_undefined },
3582 { /*113, Undefined */ 0, state_undefined },
3583 { /*114, Undefined */ 0, state_undefined },
3584 { /*115, Undefined */ 0, state_undefined },
3585 { /*116, Undefined */ 0, state_undefined },
3586 { /*117, Undefined */ 0, state_undefined },
3587 { /*118, Undefined */ 0, state_undefined },
3588 { /*119, Undefined */ 0, state_undefined },
3589 { /*120, Undefined */ 0, state_undefined },
3590 { /*121, Undefined */ 0, state_undefined },
3591 { /*122, Undefined */ 0, state_undefined },
3592 { /*123, Undefined */ 0, state_undefined },
3593 { /*124, Undefined */ 0, state_undefined },
3594 { /*125, Undefined */ 0, state_undefined },
3595 { /*126, Undefined */ 0, state_undefined },
3596 { /*127, Undefined */ 0, state_undefined },
3598 { /*128, WINED3DRS_WRAP0 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3599 { /*129, WINED3DRS_WRAP1 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3600 { /*130, WINED3DRS_WRAP2 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3601 { /*131, WINED3DRS_WRAP3 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3602 { /*132, WINED3DRS_WRAP4 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3603 { /*133, WINED3DRS_WRAP5 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3604 { /*134, WINED3DRS_WRAP6 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3605 { /*135, WINED3DRS_WRAP7 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3606 { /*136, WINED3DRS_CLIPPING */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3607 { /*137, WINED3DRS_LIGHTING */ STATE_RENDER(WINED3DRS_LIGHTING), state_lighting },
3608 { /*138, WINED3DRS_EXTENTS */ STATE_RENDER(WINED3DRS_EXTENTS), state_extents },
3609 { /*139, WINED3DRS_AMBIENT */ STATE_RENDER(WINED3DRS_AMBIENT), state_ambient },
3610 { /*140, WINED3DRS_FOGVERTEXMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3611 { /*141, WINED3DRS_COLORVERTEX */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3612 { /*142, WINED3DRS_LOCALVIEWER */ STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer },
3613 { /*143, WINED3DRS_NORMALIZENORMALS */ STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize },
3614 { /*144, WINED3DRS_COLORKEYBLENDENABLE */ STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend },
3615 { /*145, WINED3DRS_DIFFUSEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3616 { /*146, WINED3DRS_SPECULARMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3617 { /*147, WINED3DRS_AMBIENTMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3618 { /*148, WINED3DRS_EMISSIVEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3619 { /*149, Undefined */ 0, state_undefined },
3620 { /*150, Undefined */ 0, state_undefined },
3621 { /*151, WINED3DRS_VERTEXBLEND */ STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend },
3622 { /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3623 { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING */ 0, state_nogl },
3624 { /*154, WINED3DRS_POINTSIZE */ STATE_RENDER(WINED3DRS_POINTSIZE), state_psize },
3625 { /*155, WINED3DRS_POINTSIZE_MIN */ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin },
3626 { /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite },
3627 { /*157, WINED3DRS_POINTSCALEENABLE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3628 { /*158, WINED3DRS_POINTSCALE_A */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3629 { /*159, WINED3DRS_POINTSCALE_B */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3630 { /*160, WINED3DRS_POINTSCALE_C */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3631 { /*161, WINED3DRS_MULTISAMPLEANTIALIAS */ STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_multisampleaa },
3632 { /*162, WINED3DRS_MULTISAMPLEMASK */ STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask },
3633 { /*163, WINED3DRS_PATCHEDGESTYLE */ STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle},
3634 { /*164, WINED3DRS_PATCHSEGMENTS */ STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments },
3635 { /*165, WINED3DRS_DEBUGMONITORTOKEN */ STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_nogl },
3636 { /*166, WINED3DRS_POINTSIZE_MAX */ STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax },
3637 { /*167, WINED3DRS_INDEXEDVERTEXBLENDENABLE */ 0, state_nogl },
3638 { /*168, WINED3DRS_COLORWRITEENABLE */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3639 { /*169, Undefined */ 0, state_undefined },
3640 { /*170, WINED3DRS_TWEENFACTOR */ 0, state_nogl },
3641 { /*171, WINED3DRS_BLENDOP */ STATE_RENDER(WINED3DRS_BLENDOP), state_blendop },
3642 { /*172, WINED3DRS_POSITIONDEGREE */ STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree},
3643 { /*173, WINED3DRS_NORMALDEGREE */ STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree },
3644 /*172, WINED3DRS_POSITIONORDER */ /* Value assigned to 2 state names */
3645 /*173, WINED3DRS_NORMALORDER */ /* Value assigned to 2 state names */
3646 { /*174, WINED3DRS_SCISSORTESTENABLE */ STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor },
3647 { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3648 { /*176, WINED3DRS_ANTIALIASEDLINEENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3649 { /*177, undefined */ 0, state_undefined },
3650 { /*178, WINED3DRS_MINTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3651 { /*179, WINED3DRS_MAXTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3652 { /*180, WINED3DRS_ADAPTIVETESS_X */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3653 { /*181, WINED3DRS_ADAPTIVETESS_Y */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3654 { /*182, WINED3DRS_ADAPTIVETESS_Z */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3655 { /*183, WINED3DRS_ADAPTIVETESS_W */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3656 { /*184, WINED3DRS_ENABLEADAPTIVETESSELLATION */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3657 { /*185, WINED3DRS_TWOSIDEDSTENCILMODE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3658 { /*186, WINED3DRS_CCW_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3659 { /*187, WINED3DRS_CCW_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3660 { /*188, WINED3DRS_CCW_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3661 { /*189, WINED3DRS_CCW_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3662 { /*190, WINED3DRS_COLORWRITEENABLE1 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3663 { /*191, WINED3DRS_COLORWRITEENABLE2 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3664 { /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3665 { /*193, WINED3DRS_BLENDFACTOR */ STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor },
3666 { /*194, WINED3DRS_SRGBWRITEENABLE */ STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), state_srgbwrite },
3667 { /*195, WINED3DRS_DEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3668 { /*196, undefined */ 0, state_undefined },
3669 { /*197, undefined */ 0, state_undefined },
3670 { /*198, WINED3DRS_WRAP8 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3671 { /*199, WINED3DRS_WRAP9 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3672 { /*200, WINED3DRS_WRAP10 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3673 { /*201, WINED3DRS_WRAP11 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3674 { /*202, WINED3DRS_WRAP12 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3675 { /*203, WINED3DRS_WRAP13 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3676 { /*204, WINED3DRS_WRAP14 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3677 { /*205, WINED3DRS_WRAP15 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3678 { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_separateblend },
3679 { /*207, WINED3DRS_SRCBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_separateblend },
3680 { /*208, WINED3DRS_DESTBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_separateblend },
3681 { /*209, WINED3DRS_BLENDOPALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_separateblend },
3682 /* Texture stage states */
3683 { /*0, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3684 { /*0, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3685 { /*0, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3686 { /*0, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3687 { /*0, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3688 { /*0, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3689 { /*0, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3690 { /*0, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3691 { /*0, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3692 { /*0, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3693 { /*0, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3694 { /*0, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3695 { /*0, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3696 { /*0, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3697 { /*0, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3698 { /*0, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3699 { /*0, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3700 { /*0, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3701 { /*0, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3702 { /*0, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3703 { /*0, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3704 { /*0, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3705 { /*0, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3706 { /*0, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3707 { /*0, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3708 { /*0, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3709 { /*0, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3710 { /*0, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), tex_resultarg },
3711 { /*0, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3712 { /*0, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3713 { /*0, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3714 { /*0, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3716 { /*1, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3717 { /*1, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3718 { /*1, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3719 { /*1, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3720 { /*1, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3721 { /*1, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3722 { /*1, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3723 { /*1, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3724 { /*1, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3725 { /*1, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3726 { /*1, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3727 { /*1, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3728 { /*1, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3729 { /*1, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3730 { /*1, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3731 { /*1, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3732 { /*1, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3733 { /*1, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3734 { /*1, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3735 { /*1, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3736 { /*1, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3737 { /*1, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3738 { /*1, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3739 { /*1, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3740 { /*1, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3741 { /*1, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3742 { /*1, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3743 { /*1, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), tex_resultarg },
3744 { /*1, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3745 { /*1, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3746 { /*1, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3747 { /*1, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3749 { /*2, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3750 { /*2, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3751 { /*2, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3752 { /*2, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3753 { /*2, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3754 { /*2, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3755 { /*2, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3756 { /*2, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3757 { /*2, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3758 { /*2, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3759 { /*2, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3760 { /*2, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3761 { /*2, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3762 { /*2, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3763 { /*2, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3764 { /*2, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3765 { /*2, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3766 { /*2, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3767 { /*2, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3768 { /*2, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3769 { /*2, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3770 { /*2, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3771 { /*2, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3772 { /*2, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3773 { /*2, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3774 { /*2, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3775 { /*2, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3776 { /*2, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), tex_resultarg },
3777 { /*2, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3778 { /*2, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3779 { /*2, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3780 { /*2, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3782 { /*3, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3783 { /*3, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3784 { /*3, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3785 { /*3, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3786 { /*3, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3787 { /*3, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3788 { /*3, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3789 { /*3, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3790 { /*3, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3791 { /*3, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3792 { /*3, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3793 { /*3, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3794 { /*3, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3795 { /*3, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3796 { /*3, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3797 { /*3, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3798 { /*3, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3799 { /*3, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3800 { /*3, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3801 { /*3, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3802 { /*3, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3803 { /*3, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3804 { /*3, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3805 { /*3, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3806 { /*3, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3807 { /*3, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3808 { /*3, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3809 { /*3, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), tex_resultarg },
3810 { /*3, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3811 { /*3, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3812 { /*3, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3813 { /*3, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3815 { /*4, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3816 { /*4, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3817 { /*4, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3818 { /*4, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3819 { /*4, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3820 { /*4, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3821 { /*4, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3822 { /*4, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3823 { /*4, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3824 { /*4, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3825 { /*4, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3826 { /*4, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3827 { /*4, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3828 { /*4, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3829 { /*4, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3830 { /*4, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3831 { /*4, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3832 { /*4, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3833 { /*4, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3834 { /*4, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3835 { /*4, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3836 { /*4, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3837 { /*4, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3838 { /*4, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3839 { /*4, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3840 { /*4, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3841 { /*4, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3842 { /*4, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), tex_resultarg },
3843 { /*4, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3844 { /*4, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3845 { /*4, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3846 { /*4, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3848 { /*5, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3849 { /*5, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3850 { /*5, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3851 { /*5, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3852 { /*5, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3853 { /*5, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3854 { /*5, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3855 { /*5, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3856 { /*5, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3857 { /*5, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3858 { /*5, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3859 { /*5, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3860 { /*5, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3861 { /*5, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3862 { /*5, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3863 { /*5, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3864 { /*5, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3865 { /*5, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3866 { /*5, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3867 { /*5, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3868 { /*5, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3869 { /*5, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3870 { /*5, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3871 { /*5, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3872 { /*5, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3873 { /*5, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3874 { /*5, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3875 { /*5, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), tex_resultarg },
3876 { /*5, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3877 { /*5, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3878 { /*5, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3879 { /*5, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3881 { /*6, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3882 { /*6, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3883 { /*6, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3884 { /*6, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3885 { /*6, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3886 { /*6, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3887 { /*6, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3888 { /*6, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3889 { /*6, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3890 { /*6, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3891 { /*6, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3892 { /*6, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3893 { /*6, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3894 { /*6, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3895 { /*6, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3896 { /*6, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3897 { /*6, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3898 { /*6, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3899 { /*6, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3900 { /*6, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3901 { /*6, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3902 { /*6, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3903 { /*6, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3904 { /*6, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3905 { /*6, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3906 { /*6, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3907 { /*6, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3908 { /*6, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), tex_resultarg },
3909 { /*6, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3910 { /*6, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3911 { /*6, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3912 { /*6, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3914 { /*7, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3915 { /*7, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3916 { /*7, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3917 { /*7, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3918 { /*7, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3919 { /*7, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3920 { /*7, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3921 { /*7, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3922 { /*7, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3923 { /*7, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3924 { /*7, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3925 { /*7, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3926 { /*7, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3927 { /*7, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3928 { /*7, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3929 { /*7, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3930 { /*7, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3931 { /*7, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3932 { /*7, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3933 { /*7, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3934 { /*7, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3935 { /*7, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3936 { /*7, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3937 { /*7, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3938 { /*7, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3939 { /*7, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3940 { /*7, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3941 { /*7, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), tex_resultarg },
3942 { /*7, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3943 { /*7, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3944 { /*7, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3945 { /*7, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3946 /* Sampler states */
3947 { /* 0, Sampler 0 */ STATE_SAMPLER(0), sampler },
3948 { /* 1, Sampler 1 */ STATE_SAMPLER(1), sampler },
3949 { /* 2, Sampler 2 */ STATE_SAMPLER(2), sampler },
3950 { /* 3, Sampler 3 */ STATE_SAMPLER(3), sampler },
3951 { /* 4, Sampler 3 */ STATE_SAMPLER(4), sampler },
3952 { /* 5, Sampler 5 */ STATE_SAMPLER(5), sampler },
3953 { /* 6, Sampler 6 */ STATE_SAMPLER(6), sampler },
3954 { /* 7, Sampler 7 */ STATE_SAMPLER(7), sampler },
3955 { /* 8, Sampler 8 */ STATE_SAMPLER(8), sampler },
3956 { /* 9, Sampler 9 */ STATE_SAMPLER(9), sampler },
3957 { /*10, Sampler 10 */ STATE_SAMPLER(10), sampler },
3958 { /*11, Sampler 11 */ STATE_SAMPLER(11), sampler },
3959 { /*12, Sampler 12 */ STATE_SAMPLER(12), sampler },
3960 { /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
3961 { /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
3962 { /*15, Sampler 15 */ STATE_SAMPLER(15), sampler },
3964 { /* , Pixel Shader */ STATE_PIXELSHADER, pixelshader },
3965 /* Transform states follow */
3966 { /* 1, undefined */ 0, state_undefined },
3967 { /* 2, WINED3DTS_VIEW */ STATE_TRANSFORM(WINED3DTS_VIEW), transform_view },
3968 { /* 3, WINED3DTS_PROJECTION */ STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection},
3969 { /* 4, undefined */ 0, state_undefined },
3970 { /* 5, undefined */ 0, state_undefined },
3971 { /* 6, undefined */ 0, state_undefined },
3972 { /* 7, undefined */ 0, state_undefined },
3973 { /* 8, undefined */ 0, state_undefined },
3974 { /* 9, undefined */ 0, state_undefined },
3975 { /* 10, undefined */ 0, state_undefined },
3976 { /* 11, undefined */ 0, state_undefined },
3977 { /* 12, undefined */ 0, state_undefined },
3978 { /* 13, undefined */ 0, state_undefined },
3979 { /* 14, undefined */ 0, state_undefined },
3980 { /* 15, undefined */ 0, state_undefined },
3981 { /* 16, WINED3DTS_TEXTURE0 */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3982 { /* 17, WINED3DTS_TEXTURE1 */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3983 { /* 18, WINED3DTS_TEXTURE2 */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3984 { /* 19, WINED3DTS_TEXTURE3 */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3985 { /* 20, WINED3DTS_TEXTURE4 */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3986 { /* 21, WINED3DTS_TEXTURE5 */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3987 { /* 22, WINED3DTS_TEXTURE6 */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3988 { /* 23, WINED3DTS_TEXTURE7 */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3989 /* A huge gap between TEXTURE7 and WORLDMATRIX(0) :-( But entries are needed to catch then if a broken app sets them */
3990 { /* 24, undefined */ 0, state_undefined },
3991 { /* 25, undefined */ 0, state_undefined },
3992 { /* 26, undefined */ 0, state_undefined },
3993 { /* 27, undefined */ 0, state_undefined },
3994 { /* 28, undefined */ 0, state_undefined },
3995 { /* 29, undefined */ 0, state_undefined },
3996 { /* 30, undefined */ 0, state_undefined },
3997 { /* 31, undefined */ 0, state_undefined },
3998 { /* 32, undefined */ 0, state_undefined },
3999 { /* 33, undefined */ 0, state_undefined },
4000 { /* 34, undefined */ 0, state_undefined },
4001 { /* 35, undefined */ 0, state_undefined },
4002 { /* 36, undefined */ 0, state_undefined },
4003 { /* 37, undefined */ 0, state_undefined },
4004 { /* 38, undefined */ 0, state_undefined },
4005 { /* 39, undefined */ 0, state_undefined },
4006 { /* 40, undefined */ 0, state_undefined },
4007 { /* 41, undefined */ 0, state_undefined },
4008 { /* 42, undefined */ 0, state_undefined },
4009 { /* 43, undefined */ 0, state_undefined },
4010 { /* 44, undefined */ 0, state_undefined },
4011 { /* 45, undefined */ 0, state_undefined },
4012 { /* 46, undefined */ 0, state_undefined },
4013 { /* 47, undefined */ 0, state_undefined },
4014 { /* 48, undefined */ 0, state_undefined },
4015 { /* 49, undefined */ 0, state_undefined },
4016 { /* 50, undefined */ 0, state_undefined },
4017 { /* 51, undefined */ 0, state_undefined },
4018 { /* 52, undefined */ 0, state_undefined },
4019 { /* 53, undefined */ 0, state_undefined },
4020 { /* 54, undefined */ 0, state_undefined },
4021 { /* 55, undefined */ 0, state_undefined },
4022 { /* 56, undefined */ 0, state_undefined },
4023 { /* 57, undefined */ 0, state_undefined },
4024 { /* 58, undefined */ 0, state_undefined },
4025 { /* 59, undefined */ 0, state_undefined },
4026 { /* 60, undefined */ 0, state_undefined },
4027 { /* 61, undefined */ 0, state_undefined },
4028 { /* 62, undefined */ 0, state_undefined },
4029 { /* 63, undefined */ 0, state_undefined },
4030 { /* 64, undefined */ 0, state_undefined },
4031 { /* 65, undefined */ 0, state_undefined },
4032 { /* 66, undefined */ 0, state_undefined },
4033 { /* 67, undefined */ 0, state_undefined },
4034 { /* 68, undefined */ 0, state_undefined },
4035 { /* 69, undefined */ 0, state_undefined },
4036 { /* 70, undefined */ 0, state_undefined },
4037 { /* 71, undefined */ 0, state_undefined },
4038 { /* 72, undefined */ 0, state_undefined },
4039 { /* 73, undefined */ 0, state_undefined },
4040 { /* 74, undefined */ 0, state_undefined },
4041 { /* 75, undefined */ 0, state_undefined },
4042 { /* 76, undefined */ 0, state_undefined },
4043 { /* 77, undefined */ 0, state_undefined },
4044 { /* 78, undefined */ 0, state_undefined },
4045 { /* 79, undefined */ 0, state_undefined },
4046 { /* 80, undefined */ 0, state_undefined },
4047 { /* 81, undefined */ 0, state_undefined },
4048 { /* 82, undefined */ 0, state_undefined },
4049 { /* 83, undefined */ 0, state_undefined },
4050 { /* 84, undefined */ 0, state_undefined },
4051 { /* 85, undefined */ 0, state_undefined },
4052 { /* 86, undefined */ 0, state_undefined },
4053 { /* 87, undefined */ 0, state_undefined },
4054 { /* 88, undefined */ 0, state_undefined },
4055 { /* 89, undefined */ 0, state_undefined },
4056 { /* 90, undefined */ 0, state_undefined },
4057 { /* 91, undefined */ 0, state_undefined },
4058 { /* 92, undefined */ 0, state_undefined },
4059 { /* 93, undefined */ 0, state_undefined },
4060 { /* 94, undefined */ 0, state_undefined },
4061 { /* 95, undefined */ 0, state_undefined },
4062 { /* 96, undefined */ 0, state_undefined },
4063 { /* 97, undefined */ 0, state_undefined },
4064 { /* 98, undefined */ 0, state_undefined },
4065 { /* 99, undefined */ 0, state_undefined },
4066 { /*100, undefined */ 0, state_undefined },
4067 { /*101, undefined */ 0, state_undefined },
4068 { /*102, undefined */ 0, state_undefined },
4069 { /*103, undefined */ 0, state_undefined },
4070 { /*104, undefined */ 0, state_undefined },
4071 { /*105, undefined */ 0, state_undefined },
4072 { /*106, undefined */ 0, state_undefined },
4073 { /*107, undefined */ 0, state_undefined },
4074 { /*108, undefined */ 0, state_undefined },
4075 { /*109, undefined */ 0, state_undefined },
4076 { /*110, undefined */ 0, state_undefined },
4077 { /*111, undefined */ 0, state_undefined },
4078 { /*112, undefined */ 0, state_undefined },
4079 { /*113, undefined */ 0, state_undefined },
4080 { /*114, undefined */ 0, state_undefined },
4081 { /*115, undefined */ 0, state_undefined },
4082 { /*116, undefined */ 0, state_undefined },
4083 { /*117, undefined */ 0, state_undefined },
4084 { /*118, undefined */ 0, state_undefined },
4085 { /*119, undefined */ 0, state_undefined },
4086 { /*120, undefined */ 0, state_undefined },
4087 { /*121, undefined */ 0, state_undefined },
4088 { /*122, undefined */ 0, state_undefined },
4089 { /*123, undefined */ 0, state_undefined },
4090 { /*124, undefined */ 0, state_undefined },
4091 { /*125, undefined */ 0, state_undefined },
4092 { /*126, undefined */ 0, state_undefined },
4093 { /*127, undefined */ 0, state_undefined },
4094 { /*128, undefined */ 0, state_undefined },
4095 { /*129, undefined */ 0, state_undefined },
4096 { /*130, undefined */ 0, state_undefined },
4097 { /*131, undefined */ 0, state_undefined },
4098 { /*132, undefined */ 0, state_undefined },
4099 { /*133, undefined */ 0, state_undefined },
4100 { /*134, undefined */ 0, state_undefined },
4101 { /*135, undefined */ 0, state_undefined },
4102 { /*136, undefined */ 0, state_undefined },
4103 { /*137, undefined */ 0, state_undefined },
4104 { /*138, undefined */ 0, state_undefined },
4105 { /*139, undefined */ 0, state_undefined },
4106 { /*140, undefined */ 0, state_undefined },
4107 { /*141, undefined */ 0, state_undefined },
4108 { /*142, undefined */ 0, state_undefined },
4109 { /*143, undefined */ 0, state_undefined },
4110 { /*144, undefined */ 0, state_undefined },
4111 { /*145, undefined */ 0, state_undefined },
4112 { /*146, undefined */ 0, state_undefined },
4113 { /*147, undefined */ 0, state_undefined },
4114 { /*148, undefined */ 0, state_undefined },
4115 { /*149, undefined */ 0, state_undefined },
4116 { /*150, undefined */ 0, state_undefined },
4117 { /*151, undefined */ 0, state_undefined },
4118 { /*152, undefined */ 0, state_undefined },
4119 { /*153, undefined */ 0, state_undefined },
4120 { /*154, undefined */ 0, state_undefined },
4121 { /*155, undefined */ 0, state_undefined },
4122 { /*156, undefined */ 0, state_undefined },
4123 { /*157, undefined */ 0, state_undefined },
4124 { /*158, undefined */ 0, state_undefined },
4125 { /*159, undefined */ 0, state_undefined },
4126 { /*160, undefined */ 0, state_undefined },
4127 { /*161, undefined */ 0, state_undefined },
4128 { /*162, undefined */ 0, state_undefined },
4129 { /*163, undefined */ 0, state_undefined },
4130 { /*164, undefined */ 0, state_undefined },
4131 { /*165, undefined */ 0, state_undefined },
4132 { /*166, undefined */ 0, state_undefined },
4133 { /*167, undefined */ 0, state_undefined },
4134 { /*168, undefined */ 0, state_undefined },
4135 { /*169, undefined */ 0, state_undefined },
4136 { /*170, undefined */ 0, state_undefined },
4137 { /*171, undefined */ 0, state_undefined },
4138 { /*172, undefined */ 0, state_undefined },
4139 { /*173, undefined */ 0, state_undefined },
4140 { /*174, undefined */ 0, state_undefined },
4141 { /*175, undefined */ 0, state_undefined },
4142 { /*176, undefined */ 0, state_undefined },
4143 { /*177, undefined */ 0, state_undefined },
4144 { /*178, undefined */ 0, state_undefined },
4145 { /*179, undefined */ 0, state_undefined },
4146 { /*180, undefined */ 0, state_undefined },
4147 { /*181, undefined */ 0, state_undefined },
4148 { /*182, undefined */ 0, state_undefined },
4149 { /*183, undefined */ 0, state_undefined },
4150 { /*184, undefined */ 0, state_undefined },
4151 { /*185, undefined */ 0, state_undefined },
4152 { /*186, undefined */ 0, state_undefined },
4153 { /*187, undefined */ 0, state_undefined },
4154 { /*188, undefined */ 0, state_undefined },
4155 { /*189, undefined */ 0, state_undefined },
4156 { /*190, undefined */ 0, state_undefined },
4157 { /*191, undefined */ 0, state_undefined },
4158 { /*192, undefined */ 0, state_undefined },
4159 { /*193, undefined */ 0, state_undefined },
4160 { /*194, undefined */ 0, state_undefined },
4161 { /*195, undefined */ 0, state_undefined },
4162 { /*196, undefined */ 0, state_undefined },
4163 { /*197, undefined */ 0, state_undefined },
4164 { /*198, undefined */ 0, state_undefined },
4165 { /*199, undefined */ 0, state_undefined },
4166 { /*200, undefined */ 0, state_undefined },
4167 { /*201, undefined */ 0, state_undefined },
4168 { /*202, undefined */ 0, state_undefined },
4169 { /*203, undefined */ 0, state_undefined },
4170 { /*204, undefined */ 0, state_undefined },
4171 { /*205, undefined */ 0, state_undefined },
4172 { /*206, undefined */ 0, state_undefined },
4173 { /*207, undefined */ 0, state_undefined },
4174 { /*208, undefined */ 0, state_undefined },
4175 { /*209, undefined */ 0, state_undefined },
4176 { /*210, undefined */ 0, state_undefined },
4177 { /*211, undefined */ 0, state_undefined },
4178 { /*212, undefined */ 0, state_undefined },
4179 { /*213, undefined */ 0, state_undefined },
4180 { /*214, undefined */ 0, state_undefined },
4181 { /*215, undefined */ 0, state_undefined },
4182 { /*216, undefined */ 0, state_undefined },
4183 { /*217, undefined */ 0, state_undefined },
4184 { /*218, undefined */ 0, state_undefined },
4185 { /*219, undefined */ 0, state_undefined },
4186 { /*220, undefined */ 0, state_undefined },
4187 { /*221, undefined */ 0, state_undefined },
4188 { /*222, undefined */ 0, state_undefined },
4189 { /*223, undefined */ 0, state_undefined },
4190 { /*224, undefined */ 0, state_undefined },
4191 { /*225, undefined */ 0, state_undefined },
4192 { /*226, undefined */ 0, state_undefined },
4193 { /*227, undefined */ 0, state_undefined },
4194 { /*228, undefined */ 0, state_undefined },
4195 { /*229, undefined */ 0, state_undefined },
4196 { /*230, undefined */ 0, state_undefined },
4197 { /*231, undefined */ 0, state_undefined },
4198 { /*232, undefined */ 0, state_undefined },
4199 { /*233, undefined */ 0, state_undefined },
4200 { /*234, undefined */ 0, state_undefined },
4201 { /*235, undefined */ 0, state_undefined },
4202 { /*236, undefined */ 0, state_undefined },
4203 { /*237, undefined */ 0, state_undefined },
4204 { /*238, undefined */ 0, state_undefined },
4205 { /*239, undefined */ 0, state_undefined },
4206 { /*240, undefined */ 0, state_undefined },
4207 { /*241, undefined */ 0, state_undefined },
4208 { /*242, undefined */ 0, state_undefined },
4209 { /*243, undefined */ 0, state_undefined },
4210 { /*244, undefined */ 0, state_undefined },
4211 { /*245, undefined */ 0, state_undefined },
4212 { /*246, undefined */ 0, state_undefined },
4213 { /*247, undefined */ 0, state_undefined },
4214 { /*248, undefined */ 0, state_undefined },
4215 { /*249, undefined */ 0, state_undefined },
4216 { /*250, undefined */ 0, state_undefined },
4217 { /*251, undefined */ 0, state_undefined },
4218 { /*252, undefined */ 0, state_undefined },
4219 { /*253, undefined */ 0, state_undefined },
4220 { /*254, undefined */ 0, state_undefined },
4221 { /*255, undefined */ 0, state_undefined },
4223 { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), transform_world },
4224 { /*257, WINED3DTS_WORLDMATRIX(1) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)), transform_worldex },
4225 { /*258, WINED3DTS_WORLDMATRIX(2) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)), transform_worldex },
4226 { /*259, WINED3DTS_WORLDMATRIX(3) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)), transform_worldex },
4227 { /*260, WINED3DTS_WORLDMATRIX(4) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(4)), transform_worldex },
4228 { /*261, WINED3DTS_WORLDMATRIX(5) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(5)), transform_worldex },
4229 { /*262, WINED3DTS_WORLDMATRIX(6) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(6)), transform_worldex },
4230 { /*263, WINED3DTS_WORLDMATRIX(7) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(7)), transform_worldex },
4231 { /*264, WINED3DTS_WORLDMATRIX(8) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(8)), transform_worldex },
4232 { /*265, WINED3DTS_WORLDMATRIX(9) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(9)), transform_worldex },
4233 { /*266, WINED3DTS_WORLDMATRIX(10) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(10)), transform_worldex },
4234 { /*267, WINED3DTS_WORLDMATRIX(11) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(11)), transform_worldex },
4235 { /*268, WINED3DTS_WORLDMATRIX(12) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(12)), transform_worldex },
4236 { /*269, WINED3DTS_WORLDMATRIX(13) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(13)), transform_worldex },
4237 { /*270, WINED3DTS_WORLDMATRIX(14) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(14)), transform_worldex },
4238 { /*271, WINED3DTS_WORLDMATRIX(15) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(15)), transform_worldex },
4239 { /*272, WINED3DTS_WORLDMATRIX(16) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(16)), transform_worldex },
4240 { /*273, WINED3DTS_WORLDMATRIX(17) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(17)), transform_worldex },
4241 { /*274, WINED3DTS_WORLDMATRIX(18) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(18)), transform_worldex },
4242 { /*275, WINED3DTS_WORLDMATRIX(19) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(19)), transform_worldex },
4243 { /*276, WINED3DTS_WORLDMATRIX(20) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(20)), transform_worldex },
4244 { /*277, WINED3DTS_WORLDMATRIX(21) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(21)), transform_worldex },
4245 { /*278, WINED3DTS_WORLDMATRIX(22) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(22)), transform_worldex },
4246 { /*279, WINED3DTS_WORLDMATRIX(23) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(23)), transform_worldex },
4247 { /*280, WINED3DTS_WORLDMATRIX(24) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(24)), transform_worldex },
4248 { /*281, WINED3DTS_WORLDMATRIX(25) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(25)), transform_worldex },
4249 { /*282, WINED3DTS_WORLDMATRIX(26) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(26)), transform_worldex },
4250 { /*283, WINED3DTS_WORLDMATRIX(27) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(27)), transform_worldex },
4251 { /*284, WINED3DTS_WORLDMATRIX(28) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(28)), transform_worldex },
4252 { /*285, WINED3DTS_WORLDMATRIX(29) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(29)), transform_worldex },
4253 { /*286, WINED3DTS_WORLDMATRIX(30) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(30)), transform_worldex },
4254 { /*287, WINED3DTS_WORLDMATRIX(31) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(31)), transform_worldex },
4255 { /*288, WINED3DTS_WORLDMATRIX(32) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(32)), transform_worldex },
4256 { /*289, WINED3DTS_WORLDMATRIX(33) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(33)), transform_worldex },
4257 { /*290, WINED3DTS_WORLDMATRIX(34) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(34)), transform_worldex },
4258 { /*291, WINED3DTS_WORLDMATRIX(35) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(35)), transform_worldex },
4259 { /*292, WINED3DTS_WORLDMATRIX(36) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(36)), transform_worldex },
4260 { /*293, WINED3DTS_WORLDMATRIX(37) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(37)), transform_worldex },
4261 { /*294, WINED3DTS_WORLDMATRIX(38) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(38)), transform_worldex },
4262 { /*295, WINED3DTS_WORLDMATRIX(39) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(39)), transform_worldex },
4263 { /*296, WINED3DTS_WORLDMATRIX(40) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(40)), transform_worldex },
4264 { /*297, WINED3DTS_WORLDMATRIX(41) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(41)), transform_worldex },
4265 { /*298, WINED3DTS_WORLDMATRIX(42) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(42)), transform_worldex },
4266 { /*299, WINED3DTS_WORLDMATRIX(43) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(43)), transform_worldex },
4267 { /*300, WINED3DTS_WORLDMATRIX(44) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(44)), transform_worldex },
4268 { /*301, WINED3DTS_WORLDMATRIX(45) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(45)), transform_worldex },
4269 { /*302, WINED3DTS_WORLDMATRIX(46) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(46)), transform_worldex },
4270 { /*303, WINED3DTS_WORLDMATRIX(47) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(47)), transform_worldex },
4271 { /*304, WINED3DTS_WORLDMATRIX(48) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(48)), transform_worldex },
4272 { /*305, WINED3DTS_WORLDMATRIX(49) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(49)), transform_worldex },
4273 { /*306, WINED3DTS_WORLDMATRIX(50) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(50)), transform_worldex },
4274 { /*307, WINED3DTS_WORLDMATRIX(51) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(51)), transform_worldex },
4275 { /*308, WINED3DTS_WORLDMATRIX(52) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(52)), transform_worldex },
4276 { /*309, WINED3DTS_WORLDMATRIX(53) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(53)), transform_worldex },
4277 { /*310, WINED3DTS_WORLDMATRIX(54) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(54)), transform_worldex },
4278 { /*311, WINED3DTS_WORLDMATRIX(55) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(55)), transform_worldex },
4279 { /*312, WINED3DTS_WORLDMATRIX(56) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(56)), transform_worldex },
4280 { /*313, WINED3DTS_WORLDMATRIX(57) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(57)), transform_worldex },
4281 { /*314, WINED3DTS_WORLDMATRIX(58) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(58)), transform_worldex },
4282 { /*315, WINED3DTS_WORLDMATRIX(59) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(59)), transform_worldex },
4283 { /*316, WINED3DTS_WORLDMATRIX(60) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(60)), transform_worldex },
4284 { /*317, WINED3DTS_WORLDMATRIX(61) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(61)), transform_worldex },
4285 { /*318, WINED3DTS_WORLDMATRIX(62) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(62)), transform_worldex },
4286 { /*319, WINED3DTS_WORLDMATRIX(63) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(63)), transform_worldex },
4287 { /*320, WINED3DTS_WORLDMATRIX(64) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(64)), transform_worldex },
4288 { /*321, WINED3DTS_WORLDMATRIX(65) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(65)), transform_worldex },
4289 { /*322, WINED3DTS_WORLDMATRIX(66) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(66)), transform_worldex },
4290 { /*323, WINED3DTS_WORLDMATRIX(67) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(67)), transform_worldex },
4291 { /*324, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(68)), transform_worldex },
4292 { /*325, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(69)), transform_worldex },
4293 { /*326, WINED3DTS_WORLDMATRIX(70) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(70)), transform_worldex },
4294 { /*327, WINED3DTS_WORLDMATRIX(71) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(71)), transform_worldex },
4295 { /*328, WINED3DTS_WORLDMATRIX(72) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(72)), transform_worldex },
4296 { /*329, WINED3DTS_WORLDMATRIX(73) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(73)), transform_worldex },
4297 { /*330, WINED3DTS_WORLDMATRIX(74) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(74)), transform_worldex },
4298 { /*331, WINED3DTS_WORLDMATRIX(75) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(75)), transform_worldex },
4299 { /*332, WINED3DTS_WORLDMATRIX(76) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(76)), transform_worldex },
4300 { /*333, WINED3DTS_WORLDMATRIX(77) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(77)), transform_worldex },
4301 { /*334, WINED3DTS_WORLDMATRIX(78) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(78)), transform_worldex },
4302 { /*335, WINED3DTS_WORLDMATRIX(79) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(79)), transform_worldex },
4303 { /*336, WINED3DTS_WORLDMATRIX(80) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(80)), transform_worldex },
4304 { /*337, WINED3DTS_WORLDMATRIX(81) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(81)), transform_worldex },
4305 { /*338, WINED3DTS_WORLDMATRIX(82) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(82)), transform_worldex },
4306 { /*339, WINED3DTS_WORLDMATRIX(83) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(83)), transform_worldex },
4307 { /*340, WINED3DTS_WORLDMATRIX(84) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(84)), transform_worldex },
4308 { /*341, WINED3DTS_WORLDMATRIX(85) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(85)), transform_worldex },
4309 { /*341, WINED3DTS_WORLDMATRIX(86) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(86)), transform_worldex },
4310 { /*343, WINED3DTS_WORLDMATRIX(87) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(87)), transform_worldex },
4311 { /*344, WINED3DTS_WORLDMATRIX(88) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(88)), transform_worldex },
4312 { /*345, WINED3DTS_WORLDMATRIX(89) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(89)), transform_worldex },
4313 { /*346, WINED3DTS_WORLDMATRIX(90) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(90)), transform_worldex },
4314 { /*347, WINED3DTS_WORLDMATRIX(91) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(91)), transform_worldex },
4315 { /*348, WINED3DTS_WORLDMATRIX(92) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(92)), transform_worldex },
4316 { /*349, WINED3DTS_WORLDMATRIX(93) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(93)), transform_worldex },
4317 { /*350, WINED3DTS_WORLDMATRIX(94) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(94)), transform_worldex },
4318 { /*351, WINED3DTS_WORLDMATRIX(95) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(95)), transform_worldex },
4319 { /*352, WINED3DTS_WORLDMATRIX(96) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(96)), transform_worldex },
4320 { /*353, WINED3DTS_WORLDMATRIX(97) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(97)), transform_worldex },
4321 { /*354, WINED3DTS_WORLDMATRIX(98) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(98)), transform_worldex },
4322 { /*355, WINED3DTS_WORLDMATRIX(99) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(99)), transform_worldex },
4323 { /*356, WINED3DTS_WORLDMATRIX(100) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex },
4324 { /*357, WINED3DTS_WORLDMATRIX(101) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex },
4325 { /*358, WINED3DTS_WORLDMATRIX(102) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex },
4326 { /*359, WINED3DTS_WORLDMATRIX(103) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex },
4327 { /*360, WINED3DTS_WORLDMATRIX(104) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex },
4328 { /*361, WINED3DTS_WORLDMATRIX(105) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex },
4329 { /*362, WINED3DTS_WORLDMATRIX(106) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex },
4330 { /*363, WINED3DTS_WORLDMATRIX(107) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex },
4331 { /*364, WINED3DTS_WORLDMATRIX(108) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex },
4332 { /*365, WINED3DTS_WORLDMATRIX(109) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex },
4333 { /*366, WINED3DTS_WORLDMATRIX(110) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex },
4334 { /*367, WINED3DTS_WORLDMATRIX(111) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex },
4335 { /*368, WINED3DTS_WORLDMATRIX(112) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex },
4336 { /*369, WINED3DTS_WORLDMATRIX(113) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex },
4337 { /*370, WINED3DTS_WORLDMATRIX(114) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex },
4338 { /*371, WINED3DTS_WORLDMATRIX(115) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex },
4339 { /*372, WINED3DTS_WORLDMATRIX(116) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex },
4340 { /*373, WINED3DTS_WORLDMATRIX(117) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex },
4341 { /*374, WINED3DTS_WORLDMATRIX(118) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex },
4342 { /*375, WINED3DTS_WORLDMATRIX(119) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex },
4343 { /*376, WINED3DTS_WORLDMATRIX(120) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex },
4344 { /*377, WINED3DTS_WORLDMATRIX(121) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex },
4345 { /*378, WINED3DTS_WORLDMATRIX(122) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex },
4346 { /*379, WINED3DTS_WORLDMATRIX(123) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex },
4347 { /*380, WINED3DTS_WORLDMATRIX(124) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex },
4348 { /*381, WINED3DTS_WORLDMATRIX(125) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex },
4349 { /*382, WINED3DTS_WORLDMATRIX(126) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex },
4350 { /*383, WINED3DTS_WORLDMATRIX(127) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex },
4351 { /*384, WINED3DTS_WORLDMATRIX(128) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex },
4352 { /*385, WINED3DTS_WORLDMATRIX(129) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex },
4353 { /*386, WINED3DTS_WORLDMATRIX(130) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex },
4354 { /*387, WINED3DTS_WORLDMATRIX(131) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex },
4355 { /*388, WINED3DTS_WORLDMATRIX(132) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex },
4356 { /*389, WINED3DTS_WORLDMATRIX(133) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex },
4357 { /*390, WINED3DTS_WORLDMATRIX(134) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex },
4358 { /*391, WINED3DTS_WORLDMATRIX(135) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex },
4359 { /*392, WINED3DTS_WORLDMATRIX(136) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex },
4360 { /*393, WINED3DTS_WORLDMATRIX(137) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex },
4361 { /*394, WINED3DTS_WORLDMATRIX(138) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex },
4362 { /*395, WINED3DTS_WORLDMATRIX(139) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex },
4363 { /*396, WINED3DTS_WORLDMATRIX(140) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex },
4364 { /*397, WINED3DTS_WORLDMATRIX(141) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex },
4365 { /*398, WINED3DTS_WORLDMATRIX(142) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex },
4366 { /*399, WINED3DTS_WORLDMATRIX(143) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex },
4367 { /*400, WINED3DTS_WORLDMATRIX(144) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex },
4368 { /*401, WINED3DTS_WORLDMATRIX(145) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex },
4369 { /*402, WINED3DTS_WORLDMATRIX(146) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex },
4370 { /*403, WINED3DTS_WORLDMATRIX(147) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex },
4371 { /*404, WINED3DTS_WORLDMATRIX(148) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex },
4372 { /*405, WINED3DTS_WORLDMATRIX(149) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex },
4373 { /*406, WINED3DTS_WORLDMATRIX(150) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex },
4374 { /*407, WINED3DTS_WORLDMATRIX(151) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex },
4375 { /*408, WINED3DTS_WORLDMATRIX(152) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex },
4376 { /*409, WINED3DTS_WORLDMATRIX(153) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex },
4377 { /*410, WINED3DTS_WORLDMATRIX(154) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex },
4378 { /*411, WINED3DTS_WORLDMATRIX(155) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex },
4379 { /*412, WINED3DTS_WORLDMATRIX(156) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex },
4380 { /*413, WINED3DTS_WORLDMATRIX(157) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex },
4381 { /*414, WINED3DTS_WORLDMATRIX(158) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex },
4382 { /*415, WINED3DTS_WORLDMATRIX(159) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex },
4383 { /*416, WINED3DTS_WORLDMATRIX(160) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex },
4384 { /*417, WINED3DTS_WORLDMATRIX(161) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex },
4385 { /*418, WINED3DTS_WORLDMATRIX(162) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex },
4386 { /*419, WINED3DTS_WORLDMATRIX(163) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex },
4387 { /*420, WINED3DTS_WORLDMATRIX(164) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex },
4388 { /*421, WINED3DTS_WORLDMATRIX(165) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex },
4389 { /*422, WINED3DTS_WORLDMATRIX(166) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex },
4390 { /*423, WINED3DTS_WORLDMATRIX(167) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex },
4391 { /*424, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex },
4392 { /*425, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex },
4393 { /*426, WINED3DTS_WORLDMATRIX(170) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex },
4394 { /*427, WINED3DTS_WORLDMATRIX(171) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex },
4395 { /*428, WINED3DTS_WORLDMATRIX(172) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex },
4396 { /*429, WINED3DTS_WORLDMATRIX(173) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex },
4397 { /*430, WINED3DTS_WORLDMATRIX(174) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex },
4398 { /*431, WINED3DTS_WORLDMATRIX(175) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex },
4399 { /*432, WINED3DTS_WORLDMATRIX(176) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex },
4400 { /*433, WINED3DTS_WORLDMATRIX(177) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex },
4401 { /*434, WINED3DTS_WORLDMATRIX(178) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex },
4402 { /*435, WINED3DTS_WORLDMATRIX(179) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex },
4403 { /*436, WINED3DTS_WORLDMATRIX(180) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex },
4404 { /*437, WINED3DTS_WORLDMATRIX(181) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex },
4405 { /*438, WINED3DTS_WORLDMATRIX(182) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex },
4406 { /*439, WINED3DTS_WORLDMATRIX(183) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex },
4407 { /*440, WINED3DTS_WORLDMATRIX(184) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex },
4408 { /*441, WINED3DTS_WORLDMATRIX(185) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex },
4409 { /*441, WINED3DTS_WORLDMATRIX(186) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex },
4410 { /*443, WINED3DTS_WORLDMATRIX(187) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex },
4411 { /*444, WINED3DTS_WORLDMATRIX(188) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex },
4412 { /*445, WINED3DTS_WORLDMATRIX(189) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex },
4413 { /*446, WINED3DTS_WORLDMATRIX(190) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex },
4414 { /*447, WINED3DTS_WORLDMATRIX(191) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex },
4415 { /*448, WINED3DTS_WORLDMATRIX(192) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex },
4416 { /*449, WINED3DTS_WORLDMATRIX(193) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex },
4417 { /*450, WINED3DTS_WORLDMATRIX(194) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex },
4418 { /*451, WINED3DTS_WORLDMATRIX(195) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex },
4419 { /*452, WINED3DTS_WORLDMATRIX(196) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex },
4420 { /*453, WINED3DTS_WORLDMATRIX(197) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex },
4421 { /*454, WINED3DTS_WORLDMATRIX(198) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex },
4422 { /*455, WINED3DTS_WORLDMATRIX(199) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex },
4423 { /*356, WINED3DTS_WORLDMATRIX(200) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex },
4424 { /*457, WINED3DTS_WORLDMATRIX(201) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex },
4425 { /*458, WINED3DTS_WORLDMATRIX(202) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex },
4426 { /*459, WINED3DTS_WORLDMATRIX(203) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex },
4427 { /*460, WINED3DTS_WORLDMATRIX(204) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex },
4428 { /*461, WINED3DTS_WORLDMATRIX(205) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex },
4429 { /*462, WINED3DTS_WORLDMATRIX(206) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex },
4430 { /*463, WINED3DTS_WORLDMATRIX(207) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex },
4431 { /*464, WINED3DTS_WORLDMATRIX(208) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex },
4432 { /*465, WINED3DTS_WORLDMATRIX(209) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex },
4433 { /*466, WINED3DTS_WORLDMATRIX(210) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex },
4434 { /*467, WINED3DTS_WORLDMATRIX(211) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex },
4435 { /*468, WINED3DTS_WORLDMATRIX(212) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex },
4436 { /*469, WINED3DTS_WORLDMATRIX(213) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex },
4437 { /*470, WINED3DTS_WORLDMATRIX(214) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex },
4438 { /*471, WINED3DTS_WORLDMATRIX(215) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex },
4439 { /*472, WINED3DTS_WORLDMATRIX(216) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex },
4440 { /*473, WINED3DTS_WORLDMATRIX(217) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex },
4441 { /*474, WINED3DTS_WORLDMATRIX(218) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex },
4442 { /*475, WINED3DTS_WORLDMATRIX(219) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex },
4443 { /*476, WINED3DTS_WORLDMATRIX(220) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex },
4444 { /*477, WINED3DTS_WORLDMATRIX(221) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex },
4445 { /*478, WINED3DTS_WORLDMATRIX(222) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex },
4446 { /*479, WINED3DTS_WORLDMATRIX(223) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex },
4447 { /*480, WINED3DTS_WORLDMATRIX(224) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex },
4448 { /*481, WINED3DTS_WORLDMATRIX(225) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex },
4449 { /*482, WINED3DTS_WORLDMATRIX(226) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex },
4450 { /*483, WINED3DTS_WORLDMATRIX(227) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex },
4451 { /*484, WINED3DTS_WORLDMATRIX(228) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex },
4452 { /*485, WINED3DTS_WORLDMATRIX(229) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex },
4453 { /*486, WINED3DTS_WORLDMATRIX(230) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex },
4454 { /*487, WINED3DTS_WORLDMATRIX(231) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex },
4455 { /*488, WINED3DTS_WORLDMATRIX(232) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex },
4456 { /*489, WINED3DTS_WORLDMATRIX(233) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex },
4457 { /*490, WINED3DTS_WORLDMATRIX(234) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex },
4458 { /*491, WINED3DTS_WORLDMATRIX(235) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex },
4459 { /*492, WINED3DTS_WORLDMATRIX(236) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex },
4460 { /*493, WINED3DTS_WORLDMATRIX(237) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex },
4461 { /*494, WINED3DTS_WORLDMATRIX(238) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex },
4462 { /*495, WINED3DTS_WORLDMATRIX(239) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex },
4463 { /*496, WINED3DTS_WORLDMATRIX(240) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex },
4464 { /*497, WINED3DTS_WORLDMATRIX(241) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex },
4465 { /*498, WINED3DTS_WORLDMATRIX(242) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex },
4466 { /*499, WINED3DTS_WORLDMATRIX(243) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex },
4467 { /*500, WINED3DTS_WORLDMATRIX(244) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex },
4468 { /*501, WINED3DTS_WORLDMATRIX(245) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex },
4469 { /*502, WINED3DTS_WORLDMATRIX(246) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex },
4470 { /*503, WINED3DTS_WORLDMATRIX(247) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex },
4471 { /*504, WINED3DTS_WORLDMATRIX(248) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex },
4472 { /*505, WINED3DTS_WORLDMATRIX(249) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex },
4473 { /*506, WINED3DTS_WORLDMATRIX(250) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex },
4474 { /*507, WINED3DTS_WORLDMATRIX(251) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex },
4475 { /*508, WINED3DTS_WORLDMATRIX(252) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex },
4476 { /*509, WINED3DTS_WORLDMATRIX(253) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex },
4477 { /*510, WINED3DTS_WORLDMATRIX(254) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex },
4478 { /*511, WINED3DTS_WORLDMATRIX(255) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex },
4479 /* Various Vertex states follow */
4480 { /* , STATE_STREAMSRC */ STATE_VDECL, vertexdeclaration },
4481 { /* , STATE_INDEXBUFFER */ STATE_INDEXBUFFER, indexbuffer },
4482 { /* , STATE_VDECL */ STATE_VDECL, vertexdeclaration },
4483 { /* , STATE_VSHADER */ STATE_VDECL, vertexdeclaration },
4484 { /* , STATE_VIEWPORT */ STATE_VIEWPORT, viewport },
4485 { /* , STATE_VERTEXSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4486 { /* , STATE_PIXELSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4488 { /* , STATE_ACTIVELIGHT(0) */ STATE_ACTIVELIGHT(0), light },
4489 { /* , STATE_ACTIVELIGHT(1) */ STATE_ACTIVELIGHT(1), light },
4490 { /* , STATE_ACTIVELIGHT(2) */ STATE_ACTIVELIGHT(2), light },
4491 { /* , STATE_ACTIVELIGHT(3) */ STATE_ACTIVELIGHT(3), light },
4492 { /* , STATE_ACTIVELIGHT(4) */ STATE_ACTIVELIGHT(4), light },
4493 { /* , STATE_ACTIVELIGHT(5) */ STATE_ACTIVELIGHT(5), light },
4494 { /* , STATE_ACTIVELIGHT(6) */ STATE_ACTIVELIGHT(6), light },
4495 { /* , STATE_ACTIVELIGHT(7) */ STATE_ACTIVELIGHT(7), light },
4497 { /* Scissor rect */ STATE_SCISSORRECT, scissorrect },
4499 { /* STATE_CLIPPLANE(0) */ STATE_CLIPPLANE(0), clipplane },
4500 { /* STATE_CLIPPLANE(1) */ STATE_CLIPPLANE(1), clipplane },
4501 { /* STATE_CLIPPLANE(2) */ STATE_CLIPPLANE(2), clipplane },
4502 { /* STATE_CLIPPLANE(3) */ STATE_CLIPPLANE(3), clipplane },
4503 { /* STATE_CLIPPLANE(4) */ STATE_CLIPPLANE(4), clipplane },
4504 { /* STATE_CLIPPLANE(5) */ STATE_CLIPPLANE(5), clipplane },
4505 { /* STATE_CLIPPLANE(6) */ STATE_CLIPPLANE(6), clipplane },
4506 { /* STATE_CLIPPLANE(7) */ STATE_CLIPPLANE(7), clipplane },
4507 { /* STATE_CLIPPLANE(8) */ STATE_CLIPPLANE(8), clipplane },
4508 { /* STATE_CLIPPLANE(9) */ STATE_CLIPPLANE(9), clipplane },
4509 { /* STATE_CLIPPLANE(10) */ STATE_CLIPPLANE(10), clipplane },
4510 { /* STATE_CLIPPLANE(11) */ STATE_CLIPPLANE(11), clipplane },
4511 { /* STATE_CLIPPLANE(12) */ STATE_CLIPPLANE(12), clipplane },
4512 { /* STATE_CLIPPLANE(13) */ STATE_CLIPPLANE(13), clipplane },
4513 { /* STATE_CLIPPLANE(14) */ STATE_CLIPPLANE(14), clipplane },
4514 { /* STATE_CLIPPLANE(15) */ STATE_CLIPPLANE(15), clipplane },
4515 { /* STATE_CLIPPLANE(16) */ STATE_CLIPPLANE(16), clipplane },
4516 { /* STATE_CLIPPLANE(17) */ STATE_CLIPPLANE(17), clipplane },
4517 { /* STATE_CLIPPLANE(18) */ STATE_CLIPPLANE(18), clipplane },
4518 { /* STATE_CLIPPLANE(19) */ STATE_CLIPPLANE(19), clipplane },
4519 { /* STATE_CLIPPLANE(20) */ STATE_CLIPPLANE(20), clipplane },
4520 { /* STATE_CLIPPLANE(21) */ STATE_CLIPPLANE(21), clipplane },
4521 { /* STATE_CLIPPLANE(22) */ STATE_CLIPPLANE(22), clipplane },
4522 { /* STATE_CLIPPLANE(23) */ STATE_CLIPPLANE(23), clipplane },
4523 { /* STATE_CLIPPLANE(24) */ STATE_CLIPPLANE(24), clipplane },
4524 { /* STATE_CLIPPLANE(25) */ STATE_CLIPPLANE(25), clipplane },
4525 { /* STATE_CLIPPLANE(26) */ STATE_CLIPPLANE(26), clipplane },
4526 { /* STATE_CLIPPLANE(27) */ STATE_CLIPPLANE(27), clipplane },
4527 { /* STATE_CLIPPLANE(28) */ STATE_CLIPPLANE(28), clipplane },
4528 { /* STATE_CLIPPLANE(29) */ STATE_CLIPPLANE(29), clipplane },
4529 { /* STATE_CLIPPLANE(30) */ STATE_CLIPPLANE(30), clipplane },
4530 { /* STATE_CLIPPLANE(31) */ STATE_CLIPPLANE(31), clipplane },
4532 { /* STATE_MATERIAL */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},