- some fixes in CreateDevice init
[wine/testsucceed.git] / dlls / d3d8 / device.c
blob7ad03ccc25511fd377e9a69598c1296ecfecc22b
1 /*
2 * IDirect3DDevice8 implementation
4 * Copyright 2002 Jason Edmeades
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <math.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winuser.h"
25 #include "wingdi.h"
26 #include "wine/debug.h"
28 #include "d3d8_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32 static VERTEXSHADER8* VertexShaders[64];
33 static PIXELSHADER8* PixelShaders[64];
35 /* CreateVertexShader can return > 0xFFFF */
36 #define VS_HIGHESTFIXEDFXF 0xF0000000
38 /* Used for CreateStateBlock */
39 #define NUM_SAVEDPIXELSTATES_R 38
40 #define NUM_SAVEDPIXELSTATES_T 27
41 #define NUM_SAVEDVERTEXSTATES_R 33
42 #define NUM_SAVEDVERTEXSTATES_T 2
45 * Utility functions or macros
47 #define conv_mat(mat,gl_mat) \
48 { \
49 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
50 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
51 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
52 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
53 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
57 * Globals
59 extern DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R];
60 extern DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T];
61 extern DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R];
62 extern DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T];
64 static const float idmatrix[16] = {
65 1.0, 0.0, 0.0, 0.0,
66 0.0, 1.0, 0.0, 0.0,
67 0.0, 0.0, 1.0, 0.0,
68 0.0, 0.0, 0.0, 1.0
71 /* Routine common to the draw primitive and draw indexed primitive routines
72 Doesnt use gl pointer arrays as I dont believe we can support the blending
73 coordinates that way. */
75 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
76 int PrimitiveType,
77 long NumPrimitives,
78 BOOL isIndexed,
80 /* For Both:*/
81 D3DFORMAT fvf,
82 const void *vertexBufData,
84 /* for Indexed: */
85 long StartVertexIndex,
86 long StartIdx,
87 short idxBytes,
88 const void *idxData) {
90 int vx_index;
91 int NumVertexes = NumPrimitives;
93 ICOM_THIS(IDirect3DDevice8Impl,iface);
95 /* Dont understand how to handle multiple streams, but if a fixed
96 FVF is passed in rather than a handle, it must use stream 0 */
98 if (This->StateBlock.VertexShader > VS_HIGHESTFIXEDFXF) {
99 FIXME("Cant handle created shaders yet\n");
100 return;
101 } else {
103 int skip = This->StateBlock.stream_stride[0];
105 BOOL normal;
106 BOOL isRHW;
107 BOOL isPtSize;
108 BOOL isDiffuse;
109 BOOL isSpecular;
110 int numTextures;
111 int textureNo;
112 const void *curVtx = NULL;
113 const short *pIdxBufS = NULL;
114 const long *pIdxBufL = NULL;
115 const void *curPos;
116 BOOL isLightingOn = FALSE;
118 float x=0.0, y=0.0, z=0.0; /* x,y,z coordinates */
119 float nx=0.0, ny=0.0, nz=0.0; /* normal x,y,z coordinates */
120 float rhw=0.0; /* rhw */
121 float ptSize=0.0; /* Point size */
122 DWORD diffuseColor=0; /* Diffusre Color */
123 DWORD specularColor=0; /* Specular Color */
125 ENTER_GL();
127 if (isIndexed) {
128 if (idxBytes == 2) pIdxBufS = (short *) idxData;
129 else pIdxBufL = (long *) idxData;
132 /* Check vertex formats expected ? */
133 normal = fvf & D3DFVF_NORMAL;
134 isRHW = fvf & D3DFVF_XYZRHW;
135 /*numBlends = 5 - ((~fvf) & 0xe);*/ /* There must be a simpler way? */
136 isPtSize = fvf & D3DFVF_PSIZE;
137 isDiffuse = fvf & D3DFVF_DIFFUSE;
138 isSpecular = fvf & D3DFVF_SPECULAR;
139 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
141 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d)\n",
142 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures);
144 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
145 set by the appropriate render state */
146 if (!normal) {
147 isLightingOn = glIsEnabled(GL_LIGHTING);
148 glDisable(GL_LIGHTING);
149 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
153 if (isRHW) {
155 double height, width, minZ, maxZ;
158 * Already transformed vertex do not need transform
159 * matrices. Reset all matrices to identity.
160 * Leave the default matrix in world mode.
162 glMatrixMode(GL_PROJECTION);
163 checkGLcall("glMatrixMode");
164 glLoadIdentity();
165 checkGLcall("glLoadIdentity");
166 glMatrixMode(GL_MODELVIEW);
167 checkGLcall("glMatrixMode");
168 glLoadIdentity();
169 checkGLcall("glLoadIdentity");
170 height = This->StateBlock.viewport.Height;
171 width = This->StateBlock.viewport.Width;
172 minZ = This->StateBlock.viewport.MinZ;
173 maxZ = This->StateBlock.viewport.MaxZ;
174 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
175 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
176 checkGLcall("glOrtho");
178 } else {
179 glMatrixMode(GL_PROJECTION);
180 checkGLcall("glMatrixMode");
181 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
182 checkGLcall("glLoadMatrixf");
184 glMatrixMode(GL_MODELVIEW);
185 checkGLcall("glMatrixMode");
186 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
187 checkGLcall("glLoadMatrixf");
188 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
189 checkGLcall("glMultMatrixf");
192 /* Set OpenGL to the appropriate Primitive Type */
193 switch (PrimitiveType) {
194 case D3DPT_POINTLIST:
195 TRACE("glBegin, Start POINTS\n");
196 glBegin(GL_POINTS);
197 NumVertexes = NumPrimitives;
198 break;
200 case D3DPT_LINELIST:
201 TRACE("glBegin, Start LINES\n");
202 glBegin(GL_LINES);
203 NumVertexes = NumPrimitives * 2;
204 break;
206 case D3DPT_LINESTRIP:
207 TRACE("glBegin, Start LINE_STRIP\n");
208 glBegin(GL_LINE_STRIP);
209 NumVertexes = NumPrimitives + 1;
210 break;
212 case D3DPT_TRIANGLELIST:
213 TRACE("glBegin, Start TRIANGLES\n");
214 glBegin(GL_TRIANGLES);
215 NumVertexes = NumPrimitives * 3;
216 break;
218 case D3DPT_TRIANGLESTRIP:
219 TRACE("glBegin, Start TRIANGLE_STRIP\n");
220 glBegin(GL_TRIANGLE_STRIP);
221 NumVertexes = NumPrimitives + 2;
222 break;
224 case D3DPT_TRIANGLEFAN:
225 TRACE("glBegin, Start TRIANGLE_FAN\n");
226 glBegin(GL_TRIANGLE_FAN);
227 NumVertexes = NumPrimitives + 2;
228 break;
230 default:
231 FIXME("Unhandled primitive\n");
232 break;
236 /* Draw the primitives */
237 curVtx = vertexBufData + (StartVertexIndex * skip);
239 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
241 if (!isIndexed) {
242 curPos = curVtx;
243 } else {
244 if (idxBytes == 2) {
245 TRACE("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index]));
246 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
247 } else {
248 TRACE("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index]));
249 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
253 /* Work through the vertex buffer */
254 x = *(float *)curPos;
255 curPos = curPos + sizeof(float);
256 y = *(float *)curPos;
257 curPos = curPos + sizeof(float);
258 z = *(float *)curPos;
259 curPos = curPos + sizeof(float);
260 TRACE("x,y,z=%f,%f,%f\n", x,y,z);
262 /* RHW follows, only if transformed */
263 if (isRHW) {
264 rhw = *(float *)curPos;
265 curPos = curPos + sizeof(float);
266 TRACE("rhw=%f\n", rhw);
270 /* FIXME: Skip Blending data */
272 /* Vertex Normal Data (untransformed only) */
273 if (normal) {
274 nx = *(float *)curPos;
275 curPos = curPos + sizeof(float);
276 ny = *(float *)curPos;
277 curPos = curPos + sizeof(float);
278 nz = *(float *)curPos;
279 curPos = curPos + sizeof(float);
280 TRACE("nx,ny,nz=%f,%f,%f\n", nx,ny,nz);
283 if (isPtSize) {
284 ptSize = *(float *)curPos;
285 curPos = curPos + sizeof(float);
286 TRACE("ptSize=%f\n", ptSize);
288 if (isDiffuse) {
289 diffuseColor = *(DWORD *)curPos;
290 TRACE("diffuseColor=%lx\n", diffuseColor);
291 curPos = curPos + sizeof(DWORD);
293 if (isSpecular) {
294 specularColor = *(DWORD *)curPos;
295 TRACE("specularColor=%lx\n", specularColor);
296 curPos = curPos + sizeof(DWORD);
299 /* ToDo: Texture coords */
300 for (textureNo = 0;textureNo<numTextures; textureNo++) {
302 float s,t,r,q;
304 /* Query tex coords */
305 if (This->StateBlock.textures[textureNo] != NULL) {
306 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
307 case D3DRTYPE_TEXTURE:
308 s = *(float *)curPos;
309 curPos = curPos + sizeof(float);
310 t = *(float *)curPos;
311 curPos = curPos + sizeof(float);
312 TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t);
313 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
314 break;
316 case D3DRTYPE_VOLUMETEXTURE:
317 s = *(float *)curPos;
318 curPos = curPos + sizeof(float);
319 t = *(float *)curPos;
320 curPos = curPos + sizeof(float);
321 r = *(float *)curPos;
322 curPos = curPos + sizeof(float);
323 TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r);
324 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
325 break;
327 default:
328 r=0;q=0; /* Avoid compiler warnings, need these vars later for other textures */
329 FIXME("Unhandled texture type\n");
331 } else {
332 /* Note I have seen a program actually do this, so just hide it and continue */
333 TRACE("Very odd - texture requested in FVF but not bound!\n");
338 /* Handle these vertexes */
339 if (isDiffuse) {
340 glColor4f(((diffuseColor >> 16) & 0xFF) / 255.0,
341 ((diffuseColor >> 8) & 0xFF) / 255.0,
342 ((diffuseColor >> 0) & 0xFF) / 255.0,
343 ((diffuseColor >> 24) & 0xFF) / 255.0);
344 TRACE("glColor4f: r,g,b,a=%f,%f,%f,%f\n", ((diffuseColor >> 16) & 0xFF) / 255.0, ((diffuseColor >> 8) & 0xFF) / 255.0,
345 ((diffuseColor >> 0) & 0xFF) / 255.0, ((diffuseColor >> 24) & 0xFF) / 255.0);
348 if (normal) {
349 TRACE("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz);
350 glNormal3f(nx, ny, nz);
351 glVertex3f(x, y, z);
353 } else {
354 if (rhw < 0.01) {
355 TRACE("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z);
356 glVertex3f(x, y, z);
357 } else {
358 TRACE("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw);
359 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0 / rhw);
363 if (!isIndexed) {
364 curVtx = curVtx + skip;
368 glEnd();
369 checkGLcall("glEnd and previous calls");
371 /* If no normals, restore previous lighting state */
372 if (!normal) {
373 if (isLightingOn) glEnable(GL_LIGHTING);
374 else glDisable(GL_LIGHTING);
375 TRACE("Restored lighting to original state\n");
379 LEAVE_GL();
381 TRACE("glEnd\n");
385 Simple utility routines used for dx -> gl mapping of byte formats
387 SHORT bytesPerPixel(D3DFORMAT fmt) {
388 SHORT retVal;
390 switch (fmt) {
391 case D3DFMT_A4R4G4B4: retVal = 2; break;
392 case D3DFMT_A8R8G8B8: retVal = 4; break;
393 case D3DFMT_X8R8G8B8: retVal = 4; break;
394 case D3DFMT_R8G8B8: retVal = 3; break;
395 case D3DFMT_R5G6B5: retVal = 2; break;
396 case D3DFMT_A1R5G5B5: retVal = 2; break;
397 default:
398 FIXME("Unhandled fmt %d\n", fmt);
399 retVal = 4;
403 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
404 return retVal;
407 GLint fmt2glintFmt(D3DFORMAT fmt) {
408 GLint retVal;
410 switch (fmt) {
411 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
412 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
413 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
414 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
415 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
416 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
417 default:
418 FIXME("Unhandled fmt %d\n", fmt);
419 retVal = 4;
421 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
422 return retVal;
424 GLenum fmt2glFmt(D3DFORMAT fmt) {
425 GLenum retVal;
427 switch (fmt) {
428 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
429 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
430 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
431 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
432 case D3DFMT_R5G6B5: retVal = GL_BGR; break;
433 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
434 default:
435 FIXME("Unhandled fmt %d\n", fmt);
436 retVal = 4;
438 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
439 return retVal;
441 DWORD fmt2glType(D3DFORMAT fmt) {
442 GLenum retVal;
444 switch (fmt) {
445 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
446 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
447 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
448 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
449 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
450 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
451 default:
452 FIXME("Unhandled fmt %d\n", fmt);
453 retVal = 4;
457 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
458 return retVal;
461 int SOURCEx_RGB_EXT(DWORD arg) {
462 switch(arg) {
463 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
464 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
465 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
466 case D3DTSS_ALPHAARG0:
467 case D3DTSS_ALPHAARG1:
468 case D3DTSS_ALPHAARG2:
469 default:
470 FIXME("Invalid arg %ld\n", arg);
471 return GL_SOURCE0_RGB_EXT;
474 int OPERANDx_RGB_EXT(DWORD arg) {
475 switch(arg) {
476 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
477 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
478 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
479 case D3DTSS_ALPHAARG0:
480 case D3DTSS_ALPHAARG1:
481 case D3DTSS_ALPHAARG2:
482 default:
483 FIXME("Invalid arg %ld\n", arg);
484 return GL_OPERAND0_RGB_EXT;
487 int SOURCEx_ALPHA_EXT(DWORD arg) {
488 switch(arg) {
489 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
490 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
491 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
492 case D3DTSS_COLORARG0:
493 case D3DTSS_COLORARG1:
494 case D3DTSS_COLORARG2:
495 default:
496 FIXME("Invalid arg %ld\n", arg);
497 return GL_SOURCE0_ALPHA_EXT;
500 int OPERANDx_ALPHA_EXT(DWORD arg) {
501 switch(arg) {
502 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
503 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
504 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
505 case D3DTSS_COLORARG0:
506 case D3DTSS_COLORARG1:
507 case D3DTSS_COLORARG2:
508 default:
509 FIXME("Invalid arg %ld\n", arg);
510 return GL_OPERAND0_ALPHA_EXT;
513 GLenum StencilOp(DWORD op) {
514 switch(op) {
515 case D3DSTENCILOP_KEEP : return GL_KEEP;
516 case D3DSTENCILOP_ZERO : return GL_ZERO;
517 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
518 case D3DSTENCILOP_INCRSAT : return GL_INCR;
519 case D3DSTENCILOP_DECRSAT : return GL_DECR;
520 case D3DSTENCILOP_INVERT : return GL_INVERT;
521 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op %ld\n", op);
522 return GL_INCR; /* Fixme - needs to support wrap */
523 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op %ld\n", op);
524 return GL_DECR; /* Fixme - needs to support wrap */
525 default:
526 FIXME("Invalid stencil op %ld\n", op);
527 return GL_ALWAYS;
531 /* Apply the current values to the specified texture stage */
532 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
533 ICOM_THIS(IDirect3DDevice8Impl,iface);
534 int i=0;
535 float col[4];
537 /* Make appropriate texture active */
538 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
539 checkGLcall("glActiveTextureARB");
541 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
542 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
543 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock.texture_state[Stage][i]);
546 /* Note the D3DRS value applies to all textures, but GL has one
547 per texture, so apply it now ready to be used! */
548 col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
549 col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
550 col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
551 col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
552 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
553 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
555 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
558 /* IDirect3D IUnknown parts follow: */
559 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
561 ICOM_THIS(IDirect3DDevice8Impl,iface);
563 if (IsEqualGUID(riid, &IID_IUnknown)
564 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
565 IDirect3DDevice8Impl_AddRef(iface);
566 *ppobj = This;
567 return D3D_OK;
570 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
571 return E_NOINTERFACE;
574 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
575 ICOM_THIS(IDirect3DDevice8Impl,iface);
576 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
577 return ++(This->ref);
580 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
581 ICOM_THIS(IDirect3DDevice8Impl,iface);
582 ULONG ref = --This->ref;
583 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
584 if (ref == 0) {
585 HeapFree(GetProcessHeap(), 0, This);
587 return ref;
590 /* IDirect3DDevice Interface follow: */
591 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
592 ICOM_THIS(IDirect3DDevice8Impl,iface);
593 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
594 return D3D_OK;
598 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
599 ICOM_THIS(IDirect3DDevice8Impl,iface);
600 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
602 * pretend we have 32MB of any type of memory queried.
604 return (1024*1024*32);
607 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
608 ICOM_THIS(IDirect3DDevice8Impl,iface);
609 FIXME("(%p) : stub\n", This); return D3D_OK;
611 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
612 ICOM_THIS(IDirect3DDevice8Impl,iface);
613 TRACE("(%p) : returning %p\n", This, This->direct3d8);
615 /* Inc ref count */
616 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
618 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
619 return D3D_OK;
621 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
622 ICOM_THIS(IDirect3DDevice8Impl,iface);
623 FIXME("(%p) : stub, calling idirect3d for now\n", This);
624 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
625 return D3D_OK;
627 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
629 HDC hdc;
630 int bpp = 0;
632 ICOM_THIS(IDirect3DDevice8Impl,iface);
633 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
634 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
635 pMode->RefreshRate = 85; /*FIXME: How to identify? */
637 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
638 bpp = GetDeviceCaps(hdc, BITSPIXEL);
639 DeleteDC(hdc);
641 switch (bpp) {
642 case 8: pMode->Format = D3DFMT_R8G8B8; break;
643 case 16: pMode->Format = D3DFMT_R5G6B5; break;
644 case 24: pMode->Format = D3DFMT_R8G8B8; break;
645 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
646 default: pMode->Format = D3DFMT_UNKNOWN;
649 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
650 return D3D_OK;
652 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
653 ICOM_THIS(IDirect3DDevice8Impl,iface);
654 TRACE("(%p) copying to %p\n", This, pParameters);
655 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
656 return D3D_OK;
658 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
659 ICOM_THIS(IDirect3DDevice8Impl,iface);
660 FIXME("(%p) : stub\n", This); return D3D_OK;
662 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
663 ICOM_THIS(IDirect3DDevice8Impl,iface);
664 FIXME("(%p) : stub\n", This); return;
666 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
667 ICOM_THIS(IDirect3DDevice8Impl,iface);
668 FIXME("(%p) : stub\n", This); return D3D_OK;
670 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
671 ICOM_THIS(IDirect3DDevice8Impl,iface);
672 FIXME("(%p) : stub\n", This); return D3D_OK;
674 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
675 ICOM_THIS(IDirect3DDevice8Impl,iface);
676 FIXME("(%p) : stub\n", This); return D3D_OK;
678 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
679 ICOM_THIS(IDirect3DDevice8Impl,iface);
680 TRACE("(%p) : complete stub!\n", This);
682 ENTER_GL();
684 glXSwapBuffers(This->display, This->win);
685 checkGLcall("glXSwapBuffers");
687 LEAVE_GL();
689 return D3D_OK;
691 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
692 ICOM_THIS(IDirect3DDevice8Impl,iface);
693 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
694 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
696 /* Note inc ref on returned surface */
697 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
699 return D3D_OK;
701 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
702 ICOM_THIS(IDirect3DDevice8Impl,iface);
703 FIXME("(%p) : stub\n", This); return D3D_OK;
705 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
706 ICOM_THIS(IDirect3DDevice8Impl,iface);
707 FIXME("(%p) : stub\n", This); return;
709 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
710 ICOM_THIS(IDirect3DDevice8Impl,iface);
711 FIXME("(%p) : stub\n", This); return;
713 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
714 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
715 IDirect3DTexture8Impl *object;
716 int i;
717 UINT tmpW;
718 UINT tmpH;
720 ICOM_THIS(IDirect3DDevice8Impl,iface);
722 /* Allocate the storage for the device */
723 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
724 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
725 object->lpVtbl = &Direct3DTexture8_Vtbl;
726 object->Device = This;
727 object->ResourceType = D3DRTYPE_TEXTURE;
728 object->ref = 1;
729 object->width = Width;
730 object->height = Height;
731 object->levels = Levels;
732 object->usage = Usage;
733 object->format = Format;
734 object->device = This;
736 /* Calculate levels for mip mapping */
737 if (Levels == 0) {
738 object->levels++;
739 tmpW = Width;
740 tmpH = Height;
741 while (tmpW > 1 && tmpH > 1) {
742 tmpW = max(1,tmpW / 2);
743 tmpH = max(1, tmpH / 2);
744 object->levels++;
746 TRACE("Calculated levels = %d\n", object->levels);
749 /* Generate all the surfaces */
750 tmpW = Width;
751 tmpH = Height;
752 /*for (i=0; i<object->levels; i++) { */
753 i=0;
755 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
756 object->surfaces[i]->Container = object;
757 object->surfaces[i]->myDesc.Usage = Usage;
758 object->surfaces[i]->myDesc.Pool = Pool ;
760 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
761 tmpW = max(1,tmpW / 2);
762 tmpH = max(1, tmpH / 2);
765 *ppTexture = (LPDIRECT3DTEXTURE8)object;
766 return D3D_OK;
768 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
770 IDirect3DVolumeTexture8Impl *object;
771 int i;
772 UINT tmpW;
773 UINT tmpH;
774 UINT tmpD;
776 ICOM_THIS(IDirect3DDevice8Impl,iface);
778 /* Allocate the storage for it */
779 TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Depth, Levels, Usage, Format, Pool);
780 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
781 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
782 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
783 object->ref = 1;
786 object->width = Width;
787 object->height = Height;
788 object->depth = Depth;
789 object->levels = Levels;
790 object->usage = Usage;
791 object->format = Format;
792 object->device = This;
794 /* Calculate levels for mip mapping */
795 if (Levels == 0) {
796 object->levels++;
797 tmpW = Width;
798 tmpH = Height;
799 tmpD = Depth;
800 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
801 tmpW = max(1,tmpW / 2);
802 tmpH = max(1, tmpH / 2);
803 tmpD = max(1, tmpD / 2);
804 object->levels++;
806 TRACE("Calculated levels = %d\n", object->levels);
809 /* Generate all the surfaces */
810 tmpW = Width;
811 tmpH = Height;
812 tmpD = Depth;
814 /*for (i=0; i<object->levels; i++) { */
815 i=0;
817 IDirect3DVolume8Impl *volume;
819 /* Create the volume - No entry point for this seperately?? */
820 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
821 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
823 volume->lpVtbl = &Direct3DVolume8_Vtbl;
824 volume->Device = This;
825 volume->ResourceType = D3DRTYPE_VOLUME;
826 volume->Container = object;
827 volume->ref = 1;
829 volume->myDesc.Width = Width;
830 volume->myDesc.Height= Height;
831 volume->myDesc.Depth = Depth;
832 volume->myDesc.Format= Format;
833 volume->myDesc.Type = D3DRTYPE_VOLUME;
834 volume->myDesc.Pool = Pool;
835 volume->myDesc.Usage = Usage;
836 volume->bytesPerPixel = bytesPerPixel(Format);
837 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
838 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
840 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
841 volume, volume->allocatedMemory, volume->myDesc.Size);
843 tmpW = max(1,tmpW / 2);
844 tmpH = max(1, tmpH / 2);
845 tmpD = max(1, tmpD / 2);
848 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
849 return D3D_OK;
851 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
853 IDirect3DCubeTexture8Impl *object;
854 ICOM_THIS(IDirect3DDevice8Impl,iface);
855 int i,j;
856 UINT tmpW;
858 /* Allocate the storage for it */
859 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
860 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
861 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
862 object->ref = 1;
863 object->Device = This;
864 object->ResourceType = D3DRTYPE_CUBETEXTURE;
866 object->edgeLength = EdgeLength;
867 object->levels = Levels;
868 object->usage = Usage;
869 object->format = Format;
870 object->device = This;
872 /* Calculate levels for mip mapping */
873 if (Levels == 0) {
874 object->levels++;
875 tmpW = EdgeLength;
876 while (tmpW > 1) {
877 tmpW = max(1,tmpW / 2);
878 object->levels++;
880 TRACE("Calculated levels = %d\n", object->levels);
883 /* Generate all the surfaces */
884 tmpW = EdgeLength;
885 /*for (i=0; i<object->levels; i++) { */
886 i=0;
888 /* Create the 6 faces */
889 for (j=0;j<6;j++) {
890 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
891 object->surfaces[j][i]->Container = object;
892 object->surfaces[j][i]->myDesc.Usage = Usage;
893 object->surfaces[j][i]->myDesc.Pool = Pool ;
895 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
896 tmpW = max(1,tmpW / 2);
900 TRACE("(%p) : Iface@%p\n", This, object);
901 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
902 return D3D_OK;
904 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage,
905 DWORD FVF,D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
906 IDirect3DVertexBuffer8Impl *object;
908 ICOM_THIS(IDirect3DDevice8Impl,iface);
910 /* Allocate the storage for the device */
911 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
912 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
913 object->Device = This;
914 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
915 object->ref = 1;
916 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
917 object->currentDesc.Usage = Usage;
918 object->currentDesc.Pool = Pool;
919 object->currentDesc.FVF = FVF;
920 object->currentDesc.Size = Size;
922 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
924 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
926 return D3D_OK;
928 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
930 IDirect3DIndexBuffer8Impl *object;
932 ICOM_THIS(IDirect3DDevice8Impl,iface);
933 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
935 /* Allocate the storage for the device */
936 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
937 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
938 object->ref = 1;
939 object->Device = This;
940 object->ResourceType = D3DRTYPE_INDEXBUFFER;
942 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
943 object->currentDesc.Usage = Usage;
944 object->currentDesc.Pool = Pool;
945 object->currentDesc.Format = Format;
946 object->currentDesc.Size = Length;
948 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
950 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
952 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
954 return D3D_OK;
956 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
957 ICOM_THIS(IDirect3DDevice8Impl,iface);
958 /* up ref count on surface, surface->container = This */
959 FIXME("(%p) : stub\n", This); return D3D_OK;
961 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
962 ICOM_THIS(IDirect3DDevice8Impl,iface);
963 /* surface->container = This */
964 FIXME("(%p) : stub\n", This); return D3D_OK;
966 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
967 IDirect3DSurface8Impl *object;
969 ICOM_THIS(IDirect3DDevice8Impl,iface);
971 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
972 *ppSurface = (LPDIRECT3DSURFACE8) object;
973 object->lpVtbl = &Direct3DSurface8_Vtbl;
974 object->Device = This;
975 object->ResourceType = D3DRTYPE_SURFACE;
976 object->Container = This;
978 object->ref = 1;
979 object->myDesc.Width = Width;
980 object->myDesc.Height= Height;
981 object->myDesc.Format= Format;
982 object->myDesc.Type = D3DRTYPE_SURFACE;
983 /*object->myDesc.Usage */
984 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
985 object->bytesPerPixel = bytesPerPixel(Format);
986 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
987 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
989 TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, *ppSurface, object->allocatedMemory, object->myDesc.Size);
990 return D3D_OK;
992 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
993 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
995 HRESULT rc = D3D_OK;
997 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
998 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1000 ICOM_THIS(IDirect3DDevice8Impl,iface);
1001 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1002 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1004 if (src->myDesc.Format != dst->myDesc.Format) {
1005 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1006 rc = D3DERR_INVALIDCALL;
1009 /* Quick if complete copy ... */
1010 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1011 src->myDesc.Width == dst->myDesc.Width &&
1012 src->myDesc.Height == dst->myDesc.Height)) {
1013 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1014 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1016 } else {
1017 int i;
1018 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1019 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1020 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1022 void *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1023 void *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1025 /* Copy rect by rect */
1026 for (i=0; i<cRects; i++) {
1027 CONST RECT *r = &pSourceRectsArray[i];
1028 CONST POINT *p = &pDestPointsArray[i];
1029 void *from;
1030 void *to;
1031 int copyperline = (r->right - r->left) * bytesPerPixel;
1032 int j;
1034 TRACE("Copying rect %d (%d,%d),(%d,%d) -> (%ld,%ld)\n", i, r->left, r->top,
1035 r->right, r->bottom, p->x, p->y);
1037 /* Find where to start */
1038 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1039 to = copyto + (p->y * pitchFrom) + (p->x * bytesPerPixel);
1041 /* Copy line by line */
1042 for (j=0; j<(r->bottom - r->top); j++) {
1043 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1047 return D3D_OK;
1049 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1050 ICOM_THIS(IDirect3DDevice8Impl,iface);
1051 FIXME("(%p) : stub\n", This); return D3D_OK;
1053 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1054 ICOM_THIS(IDirect3DDevice8Impl,iface);
1055 FIXME("(%p) : stub\n", This); return D3D_OK;
1057 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1058 ICOM_THIS(IDirect3DDevice8Impl,iface);
1059 FIXME("(%p) : stub\n", This);
1061 return D3D_OK;
1063 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1064 ICOM_THIS(IDirect3DDevice8Impl,iface);
1065 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1066 FIXME("(%p) : stub\n", This);
1069 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1070 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1073 return D3D_OK;
1075 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1077 ICOM_THIS(IDirect3DDevice8Impl,iface);
1079 /* Note inc ref on returned surface *
1080 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1082 FIXME("(%p) : stub\n", This);
1083 return D3D_OK;
1086 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1087 ICOM_THIS(IDirect3DDevice8Impl,iface);
1088 TRACE("(%p) : stub\n", This);
1089 return D3D_OK;
1091 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1092 ICOM_THIS(IDirect3DDevice8Impl,iface);
1093 TRACE("(%p)\n", This);
1095 ENTER_GL();
1097 glFlush();
1098 checkGLcall("glFlush");
1100 /* Useful for debugging sometimes!
1101 printf("Hit Enter ...\n");
1102 getchar(); */
1104 LEAVE_GL();
1105 return D3D_OK;
1107 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1108 ICOM_THIS(IDirect3DDevice8Impl,iface);
1110 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1111 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1112 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1113 GLbitfield glMask = 0;
1114 int i;
1115 CONST D3DRECT *curRect;
1117 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1118 Count, pRects, Flags, Z, Stencil);
1120 ENTER_GL();
1121 if (Count > 0 && pRects) {
1122 glEnable(GL_SCISSOR_TEST);
1123 checkGLcall("glEnable GL_SCISSOR_TEST");
1124 curRect = pRects;
1125 } else {
1126 curRect = NULL;
1129 for (i=0;i<Count || i==0; i++) {
1131 if (curRect) {
1132 /* Note gl uses lower left, width/height */
1133 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1134 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1135 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1136 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1137 checkGLcall("glScissor");
1140 /* Clear the whole screen */
1141 if (Flags & D3DCLEAR_STENCIL) {
1142 glClearStencil(Stencil);
1143 checkGLcall("glClearStencil");
1144 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1147 if (Flags & D3DCLEAR_ZBUFFER) {
1148 glClearDepth(Z);
1149 checkGLcall("glClearDepth");
1150 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1153 if (Flags & D3DCLEAR_TARGET) {
1154 TRACE("Clearing screen with glClear to color %lx\n", Color);
1155 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1156 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1157 checkGLcall("glClearColor");
1158 glMask = glMask | GL_COLOR_BUFFER_BIT;
1161 glClear(glMask);
1162 checkGLcall("glClear");
1164 if (curRect) curRect = curRect + sizeof(D3DRECT);
1167 if (Count > 0 && pRects) {
1168 glDisable(GL_SCISSOR_TEST);
1169 checkGLcall("glDisable");
1171 LEAVE_GL();
1173 return D3D_OK;
1175 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1176 ICOM_THIS(IDirect3DDevice8Impl,iface);
1177 int k;
1179 /* Most of this routine, comments included copied from ddraw tree initially: */
1180 TRACE("(%p) : State=%d\n", This, d3dts);
1182 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1183 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1184 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1186 /* Handle recording of state blocks */
1187 if (This->isRecordingState) {
1188 TRACE("Recording... not performing anything\n");
1189 return D3D_OK;
1193 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1195 where ViewMat = Camera space, WorldMat = world space.
1197 In OpenGL, camera and world space is combined into GL_MODELVIEW
1198 matrix. The Projection matrix stay projection matrix. */
1200 /* After reading through both OpenGL and Direct3D documentations, I
1201 thought that D3D matrices were written in 'line major mode' transposed
1202 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1203 works fine to transfer one matrix format to the other (it did not work
1204 when transposing)....
1206 So :
1207 1) are the documentations wrong
1208 2) does the matrix work even if they are not read correctly
1209 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1210 loading using glLoadMatrix ?
1212 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1213 to the other so that if I ever find out that I need to transpose them, I
1214 will able to do it quickly, only by changing the macro conv_mat. */
1216 switch (d3dts) {
1217 case D3DTS_WORLDMATRIX(0): {
1218 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)]);
1219 } break;
1221 case D3DTS_VIEW: {
1222 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_VIEW]);
1223 } break;
1225 case D3DTS_PROJECTION: {
1226 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_PROJECTION]);
1227 } break;
1229 default:
1230 break;
1234 * Move the GL operation to outside of switch to make it work
1235 * regardless of transform set order. Optimize later.
1237 ENTER_GL();
1238 glMatrixMode(GL_PROJECTION);
1239 checkGLcall("glMatrixMode");
1240 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
1241 checkGLcall("glLoadMatrixf");
1243 glMatrixMode(GL_MODELVIEW);
1244 checkGLcall("glMatrixMode");
1245 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1246 checkGLcall("glLoadMatrixf");
1248 /* If we are changing the View matrix, reset the light information to the new view */
1249 if (d3dts == D3DTS_VIEW) {
1250 for (k = 0; k < MAX_ACTIVE_LIGHTS; k++) {
1251 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1252 checkGLcall("glLightfv posn");
1253 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1254 checkGLcall("glLightfv dirn");
1258 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1259 checkGLcall("glMultMatrixf");
1261 LEAVE_GL();
1263 return D3D_OK;
1266 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1267 ICOM_THIS(IDirect3DDevice8Impl,iface);
1268 TRACE("(%p) : for State %d\n", This, State);
1269 memcpy(pMatrix, &This->StateBlock.transforms[State], sizeof(D3DMATRIX));
1270 return D3D_OK;
1273 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1274 ICOM_THIS(IDirect3DDevice8Impl,iface);
1275 FIXME("(%p) : stub\n", This); return D3D_OK;
1277 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1278 ICOM_THIS(IDirect3DDevice8Impl,iface);
1280 TRACE("(%p)\n", This);
1281 This->UpdateStateBlock->Changed.viewport = TRUE;
1282 This->UpdateStateBlock->Set.viewport = TRUE;
1283 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1285 /* Handle recording of state blocks */
1286 if (This->isRecordingState) {
1287 TRACE("Recording... not performing anything\n");
1288 return D3D_OK;
1291 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1292 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1294 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1295 checkGLcall("glDepthRange");
1296 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1297 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1298 checkGLcall("glViewport");
1301 return D3D_OK;
1304 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1305 ICOM_THIS(IDirect3DDevice8Impl,iface);
1306 TRACE("(%p)\n", This);
1307 memcpy(pViewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
1308 return D3D_OK;
1311 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1312 ICOM_THIS(IDirect3DDevice8Impl,iface);
1314 This->UpdateStateBlock->Changed.material = TRUE;
1315 This->UpdateStateBlock->Set.material = TRUE;
1316 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1318 /* Handle recording of state blocks */
1319 if (This->isRecordingState) {
1320 TRACE("Recording... not performing anything\n");
1321 return D3D_OK;
1324 ENTER_GL();
1325 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1326 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1327 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1328 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1329 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1331 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1332 checkGLcall("glMaterialfv");
1333 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1334 checkGLcall("glMaterialfv");
1336 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1337 checkGLcall("glMaterialfv");
1338 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1339 checkGLcall("glMaterialfv");
1340 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1341 checkGLcall("glMaterialf");
1343 LEAVE_GL();
1344 return D3D_OK;
1346 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1347 ICOM_THIS(IDirect3DDevice8Impl,iface);
1348 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1349 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1350 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1351 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1352 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1353 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1354 return D3D_OK;
1357 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1358 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1359 float rho;
1360 float quad_att;
1362 ICOM_THIS(IDirect3DDevice8Impl,iface);
1363 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1365 TRACE("Light %ld setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f)\n", Index, pLight->Type,
1366 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1367 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1368 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1369 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1370 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1371 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1373 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1374 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1375 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1377 /* Handle recording of state blocks */
1378 if (This->isRecordingState) {
1379 TRACE("Recording... not performing anything\n");
1380 return D3D_OK;
1383 /* Diffuse: */
1384 colRGBA[0] = pLight->Diffuse.r;
1385 colRGBA[1] = pLight->Diffuse.g;
1386 colRGBA[2] = pLight->Diffuse.b;
1387 colRGBA[3] = pLight->Diffuse.a;
1388 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1389 checkGLcall("glLightfv");
1391 /* Specular */
1392 colRGBA[0] = pLight->Specular.r;
1393 colRGBA[1] = pLight->Specular.g;
1394 colRGBA[2] = pLight->Specular.b;
1395 colRGBA[3] = pLight->Specular.a;
1396 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1397 checkGLcall("glLightfv");
1399 /* Ambient */
1400 colRGBA[0] = pLight->Ambient.r;
1401 colRGBA[1] = pLight->Ambient.g;
1402 colRGBA[2] = pLight->Ambient.b;
1403 colRGBA[3] = pLight->Ambient.a;
1404 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1405 checkGLcall("glLightfv");
1407 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1408 glMatrixMode(GL_MODELVIEW);
1409 glPushMatrix();
1410 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1412 /* Attenuation - Are these right? guessing... */
1413 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
1414 checkGLcall("glLightf");
1415 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
1416 checkGLcall("glLightf");
1418 quad_att = 1.4/(pLight->Range*pLight->Range);
1419 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1420 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1421 checkGLcall("glLightf");
1423 switch (pLight->Type) {
1424 case D3DLIGHT_POINT:
1425 /* Position */
1426 This->lightPosn[Index][0] = pLight->Position.x;
1427 This->lightPosn[Index][1] = pLight->Position.y;
1428 This->lightPosn[Index][2] = pLight->Position.z;
1429 This->lightPosn[Index][3] = 1.0;
1430 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1431 checkGLcall("glLightfv");
1433 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1434 checkGLcall("glLightf");
1436 /* FIXME: Range */
1437 break;
1439 case D3DLIGHT_SPOT:
1440 /* Position */
1441 This->lightPosn[Index][0] = pLight->Position.x;
1442 This->lightPosn[Index][1] = pLight->Position.y;
1443 This->lightPosn[Index][2] = pLight->Position.z;
1444 This->lightPosn[Index][3] = 1.0;
1445 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1446 checkGLcall("glLightfv");
1448 /* Direction */
1449 This->lightDirn[Index][0] = pLight->Direction.x;
1450 This->lightDirn[Index][1] = pLight->Direction.y;
1451 This->lightDirn[Index][2] = pLight->Direction.z;
1452 This->lightDirn[Index][3] = 1.0;
1453 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1454 checkGLcall("glLightfv");
1457 * opengl-ish and d3d-ish spot lights use too different models for the
1458 * light "intensity" as a function of the angle towards the main light direction,
1459 * so we only can approximate very roughly.
1460 * however spot lights are rather rarely used in games (if ever used at all).
1461 * furthermore if still used, probably nobody pays attention to such details.
1463 if (pLight->Falloff == 0) {
1464 rho = 6.28f;
1465 } else {
1466 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1468 if (rho < 0.0001) rho = 0.0001f;
1469 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
1470 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
1472 /* FIXME: Range */
1473 break;
1474 case D3DLIGHT_DIRECTIONAL:
1475 /* Direction */
1476 This->lightPosn[Index][0] = -pLight->Direction.x;
1477 This->lightPosn[Index][1] = -pLight->Direction.y;
1478 This->lightPosn[Index][2] = -pLight->Direction.z;
1479 This->lightPosn[Index][3] = 0.0;
1480 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
1481 checkGLcall("glLightfv");
1483 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
1484 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
1487 break;
1488 default:
1489 FIXME("Unrecognized light type %d\n", pLight->Type);
1492 /* Restore the modelview matrix */
1493 glPopMatrix();
1495 return D3D_OK;
1497 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1498 ICOM_THIS(IDirect3DDevice8Impl,iface);
1499 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1500 memcpy(pLight, &This->StateBlock.lights[Index], sizeof(D3DLIGHT8));
1501 return D3D_OK;
1503 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1504 ICOM_THIS(IDirect3DDevice8Impl,iface);
1505 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
1507 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
1508 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
1509 This->UpdateStateBlock->lightEnable[Index] = Enable;
1511 /* Handle recording of state blocks */
1512 if (This->isRecordingState) {
1513 TRACE("Recording... not performing anything\n");
1514 return D3D_OK;
1517 if (Enable) {
1518 glEnable(GL_LIGHT0+Index);
1519 checkGLcall("glEnable GL_LIGHT0+Index");
1520 } else {
1521 glDisable(GL_LIGHT0+Index);
1522 checkGLcall("glDisable GL_LIGHT0+Index");
1524 return D3D_OK;
1526 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1527 ICOM_THIS(IDirect3DDevice8Impl,iface);
1528 TRACE("(%p) : for idx(%ld)\n", This, Index);
1529 *pEnable = This->StateBlock.lightEnable[Index];
1530 return D3D_OK;
1532 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1533 ICOM_THIS(IDirect3DDevice8Impl,iface);
1534 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
1536 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
1537 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
1538 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
1539 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
1540 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
1541 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
1543 /* Handle recording of state blocks */
1544 if (This->isRecordingState) {
1545 TRACE("Recording... not performing anything\n");
1546 return D3D_OK;
1549 /* Apply it */
1551 /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
1552 glMatrixMode(GL_MODELVIEW);
1553 glPushMatrix();
1554 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLD].u.m[0][0]);
1556 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
1557 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
1558 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
1560 glPopMatrix();
1561 checkGLcall("glClipPlane");
1563 return D3D_OK;
1565 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1566 ICOM_THIS(IDirect3DDevice8Impl,iface);
1567 TRACE("(%p) : for idx %ld\n", This, Index);
1568 pPlane[0] = This->StateBlock.clipplane[Index][0];
1569 pPlane[1] = This->StateBlock.clipplane[Index][0];
1570 pPlane[2] = This->StateBlock.clipplane[Index][0];
1571 pPlane[3] = This->StateBlock.clipplane[Index][0];
1572 return D3D_OK;
1574 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
1575 ICOM_THIS(IDirect3DDevice8Impl,iface);
1576 DWORD OldValue = This->StateBlock.renderstate[State];
1578 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
1579 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
1580 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
1581 This->UpdateStateBlock->renderstate[State] = Value;
1583 /* Handle recording of state blocks */
1584 if (This->isRecordingState) {
1585 TRACE("Recording... not performing anything\n");
1586 return D3D_OK;
1589 switch (State) {
1590 case D3DRS_FILLMODE :
1591 switch ((D3DFILLMODE) Value) {
1592 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
1593 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
1594 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
1595 default:
1596 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
1598 checkGLcall("glPolygonMode (fillmode)");
1599 break;
1601 case D3DRS_LIGHTING :
1602 if (Value) {
1603 glEnable(GL_LIGHTING);
1604 checkGLcall("glEnable GL_LIGHTING");
1605 } else {
1606 glDisable(GL_LIGHTING);
1607 checkGLcall("glDisable GL_LIGHTING");
1609 break;
1611 case D3DRS_ZENABLE :
1612 switch ((D3DZBUFFERTYPE) Value) {
1613 case D3DZB_FALSE:
1614 glDisable(GL_DEPTH_TEST);
1615 checkGLcall("glDisable GL_DEPTH_TEST");
1616 break;
1617 case D3DZB_TRUE:
1618 glEnable(GL_DEPTH_TEST);
1619 checkGLcall("glEnable GL_DEPTH_TEST");
1620 break;
1622 case D3DZB_USEW:
1623 default:
1624 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
1626 break;
1628 case D3DRS_CULLMODE :
1630 /* If we are culling "back faces with clockwise vertices" then
1631 set front faces to be counter clockwise and enable culling
1632 of back faces */
1633 switch ((D3DCULL) Value) {
1634 case D3DCULL_NONE:
1635 glDisable(GL_CULL_FACE);
1636 checkGLcall("glDisable GL_CULL_FACE");
1637 break;
1638 case D3DCULL_CW:
1639 glEnable(GL_CULL_FACE);
1640 checkGLcall("glEnable GL_CULL_FACE");
1641 glFrontFace(GL_CCW);
1642 checkGLcall("glFrontFace GL_CCW");
1643 glCullFace(GL_BACK);
1644 break;
1645 case D3DCULL_CCW:
1646 glEnable(GL_CULL_FACE);
1647 checkGLcall("glEnable GL_CULL_FACE");
1648 glFrontFace(GL_CW);
1649 checkGLcall("glFrontFace GL_CW");
1650 glCullFace(GL_BACK);
1651 break;
1652 default:
1653 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
1655 break;
1657 case D3DRS_SHADEMODE :
1658 switch ((D3DSHADEMODE) Value) {
1659 case D3DSHADE_FLAT:
1660 glShadeModel(GL_FLAT);
1661 checkGLcall("glShadeModel");
1662 break;
1663 case D3DSHADE_GOURAUD:
1664 glShadeModel(GL_SMOOTH);
1665 checkGLcall("glShadeModel");
1666 break;
1667 case D3DSHADE_PHONG:
1668 FIXME("D3DSHADE_PHONG isnt supported?\n");
1669 return D3DERR_INVALIDCALL;
1670 default:
1671 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
1673 break;
1675 case D3DRS_DITHERENABLE :
1676 if (Value) {
1677 glEnable(GL_DITHER);
1678 checkGLcall("glEnable GL_DITHER");
1679 } else {
1680 glDisable(GL_DITHER);
1681 checkGLcall("glDisable GL_DITHER");
1683 break;
1685 case D3DRS_ZWRITEENABLE :
1686 if (Value) {
1687 glDepthMask(1);
1688 checkGLcall("glDepthMask");
1689 } else {
1690 glDepthMask(0);
1691 checkGLcall("glDepthMask");
1693 break;
1695 case D3DRS_ZFUNC :
1697 int glParm = GL_LESS;
1699 switch ((D3DCMPFUNC) Value) {
1700 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1701 case D3DCMP_LESS: glParm=GL_LESS; break;
1702 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1703 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1704 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1705 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1706 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1707 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1708 default:
1709 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1711 glDepthFunc(glParm);
1712 checkGLcall("glDepthFunc");
1714 break;
1716 case D3DRS_AMBIENT :
1719 float col[4];
1720 col[0] = ((Value >> 16) & 0xFF) / 255.0;
1721 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1722 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1723 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1724 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
1725 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
1726 checkGLcall("glLightModel for MODEL_AMBIENT");
1729 break;
1731 case D3DRS_ALPHABLENDENABLE :
1732 if (Value) {
1733 glEnable(GL_BLEND);
1734 checkGLcall("glEnable GL_BLEND");
1735 } else {
1736 glDisable(GL_BLEND);
1737 checkGLcall("glDisable GL_BLEND");
1739 break;
1741 case D3DRS_SRCBLEND :
1742 case D3DRS_DESTBLEND :
1744 int newVal = GL_ZERO;
1745 switch (Value) {
1746 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
1747 case D3DBLEND_ONE : newVal = GL_ONE; break;
1748 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
1749 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
1750 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
1751 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
1752 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
1753 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
1754 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
1755 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
1756 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
1758 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
1759 This->srcBlend = newVal;
1760 This->dstBlend = newVal;
1761 break;
1763 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
1764 This->srcBlend = newVal;
1765 This->dstBlend = newVal;
1766 break;
1767 default:
1768 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
1771 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
1772 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
1773 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
1774 glBlendFunc(This->srcBlend, This->dstBlend);
1776 checkGLcall("glBlendFunc");
1778 break;
1780 case D3DRS_ALPHATESTENABLE :
1781 if (Value) {
1782 glEnable(GL_ALPHA_TEST);
1783 checkGLcall("glEnable GL_ALPHA_TEST");
1784 } else {
1785 glDisable(GL_ALPHA_TEST);
1786 checkGLcall("glDisable GL_ALPHA_TEST");
1788 break;
1790 case D3DRS_ALPHAFUNC :
1792 int glParm = GL_LESS;
1793 float ref = 1.0;
1795 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
1796 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
1798 switch ((D3DCMPFUNC) Value) {
1799 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1800 case D3DCMP_LESS: glParm=GL_LESS; break;
1801 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1802 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1803 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1804 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1805 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1806 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1807 default:
1808 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1810 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1811 glAlphaFunc(glParm, ref);
1812 checkGLcall("glAlphaFunc");
1814 break;
1816 case D3DRS_ALPHAREF :
1818 int glParm = GL_LESS;
1819 float ref = 1.0;
1821 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
1822 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
1824 ref = ((float) Value) / 255.0;
1825 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1826 glAlphaFunc(glParm, ref);
1827 checkGLcall("glAlphaFunc");
1829 break;
1831 case D3DRS_CLIPPLANEENABLE :
1832 case D3DRS_CLIPPING :
1834 /* Ensure we only do the changed clip planes */
1835 DWORD enable = 0xFFFFFFFF;
1836 DWORD disable = 0x00000000;
1838 /* If enabling / disabling all */
1839 if (State == D3DRS_CLIPPING) {
1840 if (Value) {
1841 enable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1842 disable = 0x00;
1843 } else {
1844 disable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1845 enable = 0x00;
1847 } else {
1848 enable = Value & ~OldValue;
1849 disable = ~Value & OldValue;
1852 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
1853 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
1854 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
1855 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
1856 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
1857 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
1859 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
1860 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
1861 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
1862 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
1863 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
1864 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
1866 break;
1868 case D3DRS_BLENDOP :
1870 int glParm = GL_FUNC_ADD;
1872 switch ((D3DBLENDOP) Value) {
1873 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
1874 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
1875 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
1876 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
1877 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
1878 default:
1879 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
1881 TRACE("glBlendEquation(%x)\n", glParm);
1882 glBlendEquation(glParm);
1883 checkGLcall("glBlendEquation");
1885 break;
1887 case D3DRS_TEXTUREFACTOR :
1889 int i;
1891 /* Note the texture color applies to all textures whereas
1892 GL_TEXTURE_ENV_COLOR applies to active only */
1893 float col[4];
1894 col[0] = ((Value >> 16) & 0xFF) / 255.0;
1895 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1896 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1897 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1899 /* Set the default alpha blend color */
1900 glBlendColor(col[0], col[1], col[2], col[3]);
1901 checkGLcall("glBlendColor");
1903 /* And now the default texture color as well */
1904 for (i=0; i<8; i++) {
1906 /* Note the D3DRS value applies to all textures, but GL has one
1907 per texture, so apply it now ready to be used! */
1908 checkGLcall("Activate texture.. to update const color");
1909 glActiveTextureARB(GL_TEXTURE0_ARB + i);
1911 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1912 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1915 break;
1917 case D3DRS_SPECULARENABLE :
1919 if (Value) {
1920 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
1921 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
1922 } else {
1923 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
1924 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
1927 break;
1929 case D3DRS_STENCILENABLE :
1930 if (Value) {
1931 glEnable(GL_STENCIL_TEST);
1932 checkGLcall("glEnable GL_STENCIL_TEST");
1933 } else {
1934 glDisable(GL_STENCIL_TEST);
1935 checkGLcall("glDisable GL_STENCIL_TEST");
1937 break;
1939 case D3DRS_STENCILFUNC :
1941 int glParm = GL_ALWAYS;
1942 int ref = 0;
1943 GLuint mask = 0xFFFFFFFF;
1945 glGetIntegerv(GL_STENCIL_REF, &ref);
1946 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1947 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1948 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1950 switch ((D3DCMPFUNC) Value) {
1951 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1952 case D3DCMP_LESS: glParm=GL_LESS; break;
1953 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1954 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1955 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1956 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1957 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1958 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1959 default:
1960 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1962 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1963 glStencilFunc(glParm, ref, mask);
1964 checkGLcall("glStencilFunc");
1966 break;
1968 case D3DRS_STENCILREF :
1970 int glParm = GL_ALWAYS;
1971 int ref = 0;
1972 GLuint mask = 0xFFFFFFFF;
1974 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1975 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1976 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1977 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1979 ref = Value;
1980 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1981 glStencilFunc(glParm, ref, mask);
1982 checkGLcall("glStencilFunc");
1984 break;
1986 case D3DRS_STENCILMASK :
1988 int glParm = GL_ALWAYS;
1989 int ref = 0.0;
1990 GLuint mask = Value;
1992 glGetIntegerv(GL_STENCIL_REF, &ref);
1993 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1994 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1995 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1997 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1998 glStencilFunc(glParm, ref, mask);
1999 checkGLcall("glStencilFunc");
2001 break;
2003 case D3DRS_STENCILFAIL :
2005 GLenum fail ;
2006 GLenum zpass ;
2007 GLenum zfail ;
2009 fail = StencilOp(Value);
2010 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2011 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2012 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2013 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2015 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2016 glStencilOp(fail, zfail, zpass);
2017 checkGLcall("glStencilOp(fail, zfail, zpass);");
2019 break;
2020 case D3DRS_STENCILZFAIL :
2022 GLenum fail ;
2023 GLenum zpass ;
2024 GLenum zfail ;
2026 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2027 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2028 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2029 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2030 zfail = StencilOp(Value);
2032 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2033 glStencilOp(fail, zfail, zpass);
2034 checkGLcall("glStencilOp(fail, zfail, zpass);");
2036 break;
2037 case D3DRS_STENCILPASS :
2039 GLenum fail ;
2040 GLenum zpass ;
2041 GLenum zfail ;
2043 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2044 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2045 zpass = StencilOp(Value);
2046 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2047 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2049 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2050 glStencilOp(fail, zfail, zpass);
2051 checkGLcall("glStencilOp(fail, zfail, zpass);");
2053 break;
2055 case D3DRS_STENCILWRITEMASK :
2057 glStencilMask(Value);
2058 TRACE("glStencilMask(%lu)\n", Value);
2059 checkGLcall("glStencilMask");
2061 break;
2063 case D3DRS_FOGENABLE :
2065 if (Value && This->StateBlock.renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
2066 glEnable(GL_FOG);
2067 checkGLcall("glEnable GL_FOG\n");
2068 } else {
2069 glDisable(GL_FOG);
2070 checkGLcall("glDisable GL_FOG\n");
2073 break;
2075 case D3DRS_FOGCOLOR :
2077 float col[4];
2078 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2079 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2080 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2081 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2083 /* Set the default alpha blend color */
2084 glFogfv(GL_FOG_COLOR, &col[0]);
2085 checkGLcall("glFog GL_FOG_COLOR");
2087 break;
2089 case D3DRS_FOGSTART :
2091 float *f = (float *)&Value;
2092 glFogfv(GL_FOG_START, f);
2093 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2094 TRACE("Fog Start == %f\n", *f);
2096 break;
2098 case D3DRS_FOGEND :
2100 float *f = (float *)&Value;
2101 glFogfv(GL_FOG_END, f);
2102 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2103 TRACE("Fog End == %f\n", *f);
2105 break;
2107 case D3DRS_FOGDENSITY :
2109 glFogf(GL_FOG_DENSITY, (float) Value);
2110 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2112 break;
2114 /* Unhandled yet...! */
2115 case D3DRS_LINEPATTERN :
2116 case D3DRS_LASTPIXEL :
2117 case D3DRS_ZVISIBLE :
2118 case D3DRS_FOGTABLEMODE :
2119 case D3DRS_EDGEANTIALIAS :
2120 case D3DRS_ZBIAS :
2121 case D3DRS_RANGEFOGENABLE :
2122 case D3DRS_WRAP0 :
2123 case D3DRS_WRAP1 :
2124 case D3DRS_WRAP2 :
2125 case D3DRS_WRAP3 :
2126 case D3DRS_WRAP4 :
2127 case D3DRS_WRAP5 :
2128 case D3DRS_WRAP6 :
2129 case D3DRS_WRAP7 :
2130 case D3DRS_FOGVERTEXMODE :
2131 case D3DRS_COLORVERTEX :
2132 case D3DRS_LOCALVIEWER :
2133 case D3DRS_NORMALIZENORMALS :
2134 case D3DRS_DIFFUSEMATERIALSOURCE :
2135 case D3DRS_SPECULARMATERIALSOURCE :
2136 case D3DRS_AMBIENTMATERIALSOURCE :
2137 case D3DRS_EMISSIVEMATERIALSOURCE :
2138 case D3DRS_VERTEXBLEND :
2139 case D3DRS_SOFTWAREVERTEXPROCESSING :
2140 case D3DRS_POINTSIZE :
2141 case D3DRS_POINTSIZE_MIN :
2142 case D3DRS_POINTSPRITEENABLE :
2143 case D3DRS_POINTSCALEENABLE :
2144 case D3DRS_POINTSCALE_A :
2145 case D3DRS_POINTSCALE_B :
2146 case D3DRS_POINTSCALE_C :
2147 case D3DRS_MULTISAMPLEANTIALIAS :
2148 case D3DRS_MULTISAMPLEMASK :
2149 case D3DRS_PATCHEDGESTYLE :
2150 case D3DRS_PATCHSEGMENTS :
2151 case D3DRS_DEBUGMONITORTOKEN :
2152 case D3DRS_POINTSIZE_MAX :
2153 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2154 case D3DRS_COLORWRITEENABLE :
2155 case D3DRS_TWEENFACTOR :
2156 case D3DRS_POSITIONORDER :
2157 case D3DRS_NORMALORDER :
2158 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2159 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2160 break;
2161 default:
2162 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2165 return D3D_OK;
2167 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2168 ICOM_THIS(IDirect3DDevice8Impl,iface);
2169 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2170 *pValue = This->StateBlock.renderstate[State];
2171 return D3D_OK;
2173 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2174 ICOM_THIS(IDirect3DDevice8Impl,iface);
2176 void *memory;
2178 TRACE("(%p)\n", This);
2179 if (This->isRecordingState) {
2180 TRACE("(%p) already recording! returning error\n", This);
2181 return D3DERR_INVALIDCALL;
2184 /* Allocate Storage */
2185 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2186 This->isRecordingState = TRUE;
2187 This->UpdateStateBlock = memory;
2189 return D3D_OK;
2191 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2193 ICOM_THIS(IDirect3DDevice8Impl,iface);
2194 TRACE("(%p)\n", This);
2196 if (!This->isRecordingState) {
2197 TRACE("(%p) not recording! returning error\n", This);
2198 return D3DERR_INVALIDCALL;
2201 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2202 *pToken = (DWORD) This->UpdateStateBlock;
2203 This->isRecordingState = FALSE;
2204 This->UpdateStateBlock = &This->StateBlock;
2206 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2207 return D3D_OK;
2210 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2212 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2213 int i,j;
2215 ICOM_THIS(IDirect3DDevice8Impl,iface);
2216 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2218 /* FIXME: Only apply applicable states not all states */
2220 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2222 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2224 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2225 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2226 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2227 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2230 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2231 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2233 /* TODO: Vertex Shader Constants */
2236 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2238 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2239 IDirect3DDevice8Impl_SetPixelShader(iface, pSB->PixelShader);
2241 /* TODO: Pixel Shader Constants */
2244 /* Others + Render & Texture */
2245 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2246 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2247 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2248 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2251 if (pSB->Set.Indices && pSB->Changed.Indices)
2252 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2254 if (pSB->Set.material && pSB->Changed.material)
2255 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2257 if (pSB->Set.viewport && pSB->Changed.viewport)
2258 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2260 for (i=0; i<MAX_STREAMS; i++) {
2261 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2262 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2265 for (i=0; i<MAX_CLIPPLANES; i++) {
2266 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2267 float clip[4];
2269 clip[0] = pSB->clipplane[i][0];
2270 clip[1] = pSB->clipplane[i][1];
2271 clip[2] = pSB->clipplane[i][2];
2272 clip[3] = pSB->clipplane[i][3];
2273 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2277 /* Render */
2278 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2280 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2281 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2285 /* Texture */
2286 for (j=0; j<8; j++) {
2287 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2289 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i])
2290 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2293 if (pSB->Set.textures[j] && pSB->Changed.textures[j]) {
2294 IDirect3DDevice8Impl_SetTexture(iface, j, pSB->textures[j]);
2299 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2301 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2302 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2303 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2307 for (j=0; j<8; i++) {
2308 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2310 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2311 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2312 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2316 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2318 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2319 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2320 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2324 for (j=0; j<8; i++) {
2325 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2327 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2328 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2329 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2334 } else {
2335 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2337 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2338 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2340 return D3D_OK;
2342 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2344 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2346 ICOM_THIS(IDirect3DDevice8Impl,iface);
2348 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2350 /* If not recorded, then update can just recapture */
2351 if (updateBlock->blockType != D3DSBT_RECORDED) {
2352 DWORD tmpToken;
2353 STATEBLOCK *tmpBlock;
2354 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2355 tmpBlock = (STATEBLOCK *)tmpToken;
2356 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2357 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2359 /* FIXME: This will record states of new lights! May need to have and save set_lights
2360 across this action */
2362 } else {
2363 int i,j;
2365 /* Recorded => Only update 'changed' values */
2366 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2367 updateBlock->VertexShader = This->StateBlock.VertexShader;
2368 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2371 /* TODO: Vertex Shader Constants */
2373 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2374 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2375 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2376 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2379 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2380 &updateBlock->lights[i],
2381 sizeof(D3DLIGHT8)) != 0) {
2382 TRACE("Updating lights for light %d\n", i);
2383 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2387 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2388 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2389 updateBlock->lights[i] = This->StateBlock.lights[i];
2390 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2393 /* TODO: Pixel Shader Constants */
2395 /* Others + Render & Texture */
2396 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2397 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2398 &updateBlock->transforms[i],
2399 sizeof(D3DMATRIX)) != 0) {
2400 TRACE("Updating transform %d\n", i);
2401 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2405 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2406 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2407 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2408 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2409 updateBlock->pIndexData = This->StateBlock.pIndexData;
2410 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2413 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2414 &updateBlock->material,
2415 sizeof(D3DMATERIAL8)) != 0) {
2416 TRACE("Updating material\n");
2417 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2420 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2421 &updateBlock->viewport,
2422 sizeof(D3DVIEWPORT8)) != 0) {
2423 TRACE("Updating viewport\n");
2424 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2427 for (i=0; i<MAX_STREAMS; i++) {
2428 if (updateBlock->Set.stream_source[i] &&
2429 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2430 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2431 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2432 This->StateBlock.stream_stride[i]);
2433 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2434 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2438 for (i=0; i<MAX_CLIPPLANES; i++) {
2439 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2440 &updateBlock->clipplane[i],
2441 sizeof(updateBlock->clipplane)) != 0) {
2443 TRACE("Updating clipplane %d\n", i);
2444 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2445 sizeof(updateBlock->clipplane));
2449 /* Render */
2450 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2452 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
2453 This->StateBlock.renderstate[i])) {
2454 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2455 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2459 /* Texture */
2460 for (j=0; j<8; j++) {
2461 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2463 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
2464 This->StateBlock.texture_state[j][i])) {
2465 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
2466 updateBlock->texture_state[j][i]);
2467 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
2470 if (updateBlock->Set.textures[j] && (updateBlock->textures[j] != This->StateBlock.textures[j])) {
2471 TRACE("Updating texture %d to %p (was %p)\n", j, This->StateBlock.textures[j], updateBlock->textures[j]);
2472 updateBlock->textures[j] = This->StateBlock.textures[j];
2479 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2481 return D3D_OK;
2483 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2484 ICOM_THIS(IDirect3DDevice8Impl,iface);
2485 TRACE("(%p) : freeing StateBlock %lx\n", This, Token);
2486 HeapFree(GetProcessHeap(), 0, (void *)Token);
2487 return D3D_OK;
2490 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
2491 void *memory;
2492 STATEBLOCK *s;
2493 int i,j;
2495 ICOM_THIS(IDirect3DDevice8Impl,iface);
2496 TRACE("(%p) : for type %d\n", This, Type);
2498 /* Allocate Storage */
2499 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2500 if (memory) {
2501 memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2502 } else {
2503 *pToken = 0xFFFFFFFF;
2504 return E_OUTOFMEMORY;
2506 *pToken = (DWORD) memory;
2507 s = memory;
2508 s->blockType = Type;
2510 TRACE("Updating changed flags appropriate for type %d\n", Type);
2512 if (Type == D3DSBT_ALL) {
2513 TRACE("ALL => Pretend everything has changed\n");
2514 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2516 } else if (Type == D3DSBT_PIXELSTATE) {
2518 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2520 /* TODO: Pixel Shader Constants */
2521 s->Changed.pixelShader = TRUE;
2522 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2523 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2525 for (j=0; j<8; i++) {
2526 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2527 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2531 } else if (Type == D3DSBT_VERTEXSTATE) {
2533 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2535 /* TODO: Vertex Shader Constants */
2536 s->Changed.vertexShader = TRUE;
2538 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2539 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2541 for (j=0; j<8; i++) {
2542 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2543 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2547 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2548 s->Changed.lightEnable[i] = TRUE;
2549 s->Changed.lights[i] = TRUE;
2552 } else {
2553 FIXME("Unrecognized state block type %d\n", Type);
2555 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2556 return D3D_OK;
2559 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2560 ICOM_THIS(IDirect3DDevice8Impl,iface);
2561 FIXME("(%p) : stub\n", This); return D3D_OK;
2563 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2564 ICOM_THIS(IDirect3DDevice8Impl,iface);
2565 FIXME("(%p) : stub\n", This); return D3D_OK;
2567 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2568 ICOM_THIS(IDirect3DDevice8Impl,iface);
2569 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2570 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
2571 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2572 return D3D_OK;
2574 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2576 IDirect3DBaseTexture8 *oldTxt;
2578 ICOM_THIS(IDirect3DDevice8Impl,iface);
2579 D3DRESOURCETYPE textureType;
2581 oldTxt = This->StateBlock.textures[Stage];
2582 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2584 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2585 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2586 This->UpdateStateBlock->textures[Stage] = pTexture;
2588 /* Handle recording of state blocks */
2589 if (This->isRecordingState) {
2590 TRACE("Recording... not performing anything\n");
2591 return D3D_OK;
2594 /* Make appropriate texture active */
2595 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2596 checkGLcall("glActiveTextureARB");
2598 /* Decrement the count of the previous texture */
2599 /* FIXME PERF: If old == new and not dirty then skip all this */
2600 if (oldTxt != NULL) {
2601 IDirect3DBaseTexture8Impl_Release(oldTxt);
2604 if (pTexture) {
2605 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
2607 /* Now setup the texture appropraitly */
2608 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2610 if (textureType == D3DRTYPE_TEXTURE) {
2611 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
2612 int i;
2614 /* Standard 2D texture */
2615 TRACE("Standard 2d texture\n");
2616 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
2618 /* for (i=0; i<pTexture2->levels; i++) { */
2619 i=0;
2622 if (pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2623 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2624 checkGLcall("glBindTexture");
2625 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2626 } else {
2628 if (pTexture2->surfaces[i]->textureName == 0) {
2629 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
2630 checkGLcall("glGenTextures");
2631 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2634 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2635 checkGLcall("glBindTexture");
2637 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2638 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
2639 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2640 pTexture2->surfaces[i]->allocatedMemory);
2641 glTexImage2D(GL_TEXTURE_2D, i,
2642 fmt2glintFmt(pTexture2->format),
2643 pTexture2->surfaces[i]->myDesc.Width,
2644 pTexture2->surfaces[i]->myDesc.Height,
2646 fmt2glFmt(pTexture2->format),
2647 fmt2glType(pTexture2->format),
2648 pTexture2->surfaces[i]->allocatedMemory
2650 checkGLcall("glTexImage2D");
2653 * The following enable things to work but I dont think
2654 * they all go here - FIXME! @@@
2656 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2657 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2658 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2659 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2661 pTexture2->Dirty = FALSE;
2666 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
2667 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
2668 int i;
2670 /* Standard 3D (volume) texture */
2671 TRACE("Standard 3d texture\n");
2672 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
2674 /* for (i=0; i<pTexture2->levels; i++) { */
2675 i=0;
2678 if (pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2679 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2680 checkGLcall("glBindTexture");
2681 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2682 } else {
2684 if (pTexture2->volumes[i]->textureName == 0) {
2685 glGenTextures(1, &pTexture2->volumes[i]->textureName);
2686 checkGLcall("glGenTextures");
2687 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2690 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2691 checkGLcall("glBindTexture");
2693 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2694 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
2695 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
2696 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2697 pTexture2->volumes[i]->allocatedMemory);
2698 glTexImage3D(GL_TEXTURE_3D, i,
2699 fmt2glintFmt(pTexture2->format),
2700 pTexture2->volumes[i]->myDesc.Width,
2701 pTexture2->volumes[i]->myDesc.Height,
2702 pTexture2->volumes[i]->myDesc.Depth,
2704 fmt2glFmt(pTexture2->format),
2705 fmt2glType(pTexture2->format),
2706 pTexture2->volumes[i]->allocatedMemory
2708 checkGLcall("glTexImage3D");
2711 * The following enable things to work but I dont think
2712 * they all go here - FIXME! @@@
2714 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2715 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2716 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
2717 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2718 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2720 pTexture2->Dirty = FALSE;
2724 } else {
2725 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
2727 } else {
2728 TRACE("Setting to no texture (ie default texture)\n");
2729 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
2730 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
2731 checkGLcall("glBindTexture");
2732 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
2735 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
2736 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
2737 setupTextureStates (iface, Stage);
2739 return D3D_OK;
2742 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
2743 ICOM_THIS(IDirect3DDevice8Impl,iface);
2744 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
2745 *pValue = This->StateBlock.texture_state[Stage][Type];
2746 return D3D_OK;
2749 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
2750 ICOM_THIS(IDirect3DDevice8Impl,iface);
2752 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2754 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
2756 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
2757 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
2758 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
2760 /* Handle recording of state blocks */
2761 if (This->isRecordingState) {
2762 TRACE("Recording... not performing anything\n");
2763 return D3D_OK;
2766 /* Make appropriate texture active */
2767 TRACE("Activating appropriate texture state %ld\n", Stage);
2768 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2769 checkGLcall("glActiveTextureARB");
2771 switch (Type) {
2773 case D3DTSS_MINFILTER :
2774 if (Value == D3DTEXF_POINT) {
2775 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2776 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_NEAREST");
2777 } else if (Value == D3DTEXF_LINEAR) {
2778 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2779 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_LINEAR");
2780 } else {
2781 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", Value);
2783 break;
2786 case D3DTSS_MAGFILTER :
2787 if (Value == D3DTEXF_POINT) {
2788 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2789 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
2790 } else if (Value == D3DTEXF_LINEAR) {
2791 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2792 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
2793 } else {
2794 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
2796 break;
2798 case D3DTSS_COLORARG0 :
2799 case D3DTSS_ALPHAARG0 :
2800 /* FIXME: Mesa seems to struggle setting these at the moment */
2801 break;
2803 case D3DTSS_COLORARG1 :
2804 case D3DTSS_COLORARG2 :
2805 case D3DTSS_ALPHAARG1 :
2806 case D3DTSS_ALPHAARG2 :
2808 BOOL isAlphaReplicate = FALSE;
2809 BOOL isComplement = FALSE;
2810 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
2811 int operand= GL_SRC_COLOR;
2812 int source = GL_TEXTURE;
2814 /* Catch alpha replicate */
2815 if (Value & D3DTA_ALPHAREPLICATE) {
2816 Value = Value & ~D3DTA_ALPHAREPLICATE;
2817 isAlphaReplicate = TRUE;
2820 /* Catch Complement */
2821 if (Value & D3DTA_COMPLEMENT) {
2822 Value = Value & ~D3DTA_COMPLEMENT;
2823 isComplement = TRUE;
2826 /* Calculate the operand */
2827 if (isAlphaReplicate && !isComplement) {
2828 operand = GL_SRC_ALPHA;
2829 } else if (isAlphaReplicate && isComplement) {
2830 operand = GL_ONE_MINUS_SRC_ALPHA;
2831 } else if (isComplement) {
2832 if (isAlphaArg) {
2833 operand = GL_ONE_MINUS_SRC_COLOR;
2834 } else {
2835 operand = GL_ONE_MINUS_SRC_ALPHA;
2837 } else {
2838 if (isAlphaArg) {
2839 operand = GL_SRC_ALPHA;
2840 } else {
2841 operand = GL_SRC_COLOR;
2845 /* Calculate the source */
2846 switch (Value) {
2847 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
2848 break;
2849 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
2850 break;
2851 case D3DTA_TEXTURE: source = GL_TEXTURE;
2852 break;
2853 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
2854 break;
2856 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
2857 isnt supported until base GL supports it
2858 There is no concept of temp registers as far as I can tell */
2860 default:
2861 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
2864 if (isAlphaArg) {
2865 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
2866 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
2867 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
2868 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
2869 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
2870 } else {
2871 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
2872 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
2873 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
2874 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
2875 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
2878 break;
2880 case D3DTSS_ALPHAOP :
2881 case D3DTSS_COLOROP :
2884 int Scale = 1;
2885 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
2887 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
2888 /* TODO: Disable by making this and all later levels disabled */
2889 glDisable(GL_TEXTURE_1D);
2890 checkGLcall("Disable GL_TEXTURE_1D");
2891 glDisable(GL_TEXTURE_2D);
2892 checkGLcall("Disable GL_TEXTURE_2D");
2893 glDisable(GL_TEXTURE_3D);
2894 checkGLcall("Disable GL_TEXTURE_3D");
2895 } else {
2897 /* Enable only the appropriate texture dimension */
2898 if (Type==D3DTSS_COLOROP) {
2899 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
2900 glEnable(GL_TEXTURE_1D);
2901 checkGLcall("Enable GL_TEXTURE_1D");
2902 } else {
2903 glDisable(GL_TEXTURE_1D);
2904 checkGLcall("Disable GL_TEXTURE_1D");
2906 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
2907 glEnable(GL_TEXTURE_2D);
2908 checkGLcall("Enable GL_TEXTURE_2D");
2909 } else {
2910 glDisable(GL_TEXTURE_2D);
2911 checkGLcall("Disable GL_TEXTURE_2D");
2913 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
2914 glEnable(GL_TEXTURE_3D);
2915 checkGLcall("Enable GL_TEXTURE_3D");
2916 } else {
2917 glDisable(GL_TEXTURE_3D);
2918 checkGLcall("Disable GL_TEXTURE_3D");
2922 /* Now set up the operand correctly */
2923 switch (Value) {
2924 case D3DTOP_DISABLE :
2925 /* Contrary to the docs, alpha can be disabled when colorop is enabled
2926 and it works, so ignore this op */
2927 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
2928 break;
2930 case D3DTOP_SELECTARG1 :
2931 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
2932 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
2933 break;
2935 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
2936 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
2937 case D3DTOP_MODULATE :
2939 /* Correct scale */
2940 if (Type == D3DTSS_ALPHAOP) {
2941 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
2942 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
2943 } else {
2944 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
2945 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
2947 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
2948 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
2949 break;
2951 case D3DTOP_ADD :
2952 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
2953 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
2954 break;
2956 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
2957 case D3DTOP_ADDSIGNED :
2958 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
2959 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
2960 break;
2962 case D3DTOP_DOTPRODUCT3 :
2963 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
2964 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
2965 break;*/
2967 case D3DTOP_SUBTRACT :
2968 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
2969 case D3DTOP_SELECTARG2 :
2970 /* GL_REPLACE, swap args 0 and 1? */
2971 case D3DTOP_ADDSMOOTH :
2972 case D3DTOP_BLENDDIFFUSEALPHA :
2973 case D3DTOP_BLENDTEXTUREALPHA :
2974 case D3DTOP_BLENDFACTORALPHA :
2975 case D3DTOP_BLENDTEXTUREALPHAPM :
2976 case D3DTOP_BLENDCURRENTALPHA :
2977 case D3DTOP_PREMODULATE :
2978 case D3DTOP_MODULATEALPHA_ADDCOLOR :
2979 case D3DTOP_MODULATECOLOR_ADDALPHA :
2980 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
2981 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
2982 case D3DTOP_BUMPENVMAP :
2983 case D3DTOP_BUMPENVMAPLUMINANCE :
2984 case D3DTOP_MULTIPLYADD :
2985 case D3DTOP_LERP :
2986 default:
2987 FIXME("Unhandled texture operation %ld\n", Value);
2990 break;
2993 /* Unhandled */
2994 case D3DTSS_BUMPENVMAT00 :
2995 case D3DTSS_BUMPENVMAT01 :
2996 case D3DTSS_BUMPENVMAT10 :
2997 case D3DTSS_BUMPENVMAT11 :
2998 case D3DTSS_TEXCOORDINDEX :
2999 case D3DTSS_ADDRESSU :
3000 case D3DTSS_ADDRESSV :
3001 case D3DTSS_BORDERCOLOR :
3002 case D3DTSS_MIPFILTER :
3003 case D3DTSS_MIPMAPLODBIAS :
3004 case D3DTSS_MAXMIPLEVEL :
3005 case D3DTSS_MAXANISOTROPY :
3006 case D3DTSS_BUMPENVLSCALE :
3007 case D3DTSS_BUMPENVLOFFSET :
3008 case D3DTSS_TEXTURETRANSFORMFLAGS :
3009 case D3DTSS_ADDRESSW :
3010 case D3DTSS_RESULTARG :
3011 default:
3012 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3013 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3015 return D3D_OK;
3017 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3018 ICOM_THIS(IDirect3DDevice8Impl,iface);
3019 FIXME("(%p) : stub\n", This); return D3D_OK;
3021 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3022 ICOM_THIS(IDirect3DDevice8Impl,iface);
3023 FIXME("(%p) : stub\n", This); return D3D_OK;
3025 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3026 ICOM_THIS(IDirect3DDevice8Impl,iface);
3027 FIXME("(%p) : stub\n", This); return D3D_OK;
3029 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3030 ICOM_THIS(IDirect3DDevice8Impl,iface);
3031 FIXME("(%p) : stub\n", This); return D3D_OK;
3033 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3034 ICOM_THIS(IDirect3DDevice8Impl,iface);
3035 FIXME("(%p) : stub\n", This); return D3D_OK;
3037 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3038 ICOM_THIS(IDirect3DDevice8Impl,iface);
3039 FIXME("(%p) : stub\n", This); return D3D_OK;
3041 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3043 IDirect3DVertexBuffer8 *pVB;
3045 ICOM_THIS(IDirect3DDevice8Impl,iface);
3046 pVB = This->StateBlock.stream_source[0];
3048 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3050 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3051 This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL);
3053 return D3D_OK;
3055 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3056 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3057 UINT idxStride = 2;
3058 IDirect3DIndexBuffer8 *pIB;
3059 IDirect3DVertexBuffer8 *pVB;
3060 D3DINDEXBUFFER_DESC IdxBufDsc;
3062 ICOM_THIS(IDirect3DDevice8Impl,iface);
3063 pIB = This->StateBlock.pIndexData;
3064 pVB = This->StateBlock.stream_source[0];
3066 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3067 minIndex, NumVertices, startIndex, primCount);
3069 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3070 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3071 idxStride = 2;
3072 } else {
3073 idxStride = 4;
3076 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3077 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory);
3079 return D3D_OK;
3081 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3082 ICOM_THIS(IDirect3DDevice8Impl,iface);
3084 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3086 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3088 This->StateBlock.stream_source[0] = NULL;
3089 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3090 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3091 0, 0, 0, NULL);
3092 This->StateBlock.stream_stride[0] = 0;
3094 /*stream zero settings set to null at end */
3095 return D3D_OK;
3097 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3098 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3099 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3100 UINT VertexStreamZeroStride) {
3101 int idxStride;
3102 ICOM_THIS(IDirect3DDevice8Impl,iface);
3103 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3104 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3106 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3107 if (IndexDataFormat == D3DFMT_INDEX16) {
3108 idxStride = 2;
3109 } else {
3110 idxStride = 4;
3113 This->StateBlock.stream_source[0] = NULL;
3114 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3115 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3116 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData);
3118 /*stream zero settings set to null at end */
3119 This->StateBlock.stream_stride[0] = 0;
3120 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3122 return D3D_OK;
3124 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3125 ICOM_THIS(IDirect3DDevice8Impl,iface);
3126 FIXME("(%p) : stub\n", This); return D3D_OK;
3128 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3129 ICOM_THIS(IDirect3DDevice8Impl,iface);
3130 VERTEXSHADER8* object;
3131 UINT i;
3133 FIXME("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3134 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3135 return D3DERR_INVALIDCALL;
3137 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(VERTEXSHADER8*); ++i) ;
3138 if (i >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) {
3139 return D3DERR_OUTOFVIDEOMEMORY;
3141 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERTEXSHADER8));
3142 if (NULL == object) {
3143 return D3DERR_OUTOFVIDEOMEMORY;
3146 object->usage = Usage;
3147 object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADER8Data));
3149 VertexShaders[i] = object;
3150 *pHandle = VS_HIGHESTFIXEDFXF + i;
3152 object->decl = pDeclaration;
3153 object->function = pFunction;
3156 for (i = 0; 0xFFFFFFFF != pDeclaration[i]; ++i) ;
3157 object->declLength = i + 1;
3158 if (NULL != pFunction) {
3159 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3160 object->functionLength = i + 1;
3161 } else {
3162 object->functionLength = 1; // no Function defined use fixed function vertex processing
3165 vshader_decl_parse(object);
3166 vshader_program_parse(object);
3168 return D3D_OK;
3170 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3171 ICOM_THIS(IDirect3DDevice8Impl,iface);
3173 This->UpdateStateBlock->VertexShader = Handle;
3174 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3175 This->UpdateStateBlock->Set.vertexShader = TRUE;
3177 /* Handle recording of state blocks */
3178 if (This->isRecordingState) {
3179 TRACE("Recording... not performing anything\n");
3180 return D3D_OK;
3182 if (Handle <= VS_HIGHESTFIXEDFXF) {
3183 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3184 return D3D_OK;
3185 } else {
3186 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3187 return D3D_OK;
3190 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3191 ICOM_THIS(IDirect3DDevice8Impl,iface);
3192 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock.VertexShader);
3193 *pHandle = This->StateBlock.VertexShader;
3194 return D3D_OK;
3197 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3198 ICOM_THIS(IDirect3DDevice8Impl,iface);
3199 VERTEXSHADER8* object;
3201 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3202 return D3DERR_INVALIDCALL;
3204 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3205 if (NULL == object) {
3206 return D3DERR_INVALIDCALL;
3208 TRACE("(%p) : freing VertexShader %p\n", This, object);
3209 /* TODO: check validity of object */
3210 if (NULL != object->data) HeapFree(GetProcessHeap(), 0, (void *)object->data);
3211 HeapFree(GetProcessHeap(), 0, (void *)object);
3212 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3213 return D3D_OK;
3216 #define VERTEX_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
3218 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3219 ICOM_THIS(IDirect3DDevice8Impl,iface);
3220 VERTEXSHADER8* object;
3221 DWORD Handle = This->UpdateStateBlock->VertexShader;
3223 /* FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); */
3224 if (Register + ConstantCount > VSHADER_MAX_CONSTANTS) {
3225 return D3DERR_INVALIDCALL;
3227 object = VERTEX_SHADER(Handle);
3228 if (NULL == object || NULL == pConstantData) {
3229 return D3DERR_INVALIDCALL;
3231 if (NULL == object->data) { /* temporary while datas not supported */
3232 FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
3233 return D3DERR_INVALIDCALL;
3235 memcpy(object->data->C + Register, pConstantData, ConstantCount * sizeof(SHADER8Vector));
3237 return D3D_OK;
3239 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3240 ICOM_THIS(IDirect3DDevice8Impl,iface);
3241 VERTEXSHADER8* object;
3242 DWORD Handle = This->UpdateStateBlock->VertexShader;
3244 FIXME("(%p) : VertexShader_GetConstant not fully supported yet\n", This);
3246 if (Register + ConstantCount > VSHADER_MAX_CONSTANTS) {
3247 return D3DERR_INVALIDCALL;
3249 object = VERTEX_SHADER(Handle);
3250 if (NULL == object || NULL == pConstantData) {
3251 return D3DERR_INVALIDCALL;
3253 if (NULL == object->data) { /* temporary while datas not supported */
3254 return D3DERR_INVALIDCALL;
3256 memcpy(pConstantData, object->data->C + Register, ConstantCount * sizeof(SHADER8Vector));
3258 return D3D_OK;
3260 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3261 ICOM_THIS(IDirect3DDevice8Impl,iface);
3262 VERTEXSHADER8* object;
3264 object = VERTEX_SHADER(Handle);
3265 if (NULL == object) {
3266 return D3DERR_INVALIDCALL;
3268 if (NULL == pData) {
3269 *pSizeOfData = object->declLength;
3270 return D3D_OK;
3272 if (*pSizeOfData < object->declLength) {
3273 *pSizeOfData = object->declLength;
3274 return D3DERR_MOREDATA;
3276 TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
3277 memcpy(pData, object->decl, object->declLength);
3278 return D3D_OK;
3280 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3281 ICOM_THIS(IDirect3DDevice8Impl,iface);
3282 VERTEXSHADER8* object;
3284 object = VERTEX_SHADER(Handle);
3285 if (NULL == object) {
3286 return D3DERR_INVALIDCALL;
3288 if (NULL == pData) {
3289 *pSizeOfData = object->functionLength;
3290 return D3D_OK;
3292 if (*pSizeOfData < object->functionLength) {
3293 *pSizeOfData = object->functionLength;
3294 return D3DERR_MOREDATA;
3296 if (NULL == object->function) { /* no function defined */
3297 TRACE("(%p) : GetVertexShaderFunction no User Function defined using NULL to %p\n", This, pData);
3298 ((DWORD *) pData) = NULL;
3299 } else {
3300 TRACE("(%p) : GetVertexShaderFunction copying to %p\n", This, pData);
3301 memcpy(pData, object->function, object->functionLength);
3303 return D3D_OK;
3306 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3307 ICOM_THIS(IDirect3DDevice8Impl,iface);
3308 IDirect3DIndexBuffer8 *oldIdxs;
3310 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3311 oldIdxs = This->StateBlock.pIndexData;
3313 This->UpdateStateBlock->Changed.Indices = TRUE;
3314 This->UpdateStateBlock->Set.Indices = TRUE;
3315 This->UpdateStateBlock->pIndexData = pIndexData;
3316 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3318 /* Handle recording of state blocks */
3319 if (This->isRecordingState) {
3320 TRACE("Recording... not performing anything\n");
3321 return D3D_OK;
3324 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3325 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3326 return D3D_OK;
3328 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3329 ICOM_THIS(IDirect3DDevice8Impl,iface);
3330 FIXME("(%p) : stub\n", This);
3332 *ppIndexData = This->StateBlock.pIndexData;
3333 /* up ref count on ppindexdata */
3334 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3335 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3337 return D3D_OK;
3339 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3340 ICOM_THIS(IDirect3DDevice8Impl,iface);
3341 PIXELSHADER8* object;
3342 UINT i;
3344 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3345 if (NULL == pFunction || NULL == pHandle) {
3346 return D3DERR_INVALIDCALL;
3348 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(PIXELSHADER8*); ++i) ;
3349 if (i >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) {
3350 return D3DERR_OUTOFVIDEOMEMORY;
3352 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PIXELSHADER8));
3353 if (NULL == object) {
3354 return D3DERR_OUTOFVIDEOMEMORY;
3357 object->data = NULL; /* TODO */
3359 PixelShaders[i] = object;
3360 *pHandle = VS_HIGHESTFIXEDFXF + i;
3362 object->function = pFunction;
3363 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3364 object->functionLength = i + 1;
3366 return D3D_OK;
3368 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3369 ICOM_THIS(IDirect3DDevice8Impl,iface);
3371 This->UpdateStateBlock->PixelShader = Handle;
3372 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3373 This->UpdateStateBlock->Set.pixelShader = TRUE;
3375 /* Handle recording of state blocks */
3376 if (This->isRecordingState) {
3377 TRACE("Recording... not performing anything\n");
3378 return D3D_OK;
3381 /* FIXME: Quieten when not being used */
3382 if (Handle != 0) {
3383 FIXME("(%p) : stub %ld\n", This, Handle);
3384 } else {
3385 TRACE("(%p) : stub %ld\n", This, Handle);
3388 return D3D_OK;
3390 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3391 ICOM_THIS(IDirect3DDevice8Impl,iface);
3392 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock.PixelShader);
3393 *pHandle = This->StateBlock.PixelShader;
3394 return D3D_OK;
3397 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3398 ICOM_THIS(IDirect3DDevice8Impl,iface);
3399 PIXELSHADER8* object;
3401 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3402 return D3DERR_INVALIDCALL;
3404 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3405 TRACE("(%p) : freeing PixelShader %p\n", This, object);
3406 /* TODO: check validity of object before free */
3407 HeapFree(GetProcessHeap(), 0, (void *)object);
3408 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3409 return D3D_OK;
3411 #define PIXEL_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
3413 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
3414 ICOM_THIS(IDirect3DDevice8Impl,iface);
3415 FIXME("(%p) : stub\n", This);
3416 return D3D_OK;
3418 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
3419 ICOM_THIS(IDirect3DDevice8Impl,iface);
3420 FIXME("(%p) : stub\n", This);
3421 return D3D_OK;
3423 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3424 ICOM_THIS(IDirect3DDevice8Impl,iface);
3425 PIXELSHADER8* object;
3427 object = PIXEL_SHADER(Handle);
3428 if (NULL == object) {
3429 return D3DERR_INVALIDCALL;
3431 if (NULL == pData) {
3432 *pSizeOfData = object->functionLength;
3433 return D3D_OK;
3435 if (*pSizeOfData < object->functionLength) {
3436 *pSizeOfData = object->functionLength;
3437 return D3DERR_MOREDATA;
3439 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
3440 memcpy(pData, object->function, object->functionLength);
3441 return D3D_OK;
3443 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3444 ICOM_THIS(IDirect3DDevice8Impl,iface);
3445 FIXME("(%p) : stub\n", This); return D3D_OK;
3447 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3448 ICOM_THIS(IDirect3DDevice8Impl,iface);
3449 FIXME("(%p) : stub\n", This); return D3D_OK;
3451 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3452 ICOM_THIS(IDirect3DDevice8Impl,iface);
3453 FIXME("(%p) : stub\n", This); return D3D_OK;
3456 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3457 IDirect3DVertexBuffer8 *oldSrc;
3458 ICOM_THIS(IDirect3DDevice8Impl,iface);
3460 oldSrc = This->StateBlock.stream_source[StreamNumber];
3461 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3463 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3464 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3465 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3466 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3468 /* Handle recording of state blocks */
3469 if (This->isRecordingState) {
3470 TRACE("Recording... not performing anything\n");
3471 return D3D_OK;
3474 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3475 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3476 return D3D_OK;
3478 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3479 ICOM_THIS(IDirect3DDevice8Impl,iface);
3480 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3481 *pStream = This->StateBlock.stream_source[StreamNumber];
3482 *pStride = This->StateBlock.stream_stride[StreamNumber];
3483 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3484 return D3D_OK;
3488 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3490 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3491 IDirect3DDevice8Impl_QueryInterface,
3492 IDirect3DDevice8Impl_AddRef,
3493 IDirect3DDevice8Impl_Release,
3494 IDirect3DDevice8Impl_TestCooperativeLevel,
3495 IDirect3DDevice8Impl_GetAvailableTextureMem,
3496 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3497 IDirect3DDevice8Impl_GetDirect3D,
3498 IDirect3DDevice8Impl_GetDeviceCaps,
3499 IDirect3DDevice8Impl_GetDisplayMode,
3500 IDirect3DDevice8Impl_GetCreationParameters,
3501 IDirect3DDevice8Impl_SetCursorProperties,
3502 IDirect3DDevice8Impl_SetCursorPosition,
3503 IDirect3DDevice8Impl_ShowCursor,
3504 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3505 IDirect3DDevice8Impl_Reset,
3506 IDirect3DDevice8Impl_Present,
3507 IDirect3DDevice8Impl_GetBackBuffer,
3508 IDirect3DDevice8Impl_GetRasterStatus,
3509 IDirect3DDevice8Impl_SetGammaRamp,
3510 IDirect3DDevice8Impl_GetGammaRamp,
3511 IDirect3DDevice8Impl_CreateTexture,
3512 IDirect3DDevice8Impl_CreateVolumeTexture,
3513 IDirect3DDevice8Impl_CreateCubeTexture,
3514 IDirect3DDevice8Impl_CreateVertexBuffer,
3515 IDirect3DDevice8Impl_CreateIndexBuffer,
3516 IDirect3DDevice8Impl_CreateRenderTarget,
3517 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3518 IDirect3DDevice8Impl_CreateImageSurface,
3519 IDirect3DDevice8Impl_CopyRects,
3520 IDirect3DDevice8Impl_UpdateTexture,
3521 IDirect3DDevice8Impl_GetFrontBuffer,
3522 IDirect3DDevice8Impl_SetRenderTarget,
3523 IDirect3DDevice8Impl_GetRenderTarget,
3524 IDirect3DDevice8Impl_GetDepthStencilSurface,
3525 IDirect3DDevice8Impl_BeginScene,
3526 IDirect3DDevice8Impl_EndScene,
3527 IDirect3DDevice8Impl_Clear,
3528 IDirect3DDevice8Impl_SetTransform,
3529 IDirect3DDevice8Impl_GetTransform,
3530 IDirect3DDevice8Impl_MultiplyTransform,
3531 IDirect3DDevice8Impl_SetViewport,
3532 IDirect3DDevice8Impl_GetViewport,
3533 IDirect3DDevice8Impl_SetMaterial,
3534 IDirect3DDevice8Impl_GetMaterial,
3535 IDirect3DDevice8Impl_SetLight,
3536 IDirect3DDevice8Impl_GetLight,
3537 IDirect3DDevice8Impl_LightEnable,
3538 IDirect3DDevice8Impl_GetLightEnable,
3539 IDirect3DDevice8Impl_SetClipPlane,
3540 IDirect3DDevice8Impl_GetClipPlane,
3541 IDirect3DDevice8Impl_SetRenderState,
3542 IDirect3DDevice8Impl_GetRenderState,
3543 IDirect3DDevice8Impl_BeginStateBlock,
3544 IDirect3DDevice8Impl_EndStateBlock,
3545 IDirect3DDevice8Impl_ApplyStateBlock,
3546 IDirect3DDevice8Impl_CaptureStateBlock,
3547 IDirect3DDevice8Impl_DeleteStateBlock,
3548 IDirect3DDevice8Impl_CreateStateBlock,
3549 IDirect3DDevice8Impl_SetClipStatus,
3550 IDirect3DDevice8Impl_GetClipStatus,
3551 IDirect3DDevice8Impl_GetTexture,
3552 IDirect3DDevice8Impl_SetTexture,
3553 IDirect3DDevice8Impl_GetTextureStageState,
3554 IDirect3DDevice8Impl_SetTextureStageState,
3555 IDirect3DDevice8Impl_ValidateDevice,
3556 IDirect3DDevice8Impl_GetInfo,
3557 IDirect3DDevice8Impl_SetPaletteEntries,
3558 IDirect3DDevice8Impl_GetPaletteEntries,
3559 IDirect3DDevice8Impl_SetCurrentTexturePalette,
3560 IDirect3DDevice8Impl_GetCurrentTexturePalette,
3561 IDirect3DDevice8Impl_DrawPrimitive,
3562 IDirect3DDevice8Impl_DrawIndexedPrimitive,
3563 IDirect3DDevice8Impl_DrawPrimitiveUP,
3564 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
3565 IDirect3DDevice8Impl_ProcessVertices,
3566 IDirect3DDevice8Impl_CreateVertexShader,
3567 IDirect3DDevice8Impl_SetVertexShader,
3568 IDirect3DDevice8Impl_GetVertexShader,
3569 IDirect3DDevice8Impl_DeleteVertexShader,
3570 IDirect3DDevice8Impl_SetVertexShaderConstant,
3571 IDirect3DDevice8Impl_GetVertexShaderConstant,
3572 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
3573 IDirect3DDevice8Impl_GetVertexShaderFunction,
3574 IDirect3DDevice8Impl_SetStreamSource,
3575 IDirect3DDevice8Impl_GetStreamSource,
3576 IDirect3DDevice8Impl_SetIndices,
3577 IDirect3DDevice8Impl_GetIndices,
3578 IDirect3DDevice8Impl_CreatePixelShader,
3579 IDirect3DDevice8Impl_SetPixelShader,
3580 IDirect3DDevice8Impl_GetPixelShader,
3581 IDirect3DDevice8Impl_DeletePixelShader,
3582 IDirect3DDevice8Impl_SetPixelShaderConstant,
3583 IDirect3DDevice8Impl_GetPixelShaderConstant,
3584 IDirect3DDevice8Impl_GetPixelShaderFunction,
3585 IDirect3DDevice8Impl_DrawRectPatch,
3586 IDirect3DDevice8Impl_DrawTriPatch,
3587 IDirect3DDevice8Impl_DeletePatch
3590 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
3591 D3DLINEPATTERN lp;
3592 int i;
3594 ICOM_THIS(IDirect3DDevice8Impl,iface);
3596 /* Note this may have a large overhead but it should only be executed
3597 once, in order to initialize the complete state of the device and
3598 all opengl equivalents */
3599 TRACE("-----------------------> Setting up device defaults...\n");
3600 This->StateBlock.blockType = D3DSBT_ALL;
3602 /* FIXME: Set some of the defaults for lights, transforms etc */
3603 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
3604 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
3605 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
3607 /* Render states: */
3608 if (This->PresentParms.EnableAutoDepthStencil) {
3609 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
3610 } else {
3611 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
3613 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
3614 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3615 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
3616 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
3617 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
3618 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
3619 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
3620 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
3621 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
3622 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3623 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
3624 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
3625 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
3626 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
3627 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
3628 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
3629 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
3630 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
3631 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3632 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
3633 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
3634 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
3635 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
3636 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
3637 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
3638 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
3639 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
3640 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
3641 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
3642 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
3643 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
3644 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
3645 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
3646 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
3647 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
3648 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
3649 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
3650 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
3651 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
3652 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
3653 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
3654 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
3655 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
3656 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
3657 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
3658 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3659 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
3660 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
3661 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
3662 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3663 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
3664 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
3665 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
3666 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
3667 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
3668 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
3669 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
3670 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
3671 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
3672 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
3673 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
3674 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
3675 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
3676 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
3677 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
3678 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
3679 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
3680 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
3681 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
3682 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
3683 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
3684 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
3685 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
3686 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
3687 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
3689 /* Texture Stage States - Put directly into state block, we will call function below */
3690 for (i=0; i<8;i++) {
3691 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
3692 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
3693 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
3694 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
3695 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
3696 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
3697 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
3698 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
3699 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
3700 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
3701 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
3702 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
3703 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
3704 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
3705 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
3706 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
3707 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
3708 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
3709 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
3710 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
3711 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
3712 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
3713 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
3714 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
3715 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
3716 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
3717 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
3720 /* Under DirectX you can have texture stage operations even if no texture is
3721 bound, whereas opengl will only do texture operations when a valid texture is
3722 bound. We emulate this by creating 8 dummy textures and binding them to each
3723 texture stage, but disable all stages by default. Hence if a stage is enabled
3724 then the default texture will kick in until replaced by a SetTexture call */
3726 for (i=0; i<8; i++) {
3727 GLubyte white = 255;
3729 /* Note this avoids calling settexture, so pretend it has been called */
3730 This->StateBlock.Set.textures[i] = TRUE;
3731 This->StateBlock.Changed.textures[i] = TRUE;
3732 This->StateBlock.textures[i] = NULL;
3734 /* Make appropriate texture active */
3735 glActiveTextureARB(GL_TEXTURE0_ARB + i);
3736 checkGLcall("glActiveTextureARB");
3738 /* Generate an opengl texture name */
3739 glGenTextures(1, &This->dummyTextureName[i]);
3740 checkGLcall("glGenTextures");
3741 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
3743 /* Generate a dummy 1d texture */
3744 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
3745 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
3746 checkGLcall("glBindTexture");
3748 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
3749 checkGLcall("glTexImage1D");
3751 /* Reapply all the texture state information to this texture */
3752 setupTextureStates(iface, i);
3755 TRACE("-----------------------> Device defaults now set up...\n");
3760 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
3761 D3DRS_ALPHABLENDENABLE ,
3762 D3DRS_ALPHAFUNC ,
3763 D3DRS_ALPHAREF ,
3764 D3DRS_ALPHATESTENABLE ,
3765 D3DRS_BLENDOP ,
3766 D3DRS_COLORWRITEENABLE ,
3767 D3DRS_DESTBLEND ,
3768 D3DRS_DITHERENABLE ,
3769 D3DRS_EDGEANTIALIAS ,
3770 D3DRS_FILLMODE ,
3771 D3DRS_FOGDENSITY ,
3772 D3DRS_FOGEND ,
3773 D3DRS_FOGSTART ,
3774 D3DRS_LASTPIXEL ,
3775 D3DRS_LINEPATTERN ,
3776 D3DRS_SHADEMODE ,
3777 D3DRS_SRCBLEND ,
3778 D3DRS_STENCILENABLE ,
3779 D3DRS_STENCILFAIL ,
3780 D3DRS_STENCILFUNC ,
3781 D3DRS_STENCILMASK ,
3782 D3DRS_STENCILPASS ,
3783 D3DRS_STENCILREF ,
3784 D3DRS_STENCILWRITEMASK ,
3785 D3DRS_STENCILZFAIL ,
3786 D3DRS_TEXTUREFACTOR ,
3787 D3DRS_WRAP0 ,
3788 D3DRS_WRAP1 ,
3789 D3DRS_WRAP2 ,
3790 D3DRS_WRAP3 ,
3791 D3DRS_WRAP4 ,
3792 D3DRS_WRAP5 ,
3793 D3DRS_WRAP6 ,
3794 D3DRS_WRAP7 ,
3795 D3DRS_ZBIAS ,
3796 D3DRS_ZENABLE ,
3797 D3DRS_ZFUNC ,
3798 D3DRS_ZWRITEENABLE
3801 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
3802 D3DTSS_ADDRESSU ,
3803 D3DTSS_ADDRESSV ,
3804 D3DTSS_ADDRESSW ,
3805 D3DTSS_ALPHAARG0 ,
3806 D3DTSS_ALPHAARG1 ,
3807 D3DTSS_ALPHAARG2 ,
3808 D3DTSS_ALPHAOP ,
3809 D3DTSS_BORDERCOLOR ,
3810 D3DTSS_BUMPENVLOFFSET ,
3811 D3DTSS_BUMPENVLSCALE ,
3812 D3DTSS_BUMPENVMAT00 ,
3813 D3DTSS_BUMPENVMAT01 ,
3814 D3DTSS_BUMPENVMAT10 ,
3815 D3DTSS_BUMPENVMAT11 ,
3816 D3DTSS_COLORARG0 ,
3817 D3DTSS_COLORARG1 ,
3818 D3DTSS_COLORARG2 ,
3819 D3DTSS_COLOROP ,
3820 D3DTSS_MAGFILTER ,
3821 D3DTSS_MAXANISOTROPY ,
3822 D3DTSS_MAXMIPLEVEL ,
3823 D3DTSS_MINFILTER ,
3824 D3DTSS_MIPFILTER ,
3825 D3DTSS_MIPMAPLODBIAS ,
3826 D3DTSS_RESULTARG ,
3827 D3DTSS_TEXCOORDINDEX ,
3828 D3DTSS_TEXTURETRANSFORMFLAGS
3831 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
3832 D3DRS_AMBIENT ,
3833 D3DRS_AMBIENTMATERIALSOURCE ,
3834 D3DRS_CLIPPING ,
3835 D3DRS_CLIPPLANEENABLE ,
3836 D3DRS_COLORVERTEX ,
3837 D3DRS_DIFFUSEMATERIALSOURCE ,
3838 D3DRS_EMISSIVEMATERIALSOURCE ,
3839 D3DRS_FOGDENSITY ,
3840 D3DRS_FOGEND ,
3841 D3DRS_FOGSTART ,
3842 D3DRS_FOGTABLEMODE ,
3843 D3DRS_FOGVERTEXMODE ,
3844 D3DRS_INDEXEDVERTEXBLENDENABLE ,
3845 D3DRS_LIGHTING ,
3846 D3DRS_LOCALVIEWER ,
3847 D3DRS_MULTISAMPLEANTIALIAS ,
3848 D3DRS_MULTISAMPLEMASK ,
3849 D3DRS_NORMALIZENORMALS ,
3850 D3DRS_PATCHEDGESTYLE ,
3851 D3DRS_PATCHSEGMENTS ,
3852 D3DRS_POINTSCALE_A ,
3853 D3DRS_POINTSCALE_B ,
3854 D3DRS_POINTSCALE_C ,
3855 D3DRS_POINTSCALEENABLE ,
3856 D3DRS_POINTSIZE ,
3857 D3DRS_POINTSIZE_MAX ,
3858 D3DRS_POINTSIZE_MIN ,
3859 D3DRS_POINTSPRITEENABLE ,
3860 D3DRS_RANGEFOGENABLE ,
3861 D3DRS_SOFTWAREVERTEXPROCESSING ,
3862 D3DRS_SPECULARMATERIALSOURCE ,
3863 D3DRS_TWEENFACTOR ,
3864 D3DRS_VERTEXBLEND
3867 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
3868 D3DTSS_TEXCOORDINDEX ,
3869 D3DTSS_TEXTURETRANSFORMFLAGS