The simple bits of fog.
[wine/multimedia.git] / dlls / d3d8 / device.c
blob1017aa4174c5a27aaef95391021cb1d1b4e69537
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 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2157 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2158 break;
2159 default:
2160 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2163 return D3D_OK;
2165 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2166 ICOM_THIS(IDirect3DDevice8Impl,iface);
2167 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2168 *pValue = This->StateBlock.renderstate[State];
2169 return D3D_OK;
2171 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2172 ICOM_THIS(IDirect3DDevice8Impl,iface);
2174 void *memory;
2176 TRACE("(%p)\n", This);
2177 if (This->isRecordingState) {
2178 TRACE("(%p) already recording! returning error\n", This);
2179 return D3DERR_INVALIDCALL;
2182 /* Allocate Storage */
2183 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2184 This->isRecordingState = TRUE;
2185 This->UpdateStateBlock = memory;
2187 return D3D_OK;
2189 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2191 ICOM_THIS(IDirect3DDevice8Impl,iface);
2192 TRACE("(%p)\n", This);
2194 if (!This->isRecordingState) {
2195 TRACE("(%p) not recording! returning error\n", This);
2196 return D3DERR_INVALIDCALL;
2199 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2200 *pToken = (DWORD) This->UpdateStateBlock;
2201 This->isRecordingState = FALSE;
2202 This->UpdateStateBlock = &This->StateBlock;
2204 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2205 return D3D_OK;
2208 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2210 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2211 int i,j;
2213 ICOM_THIS(IDirect3DDevice8Impl,iface);
2214 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2216 /* FIXME: Only apply applicable states not all states */
2218 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2220 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2222 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2223 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2224 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2225 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2228 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2229 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2231 /* TODO: Vertex Shader Constants */
2234 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2236 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2237 IDirect3DDevice8Impl_SetPixelShader(iface, pSB->PixelShader);
2239 /* TODO: Pixel Shader Constants */
2242 /* Others + Render & Texture */
2243 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2244 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2245 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2246 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2249 if (pSB->Set.Indices && pSB->Changed.Indices)
2250 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2252 if (pSB->Set.material && pSB->Changed.material)
2253 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2255 if (pSB->Set.viewport && pSB->Changed.viewport)
2256 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2258 for (i=0; i<MAX_STREAMS; i++) {
2259 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2260 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2263 for (i=0; i<MAX_CLIPPLANES; i++) {
2264 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2265 float clip[4];
2267 clip[0] = pSB->clipplane[i][0];
2268 clip[1] = pSB->clipplane[i][1];
2269 clip[2] = pSB->clipplane[i][2];
2270 clip[3] = pSB->clipplane[i][3];
2271 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2275 /* Render */
2276 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2278 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2279 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2283 /* Texture */
2284 for (j=0; j<8; j++) {
2285 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2287 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i])
2288 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2291 if (pSB->Set.textures[j] && pSB->Changed.textures[j]) {
2292 IDirect3DDevice8Impl_SetTexture(iface, j, pSB->textures[j]);
2297 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2299 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2300 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2301 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2305 for (j=0; j<8; i++) {
2306 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2308 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2309 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2310 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2314 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2316 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2317 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2318 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2322 for (j=0; j<8; i++) {
2323 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2325 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2326 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2327 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2332 } else {
2333 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2335 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2336 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2338 return D3D_OK;
2340 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2342 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2344 ICOM_THIS(IDirect3DDevice8Impl,iface);
2346 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2348 /* If not recorded, then update can just recapture */
2349 if (updateBlock->blockType != D3DSBT_RECORDED) {
2350 DWORD tmpToken;
2351 STATEBLOCK *tmpBlock;
2352 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2353 tmpBlock = (STATEBLOCK *)tmpToken;
2354 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2355 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2357 /* FIXME: This will record states of new lights! May need to have and save set_lights
2358 across this action */
2360 } else {
2361 int i,j;
2363 /* Recorded => Only update 'changed' values */
2364 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2365 updateBlock->VertexShader = This->StateBlock.VertexShader;
2366 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2369 /* TODO: Vertex Shader Constants */
2371 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2372 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2373 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2374 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2377 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2378 &updateBlock->lights[i],
2379 sizeof(D3DLIGHT8)) != 0) {
2380 TRACE("Updating lights for light %d\n", i);
2381 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2385 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2386 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2387 updateBlock->lights[i] = This->StateBlock.lights[i];
2388 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2391 /* TODO: Pixel Shader Constants */
2393 /* Others + Render & Texture */
2394 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2395 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2396 &updateBlock->transforms[i],
2397 sizeof(D3DMATRIX)) != 0) {
2398 TRACE("Updating transform %d\n", i);
2399 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2403 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2404 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2405 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2406 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2407 updateBlock->pIndexData = This->StateBlock.pIndexData;
2408 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2411 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2412 &updateBlock->material,
2413 sizeof(D3DMATERIAL8)) != 0) {
2414 TRACE("Updating material\n");
2415 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2418 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2419 &updateBlock->viewport,
2420 sizeof(D3DVIEWPORT8)) != 0) {
2421 TRACE("Updating viewport\n");
2422 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2425 for (i=0; i<MAX_STREAMS; i++) {
2426 if (updateBlock->Set.stream_source[i] &&
2427 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2428 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2429 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2430 This->StateBlock.stream_stride[i]);
2431 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2432 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2436 for (i=0; i<MAX_CLIPPLANES; i++) {
2437 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2438 &updateBlock->clipplane[i],
2439 sizeof(updateBlock->clipplane)) != 0) {
2441 TRACE("Updating clipplane %d\n", i);
2442 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2443 sizeof(updateBlock->clipplane));
2447 /* Render */
2448 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2450 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
2451 This->StateBlock.renderstate[i])) {
2452 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2453 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2457 /* Texture */
2458 for (j=0; j<8; j++) {
2459 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2461 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
2462 This->StateBlock.texture_state[j][i])) {
2463 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
2464 updateBlock->texture_state[j][i]);
2465 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
2468 if (updateBlock->Set.textures[j] && (updateBlock->textures[j] != This->StateBlock.textures[j])) {
2469 TRACE("Updating texture %d to %p (was %p)\n", j, This->StateBlock.textures[j], updateBlock->textures[j]);
2470 updateBlock->textures[j] = This->StateBlock.textures[j];
2477 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2479 return D3D_OK;
2481 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2482 ICOM_THIS(IDirect3DDevice8Impl,iface);
2483 TRACE("(%p) : freeing StateBlock %lx\n", This, Token);
2484 HeapFree(GetProcessHeap(), 0, (void *)Token);
2485 return D3D_OK;
2488 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
2489 void *memory;
2490 STATEBLOCK *s;
2491 int i,j;
2493 ICOM_THIS(IDirect3DDevice8Impl,iface);
2494 TRACE("(%p) : for type %d\n", This, Type);
2496 /* Allocate Storage */
2497 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2498 if (memory) {
2499 memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2500 } else {
2501 *pToken = 0xFFFFFFFF;
2502 return E_OUTOFMEMORY;
2504 *pToken = (DWORD) memory;
2505 s = memory;
2506 s->blockType = Type;
2508 TRACE("Updating changed flags appropriate for type %d\n", Type);
2510 if (Type == D3DSBT_ALL) {
2511 TRACE("ALL => Pretend everything has changed\n");
2512 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2514 } else if (Type == D3DSBT_PIXELSTATE) {
2516 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2518 /* TODO: Pixel Shader Constants */
2519 s->Changed.pixelShader = TRUE;
2520 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2521 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2523 for (j=0; j<8; i++) {
2524 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2525 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2529 } else if (Type == D3DSBT_VERTEXSTATE) {
2531 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2533 /* TODO: Vertex Shader Constants */
2534 s->Changed.vertexShader = TRUE;
2536 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2537 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2539 for (j=0; j<8; i++) {
2540 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2541 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2545 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2546 s->Changed.lightEnable[i] = TRUE;
2547 s->Changed.lights[i] = TRUE;
2550 } else {
2551 FIXME("Unrecognized state block type %d\n", Type);
2553 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2554 return D3D_OK;
2557 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2558 ICOM_THIS(IDirect3DDevice8Impl,iface);
2559 FIXME("(%p) : stub\n", This); return D3D_OK;
2561 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2562 ICOM_THIS(IDirect3DDevice8Impl,iface);
2563 FIXME("(%p) : stub\n", This); return D3D_OK;
2565 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2566 ICOM_THIS(IDirect3DDevice8Impl,iface);
2567 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2568 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
2569 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2570 return D3D_OK;
2572 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2574 IDirect3DBaseTexture8 *oldTxt;
2576 ICOM_THIS(IDirect3DDevice8Impl,iface);
2577 D3DRESOURCETYPE textureType;
2579 oldTxt = This->StateBlock.textures[Stage];
2580 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2582 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2583 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2584 This->UpdateStateBlock->textures[Stage] = pTexture;
2586 /* Handle recording of state blocks */
2587 if (This->isRecordingState) {
2588 TRACE("Recording... not performing anything\n");
2589 return D3D_OK;
2592 /* Make appropriate texture active */
2593 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2594 checkGLcall("glActiveTextureARB");
2596 /* Decrement the count of the previous texture */
2597 /* FIXME PERF: If old == new and not dirty then skip all this */
2598 if (oldTxt != NULL) {
2599 IDirect3DBaseTexture8Impl_Release(oldTxt);
2602 if (pTexture) {
2603 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
2605 /* Now setup the texture appropraitly */
2606 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2608 if (textureType == D3DRTYPE_TEXTURE) {
2609 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
2610 int i;
2612 /* Standard 2D texture */
2613 TRACE("Standard 2d texture\n");
2614 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
2616 /* for (i=0; i<pTexture2->levels; i++) { */
2617 i=0;
2620 if (pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2621 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2622 checkGLcall("glBindTexture");
2623 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2624 } else {
2626 if (pTexture2->surfaces[i]->textureName == 0) {
2627 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
2628 checkGLcall("glGenTextures");
2629 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2632 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2633 checkGLcall("glBindTexture");
2635 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2636 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
2637 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2638 pTexture2->surfaces[i]->allocatedMemory);
2639 glTexImage2D(GL_TEXTURE_2D, i,
2640 fmt2glintFmt(pTexture2->format),
2641 pTexture2->surfaces[i]->myDesc.Width,
2642 pTexture2->surfaces[i]->myDesc.Height,
2644 fmt2glFmt(pTexture2->format),
2645 fmt2glType(pTexture2->format),
2646 pTexture2->surfaces[i]->allocatedMemory
2648 checkGLcall("glTexImage2D");
2651 * The following enable things to work but I dont think
2652 * they all go here - FIXME! @@@
2654 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2655 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2656 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2657 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2659 pTexture2->Dirty = FALSE;
2664 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
2665 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
2666 int i;
2668 /* Standard 3D (volume) texture */
2669 TRACE("Standard 3d texture\n");
2670 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
2672 /* for (i=0; i<pTexture2->levels; i++) { */
2673 i=0;
2676 if (pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2677 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2678 checkGLcall("glBindTexture");
2679 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2680 } else {
2682 if (pTexture2->volumes[i]->textureName == 0) {
2683 glGenTextures(1, &pTexture2->volumes[i]->textureName);
2684 checkGLcall("glGenTextures");
2685 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2688 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2689 checkGLcall("glBindTexture");
2691 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2692 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
2693 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
2694 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2695 pTexture2->volumes[i]->allocatedMemory);
2696 glTexImage3D(GL_TEXTURE_3D, i,
2697 fmt2glintFmt(pTexture2->format),
2698 pTexture2->volumes[i]->myDesc.Width,
2699 pTexture2->volumes[i]->myDesc.Height,
2700 pTexture2->volumes[i]->myDesc.Depth,
2702 fmt2glFmt(pTexture2->format),
2703 fmt2glType(pTexture2->format),
2704 pTexture2->volumes[i]->allocatedMemory
2706 checkGLcall("glTexImage3D");
2709 * The following enable things to work but I dont think
2710 * they all go here - FIXME! @@@
2712 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2713 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2714 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
2715 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2716 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2718 pTexture2->Dirty = FALSE;
2722 } else {
2723 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
2725 } else {
2726 TRACE("Setting to no texture (ie default texture)\n");
2727 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
2728 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
2729 checkGLcall("glBindTexture");
2730 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
2733 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
2734 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
2735 setupTextureStates (iface, Stage);
2737 return D3D_OK;
2740 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
2741 ICOM_THIS(IDirect3DDevice8Impl,iface);
2742 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
2743 *pValue = This->StateBlock.texture_state[Stage][Type];
2744 return D3D_OK;
2747 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
2748 ICOM_THIS(IDirect3DDevice8Impl,iface);
2750 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2752 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
2754 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
2755 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
2756 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
2758 /* Handle recording of state blocks */
2759 if (This->isRecordingState) {
2760 TRACE("Recording... not performing anything\n");
2761 return D3D_OK;
2764 /* Make appropriate texture active */
2765 TRACE("Activating appropriate texture state %ld\n", Stage);
2766 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2767 checkGLcall("glActiveTextureARB");
2769 switch (Type) {
2771 case D3DTSS_MINFILTER :
2772 if (Value == D3DTEXF_POINT) {
2773 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2774 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_NEAREST");
2775 } else if (Value == D3DTEXF_LINEAR) {
2776 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2777 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_LINEAR");
2778 } else {
2779 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", Value);
2781 break;
2784 case D3DTSS_MAGFILTER :
2785 if (Value == D3DTEXF_POINT) {
2786 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2787 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
2788 } else if (Value == D3DTEXF_LINEAR) {
2789 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2790 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
2791 } else {
2792 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
2794 break;
2796 case D3DTSS_COLORARG0 :
2797 case D3DTSS_ALPHAARG0 :
2798 /* FIXME: Mesa seems to struggle setting these at the moment */
2799 break;
2801 case D3DTSS_COLORARG1 :
2802 case D3DTSS_COLORARG2 :
2803 case D3DTSS_ALPHAARG1 :
2804 case D3DTSS_ALPHAARG2 :
2806 BOOL isAlphaReplicate = FALSE;
2807 BOOL isComplement = FALSE;
2808 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
2809 int operand= GL_SRC_COLOR;
2810 int source = GL_TEXTURE;
2812 /* Catch alpha replicate */
2813 if (Value & D3DTA_ALPHAREPLICATE) {
2814 Value = Value & ~D3DTA_ALPHAREPLICATE;
2815 isAlphaReplicate = TRUE;
2818 /* Catch Complement */
2819 if (Value & D3DTA_COMPLEMENT) {
2820 Value = Value & ~D3DTA_COMPLEMENT;
2821 isComplement = TRUE;
2824 /* Calculate the operand */
2825 if (isAlphaReplicate && !isComplement) {
2826 operand = GL_SRC_ALPHA;
2827 } else if (isAlphaReplicate && isComplement) {
2828 operand = GL_ONE_MINUS_SRC_ALPHA;
2829 } else if (isComplement) {
2830 if (isAlphaArg) {
2831 operand = GL_ONE_MINUS_SRC_COLOR;
2832 } else {
2833 operand = GL_ONE_MINUS_SRC_ALPHA;
2835 } else {
2836 if (isAlphaArg) {
2837 operand = GL_SRC_ALPHA;
2838 } else {
2839 operand = GL_SRC_COLOR;
2843 /* Calculate the source */
2844 switch (Value) {
2845 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
2846 break;
2847 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
2848 break;
2849 case D3DTA_TEXTURE: source = GL_TEXTURE;
2850 break;
2851 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
2852 break;
2854 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
2855 isnt supported until base GL supports it
2856 There is no concept of temp registers as far as I can tell */
2858 default:
2859 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
2862 if (isAlphaArg) {
2863 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
2864 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
2865 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
2866 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
2867 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
2868 } else {
2869 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
2870 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
2871 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
2872 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
2873 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
2876 break;
2878 case D3DTSS_ALPHAOP :
2879 case D3DTSS_COLOROP :
2882 int Scale = 1;
2883 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
2885 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
2886 /* TODO: Disable by making this and all later levels disabled */
2887 glDisable(GL_TEXTURE_1D);
2888 checkGLcall("Disable GL_TEXTURE_1D");
2889 glDisable(GL_TEXTURE_2D);
2890 checkGLcall("Disable GL_TEXTURE_2D");
2891 glDisable(GL_TEXTURE_3D);
2892 checkGLcall("Disable GL_TEXTURE_3D");
2893 } else {
2895 /* Enable only the appropriate texture dimension */
2896 if (Type==D3DTSS_COLOROP) {
2897 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
2898 glEnable(GL_TEXTURE_1D);
2899 checkGLcall("Enable GL_TEXTURE_1D");
2900 } else {
2901 glDisable(GL_TEXTURE_1D);
2902 checkGLcall("Disable GL_TEXTURE_1D");
2904 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
2905 glEnable(GL_TEXTURE_2D);
2906 checkGLcall("Enable GL_TEXTURE_2D");
2907 } else {
2908 glDisable(GL_TEXTURE_2D);
2909 checkGLcall("Disable GL_TEXTURE_2D");
2911 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
2912 glEnable(GL_TEXTURE_3D);
2913 checkGLcall("Enable GL_TEXTURE_3D");
2914 } else {
2915 glDisable(GL_TEXTURE_3D);
2916 checkGLcall("Disable GL_TEXTURE_3D");
2920 /* Now set up the operand correctly */
2921 switch (Value) {
2922 case D3DTOP_DISABLE :
2923 /* Contrary to the docs, alpha can be disabled when colorop is enabled
2924 and it works, so ignore this op */
2925 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
2926 break;
2928 case D3DTOP_SELECTARG1 :
2929 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
2930 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
2931 break;
2933 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
2934 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
2935 case D3DTOP_MODULATE :
2937 /* Correct scale */
2938 if (Type == D3DTSS_ALPHAOP) {
2939 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
2940 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
2941 } else {
2942 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
2943 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
2945 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
2946 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
2947 break;
2949 case D3DTOP_ADD :
2950 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
2951 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
2952 break;
2954 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
2955 case D3DTOP_ADDSIGNED :
2956 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
2957 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
2958 break;
2960 case D3DTOP_DOTPRODUCT3 :
2961 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
2962 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
2963 break;*/
2965 case D3DTOP_SUBTRACT :
2966 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
2967 case D3DTOP_SELECTARG2 :
2968 /* GL_REPLACE, swap args 0 and 1? */
2969 case D3DTOP_ADDSMOOTH :
2970 case D3DTOP_BLENDDIFFUSEALPHA :
2971 case D3DTOP_BLENDTEXTUREALPHA :
2972 case D3DTOP_BLENDFACTORALPHA :
2973 case D3DTOP_BLENDTEXTUREALPHAPM :
2974 case D3DTOP_BLENDCURRENTALPHA :
2975 case D3DTOP_PREMODULATE :
2976 case D3DTOP_MODULATEALPHA_ADDCOLOR :
2977 case D3DTOP_MODULATECOLOR_ADDALPHA :
2978 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
2979 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
2980 case D3DTOP_BUMPENVMAP :
2981 case D3DTOP_BUMPENVMAPLUMINANCE :
2982 case D3DTOP_MULTIPLYADD :
2983 case D3DTOP_LERP :
2984 default:
2985 FIXME("Unhandled texture operation %ld\n", Value);
2988 break;
2991 /* Unhandled */
2992 case D3DTSS_BUMPENVMAT00 :
2993 case D3DTSS_BUMPENVMAT01 :
2994 case D3DTSS_BUMPENVMAT10 :
2995 case D3DTSS_BUMPENVMAT11 :
2996 case D3DTSS_TEXCOORDINDEX :
2997 case D3DTSS_ADDRESSU :
2998 case D3DTSS_ADDRESSV :
2999 case D3DTSS_BORDERCOLOR :
3000 case D3DTSS_MIPFILTER :
3001 case D3DTSS_MIPMAPLODBIAS :
3002 case D3DTSS_MAXMIPLEVEL :
3003 case D3DTSS_MAXANISOTROPY :
3004 case D3DTSS_BUMPENVLSCALE :
3005 case D3DTSS_BUMPENVLOFFSET :
3006 case D3DTSS_TEXTURETRANSFORMFLAGS :
3007 case D3DTSS_ADDRESSW :
3008 case D3DTSS_RESULTARG :
3009 default:
3010 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3011 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3013 return D3D_OK;
3015 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3016 ICOM_THIS(IDirect3DDevice8Impl,iface);
3017 FIXME("(%p) : stub\n", This); return D3D_OK;
3019 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3020 ICOM_THIS(IDirect3DDevice8Impl,iface);
3021 FIXME("(%p) : stub\n", This); return D3D_OK;
3023 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3024 ICOM_THIS(IDirect3DDevice8Impl,iface);
3025 FIXME("(%p) : stub\n", This); return D3D_OK;
3027 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3028 ICOM_THIS(IDirect3DDevice8Impl,iface);
3029 FIXME("(%p) : stub\n", This); return D3D_OK;
3031 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3032 ICOM_THIS(IDirect3DDevice8Impl,iface);
3033 FIXME("(%p) : stub\n", This); return D3D_OK;
3035 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3036 ICOM_THIS(IDirect3DDevice8Impl,iface);
3037 FIXME("(%p) : stub\n", This); return D3D_OK;
3039 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3041 IDirect3DVertexBuffer8 *pVB;
3043 ICOM_THIS(IDirect3DDevice8Impl,iface);
3044 pVB = This->StateBlock.stream_source[0];
3046 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3048 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3049 This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL);
3051 return D3D_OK;
3053 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3054 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3055 UINT idxStride = 2;
3056 IDirect3DIndexBuffer8 *pIB;
3057 IDirect3DVertexBuffer8 *pVB;
3058 D3DINDEXBUFFER_DESC IdxBufDsc;
3060 ICOM_THIS(IDirect3DDevice8Impl,iface);
3061 pIB = This->StateBlock.pIndexData;
3062 pVB = This->StateBlock.stream_source[0];
3064 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3065 minIndex, NumVertices, startIndex, primCount);
3067 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3068 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3069 idxStride = 2;
3070 } else {
3071 idxStride = 4;
3074 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3075 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory);
3077 return D3D_OK;
3079 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3080 ICOM_THIS(IDirect3DDevice8Impl,iface);
3082 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3084 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3086 This->StateBlock.stream_source[0] = NULL;
3087 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3088 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3089 0, 0, 0, NULL);
3090 This->StateBlock.stream_stride[0] = 0;
3092 /*stream zero settings set to null at end */
3093 return D3D_OK;
3095 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3096 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3097 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3098 UINT VertexStreamZeroStride) {
3099 int idxStride;
3100 ICOM_THIS(IDirect3DDevice8Impl,iface);
3101 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3102 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3104 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3105 if (IndexDataFormat == D3DFMT_INDEX16) {
3106 idxStride = 2;
3107 } else {
3108 idxStride = 4;
3111 This->StateBlock.stream_source[0] = NULL;
3112 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3113 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3114 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData);
3116 /*stream zero settings set to null at end */
3117 This->StateBlock.stream_stride[0] = 0;
3118 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3120 return D3D_OK;
3122 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3123 ICOM_THIS(IDirect3DDevice8Impl,iface);
3124 FIXME("(%p) : stub\n", This); return D3D_OK;
3126 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3127 ICOM_THIS(IDirect3DDevice8Impl,iface);
3128 VERTEXSHADER8* object;
3129 UINT i;
3131 FIXME("(%p) : VertexShader not fully supported yet\n", This);
3132 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3133 return D3DERR_INVALIDCALL;
3135 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(VERTEXSHADER8*); ++i) ;
3136 if (i >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) {
3137 return D3DERR_OUTOFVIDEOMEMORY;
3139 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERTEXSHADER8));
3140 if (NULL == object) {
3141 return D3DERR_OUTOFVIDEOMEMORY;
3144 object->usage = Usage;
3145 object->data = NULL; /* TODO */
3147 VertexShaders[i] = object;
3148 *pHandle = VS_HIGHESTFIXEDFXF + i;
3150 object->decl = pDeclaration;
3151 for (i = 0; 0xFFFFFFFF != pDeclaration[i]; ++i) ;
3152 object->declLength = i + 1;
3153 object->function = pFunction;
3154 if (NULL != pFunction) {
3155 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3156 object->functionLength = i + 1;
3157 } else {
3158 object->functionLength = 1; /* no Function defined use fixed function vertex processing */
3161 return D3D_OK;
3163 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3164 ICOM_THIS(IDirect3DDevice8Impl,iface);
3166 This->UpdateStateBlock->VertexShader = Handle;
3167 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3168 This->UpdateStateBlock->Set.vertexShader = TRUE;
3170 /* Handle recording of state blocks */
3171 if (This->isRecordingState) {
3172 TRACE("Recording... not performing anything\n");
3173 return D3D_OK;
3176 if (Handle <= VS_HIGHESTFIXEDFXF) {
3177 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3178 return D3D_OK;
3179 } else {
3180 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3181 return D3D_OK;
3184 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3185 ICOM_THIS(IDirect3DDevice8Impl,iface);
3186 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock.VertexShader);
3187 *pHandle = This->StateBlock.VertexShader;
3188 return D3D_OK;
3191 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3192 ICOM_THIS(IDirect3DDevice8Impl,iface);
3193 VERTEXSHADER8* object;
3195 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3196 return D3DERR_INVALIDCALL;
3198 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3199 TRACE("(%p) : freing VertexShader %p\n", This, object);
3200 /* TODO: check validity of object */
3201 HeapFree(GetProcessHeap(), 0, (void *)object);
3202 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3203 return D3D_OK;
3206 #define VERTEX_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
3208 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3209 ICOM_THIS(IDirect3DDevice8Impl,iface);
3210 VERTEXSHADER8* object;
3211 DWORD Handle = This->UpdateStateBlock->VertexShader;
3213 FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
3215 if (Register + ConstantCount > VSHADER_MAX_CONSTANTS) {
3216 return D3DERR_INVALIDCALL;
3218 object = VERTEX_SHADER(Handle);
3219 if (NULL == object || NULL == pConstantData) {
3220 return D3DERR_INVALIDCALL;
3222 memcpy(object->data->constants + Register, pConstantData, ConstantCount * sizeof(SHADER8Vector));
3224 return D3D_OK;
3226 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3227 ICOM_THIS(IDirect3DDevice8Impl,iface);
3228 VERTEXSHADER8* object;
3229 DWORD Handle = This->UpdateStateBlock->VertexShader;
3231 FIXME("(%p) : VertexShader_GetConstant not fully supported yet\n", This);
3233 if (Register + ConstantCount > VSHADER_MAX_CONSTANTS) {
3234 return D3DERR_INVALIDCALL;
3236 object = VERTEX_SHADER(Handle);
3237 if (NULL == object || NULL == pConstantData) {
3238 return D3DERR_INVALIDCALL;
3240 memcpy(pConstantData, object->data->constants + Register, ConstantCount * sizeof(SHADER8Vector));
3242 return D3D_OK;
3244 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3245 ICOM_THIS(IDirect3DDevice8Impl,iface);
3246 VERTEXSHADER8* object;
3248 object = VERTEX_SHADER(Handle);
3249 if (NULL == object) {
3250 return D3DERR_INVALIDCALL;
3252 if (NULL == pData) {
3253 *pSizeOfData = object->declLength;
3254 return D3D_OK;
3256 if (*pSizeOfData < object->declLength) {
3257 *pSizeOfData = object->declLength;
3258 return D3DERR_MOREDATA;
3260 TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
3261 memcpy(pData, object->decl, object->declLength);
3262 return D3D_OK;
3264 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3265 ICOM_THIS(IDirect3DDevice8Impl,iface);
3266 VERTEXSHADER8* object;
3268 object = VERTEX_SHADER(Handle);
3269 if (NULL == object) {
3270 return D3DERR_INVALIDCALL;
3272 if (NULL == pData) {
3273 *pSizeOfData = object->functionLength;
3274 return D3D_OK;
3276 if (*pSizeOfData < object->functionLength) {
3277 *pSizeOfData = object->functionLength;
3278 return D3DERR_MOREDATA;
3280 if (NULL == object->function) { /* no function defined */
3281 TRACE("(%p) : GetVertexShaderFunction no User Function defined using NULL to %p\n", This, pData);
3282 ((DWORD *) pData) = NULL;
3283 } else {
3284 TRACE("(%p) : GetVertexShaderFunction copying to %p\n", This, pData);
3285 memcpy(pData, object->function, object->functionLength);
3287 return D3D_OK;
3290 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3292 IDirect3DIndexBuffer8 *oldIdxs;
3294 ICOM_THIS(IDirect3DDevice8Impl,iface);
3295 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3296 oldIdxs = This->StateBlock.pIndexData;
3298 This->UpdateStateBlock->Changed.Indices = TRUE;
3299 This->UpdateStateBlock->Set.Indices = TRUE;
3300 This->UpdateStateBlock->pIndexData = pIndexData;
3301 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3303 /* Handle recording of state blocks */
3304 if (This->isRecordingState) {
3305 TRACE("Recording... not performing anything\n");
3306 return D3D_OK;
3309 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3310 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3311 return D3D_OK;
3313 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3314 ICOM_THIS(IDirect3DDevice8Impl,iface);
3315 FIXME("(%p) : stub\n", This);
3317 *ppIndexData = This->StateBlock.pIndexData;
3318 /* up ref count on ppindexdata */
3319 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3320 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3322 return D3D_OK;
3324 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3325 ICOM_THIS(IDirect3DDevice8Impl,iface);
3326 PIXELSHADER8* object;
3327 UINT i;
3329 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3330 if (NULL == pFunction || NULL == pHandle) {
3331 return D3DERR_INVALIDCALL;
3333 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(PIXELSHADER8*); ++i) ;
3334 if (i >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) {
3335 return D3DERR_OUTOFVIDEOMEMORY;
3337 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PIXELSHADER8));
3338 if (NULL == object) {
3339 return D3DERR_OUTOFVIDEOMEMORY;
3342 object->data = NULL; /* TODO */
3344 PixelShaders[i] = object;
3345 *pHandle = VS_HIGHESTFIXEDFXF + i;
3347 object->function = pFunction;
3348 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3349 object->functionLength = i + 1;
3351 return D3D_OK;
3353 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3354 ICOM_THIS(IDirect3DDevice8Impl,iface);
3356 This->UpdateStateBlock->PixelShader = Handle;
3357 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3358 This->UpdateStateBlock->Set.pixelShader = TRUE;
3360 /* Handle recording of state blocks */
3361 if (This->isRecordingState) {
3362 TRACE("Recording... not performing anything\n");
3363 return D3D_OK;
3366 /* FIXME: Quieten when not being used */
3367 if (Handle != 0) {
3368 FIXME("(%p) : stub %ld\n", This, Handle);
3369 } else {
3370 TRACE("(%p) : stub %ld\n", This, Handle);
3373 return D3D_OK;
3375 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3376 ICOM_THIS(IDirect3DDevice8Impl,iface);
3377 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock.PixelShader);
3378 *pHandle = This->StateBlock.PixelShader;
3379 return D3D_OK;
3382 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3383 ICOM_THIS(IDirect3DDevice8Impl,iface);
3384 PIXELSHADER8* object;
3386 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3387 return D3DERR_INVALIDCALL;
3389 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3390 TRACE("(%p) : freeing PixelShader %p\n", This, object);
3391 /* TODO: check validity of object before free */
3392 HeapFree(GetProcessHeap(), 0, (void *)object);
3393 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3394 return D3D_OK;
3396 #define PIXEL_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
3398 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
3399 ICOM_THIS(IDirect3DDevice8Impl,iface);
3400 FIXME("(%p) : stub\n", This);
3401 return D3D_OK;
3403 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
3404 ICOM_THIS(IDirect3DDevice8Impl,iface);
3405 FIXME("(%p) : stub\n", This);
3406 return D3D_OK;
3408 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3409 ICOM_THIS(IDirect3DDevice8Impl,iface);
3410 PIXELSHADER8* object;
3412 object = PIXEL_SHADER(Handle);
3413 if (NULL == object) {
3414 return D3DERR_INVALIDCALL;
3416 if (NULL == pData) {
3417 *pSizeOfData = object->functionLength;
3418 return D3D_OK;
3420 if (*pSizeOfData < object->functionLength) {
3421 *pSizeOfData = object->functionLength;
3422 return D3DERR_MOREDATA;
3424 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
3425 memcpy(pData, object->function, object->functionLength);
3426 return D3D_OK;
3428 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3429 ICOM_THIS(IDirect3DDevice8Impl,iface);
3430 FIXME("(%p) : stub\n", This); return D3D_OK;
3432 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3433 ICOM_THIS(IDirect3DDevice8Impl,iface);
3434 FIXME("(%p) : stub\n", This); return D3D_OK;
3436 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3437 ICOM_THIS(IDirect3DDevice8Impl,iface);
3438 FIXME("(%p) : stub\n", This); return D3D_OK;
3441 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3442 IDirect3DVertexBuffer8 *oldSrc;
3443 ICOM_THIS(IDirect3DDevice8Impl,iface);
3445 oldSrc = This->StateBlock.stream_source[StreamNumber];
3446 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3448 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3449 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3450 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3451 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3453 /* Handle recording of state blocks */
3454 if (This->isRecordingState) {
3455 TRACE("Recording... not performing anything\n");
3456 return D3D_OK;
3459 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3460 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3461 return D3D_OK;
3463 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3464 ICOM_THIS(IDirect3DDevice8Impl,iface);
3465 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3466 *pStream = This->StateBlock.stream_source[StreamNumber];
3467 *pStride = This->StateBlock.stream_stride[StreamNumber];
3468 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3469 return D3D_OK;
3473 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3475 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3476 IDirect3DDevice8Impl_QueryInterface,
3477 IDirect3DDevice8Impl_AddRef,
3478 IDirect3DDevice8Impl_Release,
3479 IDirect3DDevice8Impl_TestCooperativeLevel,
3480 IDirect3DDevice8Impl_GetAvailableTextureMem,
3481 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3482 IDirect3DDevice8Impl_GetDirect3D,
3483 IDirect3DDevice8Impl_GetDeviceCaps,
3484 IDirect3DDevice8Impl_GetDisplayMode,
3485 IDirect3DDevice8Impl_GetCreationParameters,
3486 IDirect3DDevice8Impl_SetCursorProperties,
3487 IDirect3DDevice8Impl_SetCursorPosition,
3488 IDirect3DDevice8Impl_ShowCursor,
3489 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3490 IDirect3DDevice8Impl_Reset,
3491 IDirect3DDevice8Impl_Present,
3492 IDirect3DDevice8Impl_GetBackBuffer,
3493 IDirect3DDevice8Impl_GetRasterStatus,
3494 IDirect3DDevice8Impl_SetGammaRamp,
3495 IDirect3DDevice8Impl_GetGammaRamp,
3496 IDirect3DDevice8Impl_CreateTexture,
3497 IDirect3DDevice8Impl_CreateVolumeTexture,
3498 IDirect3DDevice8Impl_CreateCubeTexture,
3499 IDirect3DDevice8Impl_CreateVertexBuffer,
3500 IDirect3DDevice8Impl_CreateIndexBuffer,
3501 IDirect3DDevice8Impl_CreateRenderTarget,
3502 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3503 IDirect3DDevice8Impl_CreateImageSurface,
3504 IDirect3DDevice8Impl_CopyRects,
3505 IDirect3DDevice8Impl_UpdateTexture,
3506 IDirect3DDevice8Impl_GetFrontBuffer,
3507 IDirect3DDevice8Impl_SetRenderTarget,
3508 IDirect3DDevice8Impl_GetRenderTarget,
3509 IDirect3DDevice8Impl_GetDepthStencilSurface,
3510 IDirect3DDevice8Impl_BeginScene,
3511 IDirect3DDevice8Impl_EndScene,
3512 IDirect3DDevice8Impl_Clear,
3513 IDirect3DDevice8Impl_SetTransform,
3514 IDirect3DDevice8Impl_GetTransform,
3515 IDirect3DDevice8Impl_MultiplyTransform,
3516 IDirect3DDevice8Impl_SetViewport,
3517 IDirect3DDevice8Impl_GetViewport,
3518 IDirect3DDevice8Impl_SetMaterial,
3519 IDirect3DDevice8Impl_GetMaterial,
3520 IDirect3DDevice8Impl_SetLight,
3521 IDirect3DDevice8Impl_GetLight,
3522 IDirect3DDevice8Impl_LightEnable,
3523 IDirect3DDevice8Impl_GetLightEnable,
3524 IDirect3DDevice8Impl_SetClipPlane,
3525 IDirect3DDevice8Impl_GetClipPlane,
3526 IDirect3DDevice8Impl_SetRenderState,
3527 IDirect3DDevice8Impl_GetRenderState,
3528 IDirect3DDevice8Impl_BeginStateBlock,
3529 IDirect3DDevice8Impl_EndStateBlock,
3530 IDirect3DDevice8Impl_ApplyStateBlock,
3531 IDirect3DDevice8Impl_CaptureStateBlock,
3532 IDirect3DDevice8Impl_DeleteStateBlock,
3533 IDirect3DDevice8Impl_CreateStateBlock,
3534 IDirect3DDevice8Impl_SetClipStatus,
3535 IDirect3DDevice8Impl_GetClipStatus,
3536 IDirect3DDevice8Impl_GetTexture,
3537 IDirect3DDevice8Impl_SetTexture,
3538 IDirect3DDevice8Impl_GetTextureStageState,
3539 IDirect3DDevice8Impl_SetTextureStageState,
3540 IDirect3DDevice8Impl_ValidateDevice,
3541 IDirect3DDevice8Impl_GetInfo,
3542 IDirect3DDevice8Impl_SetPaletteEntries,
3543 IDirect3DDevice8Impl_GetPaletteEntries,
3544 IDirect3DDevice8Impl_SetCurrentTexturePalette,
3545 IDirect3DDevice8Impl_GetCurrentTexturePalette,
3546 IDirect3DDevice8Impl_DrawPrimitive,
3547 IDirect3DDevice8Impl_DrawIndexedPrimitive,
3548 IDirect3DDevice8Impl_DrawPrimitiveUP,
3549 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
3550 IDirect3DDevice8Impl_ProcessVertices,
3551 IDirect3DDevice8Impl_CreateVertexShader,
3552 IDirect3DDevice8Impl_SetVertexShader,
3553 IDirect3DDevice8Impl_GetVertexShader,
3554 IDirect3DDevice8Impl_DeleteVertexShader,
3555 IDirect3DDevice8Impl_SetVertexShaderConstant,
3556 IDirect3DDevice8Impl_GetVertexShaderConstant,
3557 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
3558 IDirect3DDevice8Impl_GetVertexShaderFunction,
3559 IDirect3DDevice8Impl_SetStreamSource,
3560 IDirect3DDevice8Impl_GetStreamSource,
3561 IDirect3DDevice8Impl_SetIndices,
3562 IDirect3DDevice8Impl_GetIndices,
3563 IDirect3DDevice8Impl_CreatePixelShader,
3564 IDirect3DDevice8Impl_SetPixelShader,
3565 IDirect3DDevice8Impl_GetPixelShader,
3566 IDirect3DDevice8Impl_DeletePixelShader,
3567 IDirect3DDevice8Impl_SetPixelShaderConstant,
3568 IDirect3DDevice8Impl_GetPixelShaderConstant,
3569 IDirect3DDevice8Impl_GetPixelShaderFunction,
3570 IDirect3DDevice8Impl_DrawRectPatch,
3571 IDirect3DDevice8Impl_DrawTriPatch,
3572 IDirect3DDevice8Impl_DeletePatch
3575 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
3576 D3DLINEPATTERN lp;
3577 int i;
3579 ICOM_THIS(IDirect3DDevice8Impl,iface);
3581 /* Note this may have a large overhead but it should only be executed
3582 once, in order to initialize the complete state of the device and
3583 all opengl equivalents */
3584 TRACE("-----------------------> Setting up device defaults...\n");
3585 This->StateBlock.blockType = D3DSBT_ALL;
3587 /* FIXME: Set some of the defaults for lights, transforms etc */
3588 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
3589 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
3590 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
3592 /* Render states: */
3593 if (This->PresentParms.EnableAutoDepthStencil) {
3594 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
3595 } else {
3596 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
3598 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
3599 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3600 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
3601 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
3602 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
3603 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
3604 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
3605 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
3606 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
3607 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3608 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
3609 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
3610 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
3611 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
3612 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
3613 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
3614 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
3615 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
3616 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3617 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
3618 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
3619 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
3620 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
3621 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
3622 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
3623 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
3624 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
3625 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
3626 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
3627 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
3628 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
3629 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
3630 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
3631 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
3632 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
3633 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
3634 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
3635 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
3636 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
3637 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
3638 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
3639 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
3640 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
3641 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
3642 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
3643 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3644 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
3645 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
3646 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
3647 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3648 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
3649 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
3650 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
3651 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
3652 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
3653 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
3654 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
3655 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
3656 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
3657 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
3658 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
3659 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
3660 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
3661 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
3662 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
3663 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
3664 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
3665 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
3666 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
3667 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
3668 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
3669 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
3670 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
3671 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
3672 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
3674 /* Texture Stage States - Put directly into state block, we will call function below */
3675 for (i=0; i<8;i++) {
3676 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
3677 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
3678 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
3679 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
3680 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
3681 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
3682 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
3683 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
3684 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
3685 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
3686 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
3687 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
3688 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
3689 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
3690 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
3691 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
3692 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
3693 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
3694 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
3695 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
3696 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
3697 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
3698 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
3699 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
3700 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
3701 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
3702 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
3705 /* Under DirectX you can have texture stage operations even if no texture is
3706 bound, whereas opengl will only do texture operations when a valid texture is
3707 bound. We emulate this by creating 8 dummy textures and binding them to each
3708 texture stage, but disable all stages by default. Hence if a stage is enabled
3709 then the default texture will kick in until replaced by a SetTexture call */
3711 for (i=0; i<8; i++) {
3712 GLubyte white = 255;
3714 /* Note this avoids calling settexture, so pretend it has been called */
3715 This->StateBlock.Set.textures[i] = TRUE;
3716 This->StateBlock.Changed.textures[i] = TRUE;
3717 This->StateBlock.textures[i] = NULL;
3719 /* Make appropriate texture active */
3720 glActiveTextureARB(GL_TEXTURE0_ARB + i);
3721 checkGLcall("glActiveTextureARB");
3723 /* Generate an opengl texture name */
3724 glGenTextures(1, &This->dummyTextureName[i]);
3725 checkGLcall("glGenTextures");
3726 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
3728 /* Generate a dummy 1d texture */
3729 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
3730 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
3731 checkGLcall("glBindTexture");
3733 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
3734 checkGLcall("glTexImage1D");
3736 /* Reapply all the texture state information to this texture */
3737 setupTextureStates(iface, i);
3740 TRACE("-----------------------> Device defaults now set up...\n");
3745 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
3746 D3DRS_ALPHABLENDENABLE ,
3747 D3DRS_ALPHAFUNC ,
3748 D3DRS_ALPHAREF ,
3749 D3DRS_ALPHATESTENABLE ,
3750 D3DRS_BLENDOP ,
3751 D3DRS_COLORWRITEENABLE ,
3752 D3DRS_DESTBLEND ,
3753 D3DRS_DITHERENABLE ,
3754 D3DRS_EDGEANTIALIAS ,
3755 D3DRS_FILLMODE ,
3756 D3DRS_FOGDENSITY ,
3757 D3DRS_FOGEND ,
3758 D3DRS_FOGSTART ,
3759 D3DRS_LASTPIXEL ,
3760 D3DRS_LINEPATTERN ,
3761 D3DRS_SHADEMODE ,
3762 D3DRS_SRCBLEND ,
3763 D3DRS_STENCILENABLE ,
3764 D3DRS_STENCILFAIL ,
3765 D3DRS_STENCILFUNC ,
3766 D3DRS_STENCILMASK ,
3767 D3DRS_STENCILPASS ,
3768 D3DRS_STENCILREF ,
3769 D3DRS_STENCILWRITEMASK ,
3770 D3DRS_STENCILZFAIL ,
3771 D3DRS_TEXTUREFACTOR ,
3772 D3DRS_WRAP0 ,
3773 D3DRS_WRAP1 ,
3774 D3DRS_WRAP2 ,
3775 D3DRS_WRAP3 ,
3776 D3DRS_WRAP4 ,
3777 D3DRS_WRAP5 ,
3778 D3DRS_WRAP6 ,
3779 D3DRS_WRAP7 ,
3780 D3DRS_ZBIAS ,
3781 D3DRS_ZENABLE ,
3782 D3DRS_ZFUNC ,
3783 D3DRS_ZWRITEENABLE
3786 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
3787 D3DTSS_ADDRESSU ,
3788 D3DTSS_ADDRESSV ,
3789 D3DTSS_ADDRESSW ,
3790 D3DTSS_ALPHAARG0 ,
3791 D3DTSS_ALPHAARG1 ,
3792 D3DTSS_ALPHAARG2 ,
3793 D3DTSS_ALPHAOP ,
3794 D3DTSS_BORDERCOLOR ,
3795 D3DTSS_BUMPENVLOFFSET ,
3796 D3DTSS_BUMPENVLSCALE ,
3797 D3DTSS_BUMPENVMAT00 ,
3798 D3DTSS_BUMPENVMAT01 ,
3799 D3DTSS_BUMPENVMAT10 ,
3800 D3DTSS_BUMPENVMAT11 ,
3801 D3DTSS_COLORARG0 ,
3802 D3DTSS_COLORARG1 ,
3803 D3DTSS_COLORARG2 ,
3804 D3DTSS_COLOROP ,
3805 D3DTSS_MAGFILTER ,
3806 D3DTSS_MAXANISOTROPY ,
3807 D3DTSS_MAXMIPLEVEL ,
3808 D3DTSS_MINFILTER ,
3809 D3DTSS_MIPFILTER ,
3810 D3DTSS_MIPMAPLODBIAS ,
3811 D3DTSS_RESULTARG ,
3812 D3DTSS_TEXCOORDINDEX ,
3813 D3DTSS_TEXTURETRANSFORMFLAGS
3816 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
3817 D3DRS_AMBIENT ,
3818 D3DRS_AMBIENTMATERIALSOURCE ,
3819 D3DRS_CLIPPING ,
3820 D3DRS_CLIPPLANEENABLE ,
3821 D3DRS_COLORVERTEX ,
3822 D3DRS_DIFFUSEMATERIALSOURCE ,
3823 D3DRS_EMISSIVEMATERIALSOURCE ,
3824 D3DRS_FOGDENSITY ,
3825 D3DRS_FOGEND ,
3826 D3DRS_FOGSTART ,
3827 D3DRS_FOGTABLEMODE ,
3828 D3DRS_FOGVERTEXMODE ,
3829 D3DRS_INDEXEDVERTEXBLENDENABLE ,
3830 D3DRS_LIGHTING ,
3831 D3DRS_LOCALVIEWER ,
3832 D3DRS_MULTISAMPLEANTIALIAS ,
3833 D3DRS_MULTISAMPLEMASK ,
3834 D3DRS_NORMALIZENORMALS ,
3835 D3DRS_PATCHEDGESTYLE ,
3836 D3DRS_PATCHSEGMENTS ,
3837 D3DRS_POINTSCALE_A ,
3838 D3DRS_POINTSCALE_B ,
3839 D3DRS_POINTSCALE_C ,
3840 D3DRS_POINTSCALEENABLE ,
3841 D3DRS_POINTSIZE ,
3842 D3DRS_POINTSIZE_MAX ,
3843 D3DRS_POINTSIZE_MIN ,
3844 D3DRS_POINTSPRITEENABLE ,
3845 D3DRS_RANGEFOGENABLE ,
3846 D3DRS_SOFTWAREVERTEXPROCESSING ,
3847 D3DRS_SPECULARMATERIALSOURCE ,
3848 D3DRS_TWEENFACTOR ,
3849 D3DRS_VERTEXBLEND
3852 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
3853 D3DTSS_TEXCOORDINDEX ,
3854 D3DTSS_TEXTURETRANSFORMFLAGS