Added support for nested exceptions happening inside a catch block.
[wine/multimedia.git] / dlls / d3d8 / device.c
blob833e64150c6d855c7f2dc3b7da08c5a75015177b
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 /* CreateVertexShader can return > 0xFFFF */
33 #define VS_HIGHESTFIXEDFXF 0xF0000000
35 /* Used for CreateStateBlock */
36 #define NUM_SAVEDPIXELSTATES_R 38
37 #define NUM_SAVEDPIXELSTATES_T 27
38 #define NUM_SAVEDVERTEXSTATES_R 33
39 #define NUM_SAVEDVERTEXSTATES_T 2
42 * Utility functions or macros
44 #define conv_mat(mat,gl_mat) \
45 { \
46 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
47 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
48 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
49 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
50 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
54 * Globals
56 extern DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R];
57 extern DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T];
58 extern DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R];
59 extern DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T];
61 static const float idmatrix[16] = {
62 1.0, 0.0, 0.0, 0.0,
63 0.0, 1.0, 0.0, 0.0,
64 0.0, 0.0, 1.0, 0.0,
65 0.0, 0.0, 0.0, 1.0
68 /* Routine common to the draw primitive and draw indexed primitive routines
69 Doesnt use gl pointer arrays as I dont believe we can support the blending
70 coordinates that way. */
72 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
73 int PrimitiveType,
74 long NumPrimitives,
75 BOOL isIndexed,
77 /* For Both:*/
78 D3DFORMAT fvf,
79 const void *vertexBufData,
81 /* for Indexed: */
82 long StartVertexIndex,
83 long StartIdx,
84 short idxBytes,
85 const void *idxData) {
87 int vx_index;
88 int NumVertexes = NumPrimitives;
90 ICOM_THIS(IDirect3DDevice8Impl,iface);
92 /* Dont understand how to handle multiple streams, but if a fixed
93 FVF is passed in rather than a handle, it must use stream 0 */
95 if (This->StateBlock.VertexShader > VS_HIGHESTFIXEDFXF) {
96 FIXME("Cant handle created shaders yet\n");
97 return;
98 } else {
100 int skip = This->StateBlock.stream_stride[0];
102 BOOL normal;
103 BOOL isRHW;
104 BOOL isPtSize;
105 BOOL isDiffuse;
106 BOOL isSpecular;
107 int numTextures;
108 int textureNo;
109 const void *curVtx = NULL;
110 const short *pIdxBufS = NULL;
111 const long *pIdxBufL = NULL;
112 const void *curPos;
113 BOOL isLightingOn = FALSE;
115 float x=0.0, y=0.0, z=0.0; /* x,y,z coordinates */
116 float nx=0.0, ny=0.0, nz=0.0; /* normal x,y,z coordinates */
117 float rhw=0.0; /* rhw */
118 float ptSize=0.0; /* Point size */
119 DWORD diffuseColor=0; /* Diffusre Color */
120 DWORD specularColor=0; /* Specular Color */
122 ENTER_GL();
124 if (isIndexed) {
125 if (idxBytes == 2) pIdxBufS = (short *) idxData;
126 else pIdxBufL = (long *) idxData;
129 /* Check vertex formats expected ? */
130 normal = fvf & D3DFVF_NORMAL;
131 isRHW = fvf & D3DFVF_XYZRHW;
132 /*numBlends = 5 - ((~fvf) & 0xe);*/ /* There must be a simpler way? */
133 isPtSize = fvf & D3DFVF_PSIZE;
134 isDiffuse = fvf & D3DFVF_DIFFUSE;
135 isSpecular = fvf & D3DFVF_SPECULAR;
136 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
138 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d)\n",
139 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures);
141 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
142 set by the appropriate render state */
143 if (!normal) {
144 isLightingOn = glIsEnabled(GL_LIGHTING);
145 glDisable(GL_LIGHTING);
146 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
150 if (isRHW) {
152 double height, width, minZ, maxZ;
155 * Already transformed vertex do not need transform
156 * matrices. Reset all matrices to identity.
157 * Leave the default matrix in world mode.
159 glMatrixMode(GL_PROJECTION);
160 checkGLcall("glMatrixMode");
161 glLoadIdentity();
162 checkGLcall("glLoadIdentity");
163 glMatrixMode(GL_MODELVIEW);
164 checkGLcall("glMatrixMode");
165 glLoadIdentity();
166 checkGLcall("glLoadIdentity");
167 height = This->StateBlock.viewport.Height;
168 width = This->StateBlock.viewport.Width;
169 minZ = This->StateBlock.viewport.MinZ;
170 maxZ = This->StateBlock.viewport.MaxZ;
171 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
172 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
173 checkGLcall("glOrtho");
175 } else {
176 glMatrixMode(GL_PROJECTION);
177 checkGLcall("glMatrixMode");
178 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
179 checkGLcall("glLoadMatrixf");
181 glMatrixMode(GL_MODELVIEW);
182 checkGLcall("glMatrixMode");
183 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
184 checkGLcall("glLoadMatrixf");
185 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
186 checkGLcall("glMultMatrixf");
189 /* Set OpenGL to the appropriate Primitive Type */
190 switch (PrimitiveType) {
191 case D3DPT_POINTLIST:
192 TRACE("glBegin, Start POINTS\n");
193 glBegin(GL_POINTS);
194 NumVertexes = NumPrimitives;
195 break;
197 case D3DPT_LINELIST:
198 TRACE("glBegin, Start LINES\n");
199 glBegin(GL_LINES);
200 NumVertexes = NumPrimitives * 2;
201 break;
203 case D3DPT_LINESTRIP:
204 TRACE("glBegin, Start LINE_STRIP\n");
205 glBegin(GL_LINE_STRIP);
206 NumVertexes = NumPrimitives + 1;
207 break;
209 case D3DPT_TRIANGLELIST:
210 TRACE("glBegin, Start TRIANGLES\n");
211 glBegin(GL_TRIANGLES);
212 NumVertexes = NumPrimitives * 3;
213 break;
215 case D3DPT_TRIANGLESTRIP:
216 TRACE("glBegin, Start TRIANGLE_STRIP\n");
217 glBegin(GL_TRIANGLE_STRIP);
218 NumVertexes = NumPrimitives + 2;
219 break;
221 case D3DPT_TRIANGLEFAN:
222 TRACE("glBegin, Start TRIANGLE_FAN\n");
223 glBegin(GL_TRIANGLE_FAN);
224 NumVertexes = NumPrimitives + 2;
225 break;
227 default:
228 FIXME("Unhandled primitive\n");
229 break;
233 /* Draw the primitives */
234 curVtx = vertexBufData + (StartVertexIndex * skip);
236 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
238 if (!isIndexed) {
239 curPos = curVtx;
240 } else {
241 if (idxBytes == 2) {
242 TRACE("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index]));
243 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
244 } else {
245 TRACE("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index]));
246 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
250 /* Work through the vertex buffer */
251 x = *(float *)curPos;
252 curPos = curPos + sizeof(float);
253 y = *(float *)curPos;
254 curPos = curPos + sizeof(float);
255 z = *(float *)curPos;
256 curPos = curPos + sizeof(float);
257 TRACE("x,y,z=%f,%f,%f\n", x,y,z);
259 /* RHW follows, only if transformed */
260 if (isRHW) {
261 rhw = *(float *)curPos;
262 curPos = curPos + sizeof(float);
263 TRACE("rhw=%f\n", rhw);
267 /* FIXME: Skip Blending data */
269 /* Vertex Normal Data (untransformed only) */
270 if (normal) {
271 nx = *(float *)curPos;
272 curPos = curPos + sizeof(float);
273 ny = *(float *)curPos;
274 curPos = curPos + sizeof(float);
275 nz = *(float *)curPos;
276 curPos = curPos + sizeof(float);
277 TRACE("nx,ny,nz=%f,%f,%f\n", nx,ny,nz);
280 if (isPtSize) {
281 ptSize = *(float *)curPos;
282 curPos = curPos + sizeof(float);
283 TRACE("ptSize=%f\n", ptSize);
285 if (isDiffuse) {
286 diffuseColor = *(DWORD *)curPos;
287 TRACE("diffuseColor=%lx\n", diffuseColor);
288 curPos = curPos + sizeof(DWORD);
290 if (isSpecular) {
291 specularColor = *(DWORD *)curPos;
292 TRACE("specularColor=%lx\n", specularColor);
293 curPos = curPos + sizeof(DWORD);
296 /* ToDo: Texture coords */
297 for (textureNo = 0;textureNo<numTextures; textureNo++) {
299 float s,t,r,q;
301 /* Query tex coords */
302 if (This->StateBlock.textures[textureNo] != NULL) {
303 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
304 case D3DRTYPE_TEXTURE:
305 s = *(float *)curPos;
306 curPos = curPos + sizeof(float);
307 t = *(float *)curPos;
308 curPos = curPos + sizeof(float);
309 TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t);
310 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
311 break;
313 case D3DRTYPE_VOLUMETEXTURE:
314 s = *(float *)curPos;
315 curPos = curPos + sizeof(float);
316 t = *(float *)curPos;
317 curPos = curPos + sizeof(float);
318 r = *(float *)curPos;
319 curPos = curPos + sizeof(float);
320 TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r);
321 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
322 break;
324 default:
325 r=0;q=0; /* Avoid compiler warnings, need these vars later for other textures */
326 FIXME("Unhandled texture type\n");
328 } else {
329 /* Note I have seen a program actually do this, so just hide it and continue */
330 TRACE("Very odd - texture requested in FVF but not bound!\n");
335 /* Handle these vertexes */
336 if (isDiffuse) {
337 glColor4f(((diffuseColor >> 16) & 0xFF) / 255.0,
338 ((diffuseColor >> 8) & 0xFF) / 255.0,
339 ((diffuseColor >> 0) & 0xFF) / 255.0,
340 ((diffuseColor >> 24) & 0xFF) / 255.0);
341 TRACE("glColor4f: r,g,b,a=%f,%f,%f,%f\n", ((diffuseColor >> 16) & 0xFF) / 255.0, ((diffuseColor >> 8) & 0xFF) / 255.0,
342 ((diffuseColor >> 0) & 0xFF) / 255.0, ((diffuseColor >> 24) & 0xFF) / 255.0);
345 if (normal) {
346 TRACE("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz);
347 glNormal3f(nx, ny, nz);
348 glVertex3f(x, y, z);
350 } else {
351 if (rhw < 0.01) {
352 TRACE("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z);
353 glVertex3f(x, y, z);
354 } else {
355 TRACE("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw);
356 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0 / rhw);
360 if (!isIndexed) {
361 curVtx = curVtx + skip;
365 glEnd();
366 checkGLcall("glEnd and previous calls");
368 /* If no normals, restore previous lighting state */
369 if (!normal) {
370 if (isLightingOn) glEnable(GL_LIGHTING);
371 else glDisable(GL_LIGHTING);
372 TRACE("Restored lighting to original state\n");
376 LEAVE_GL();
378 TRACE("glEnd\n");
382 Simple utility routines used for dx -> gl mapping of byte formats
384 SHORT bytesPerPixel(D3DFORMAT fmt) {
385 SHORT retVal;
387 switch (fmt) {
388 case D3DFMT_A4R4G4B4: retVal = 2; break;
389 case D3DFMT_A8R8G8B8: retVal = 4; break;
390 case D3DFMT_X8R8G8B8: retVal = 4; break;
391 case D3DFMT_R8G8B8: retVal = 3; break;
392 case D3DFMT_R5G6B5: retVal = 2; break;
393 case D3DFMT_A1R5G5B5: retVal = 2; break;
394 default:
395 FIXME("Unhandled fmt %d\n", fmt);
396 retVal = 4;
400 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
401 return retVal;
404 GLint fmt2glintFmt(D3DFORMAT fmt) {
405 GLint retVal;
407 switch (fmt) {
408 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
409 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
410 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
411 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
412 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
413 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
414 default:
415 FIXME("Unhandled fmt %d\n", fmt);
416 retVal = 4;
418 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
419 return retVal;
421 GLenum fmt2glFmt(D3DFORMAT fmt) {
422 GLenum retVal;
424 switch (fmt) {
425 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
426 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
427 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
428 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
429 case D3DFMT_R5G6B5: retVal = GL_BGR; break;
430 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
431 default:
432 FIXME("Unhandled fmt %d\n", fmt);
433 retVal = 4;
435 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
436 return retVal;
438 DWORD fmt2glType(D3DFORMAT fmt) {
439 GLenum retVal;
441 switch (fmt) {
442 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
443 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
444 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
445 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
446 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
447 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
448 default:
449 FIXME("Unhandled fmt %d\n", fmt);
450 retVal = 4;
454 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
455 return retVal;
458 int SOURCEx_RGB_EXT(DWORD arg) {
459 switch(arg) {
460 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
461 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
462 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
463 case D3DTSS_ALPHAARG0:
464 case D3DTSS_ALPHAARG1:
465 case D3DTSS_ALPHAARG2:
466 default:
467 FIXME("Invalid arg %ld\n", arg);
468 return GL_SOURCE0_RGB_EXT;
471 int OPERANDx_RGB_EXT(DWORD arg) {
472 switch(arg) {
473 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
474 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
475 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
476 case D3DTSS_ALPHAARG0:
477 case D3DTSS_ALPHAARG1:
478 case D3DTSS_ALPHAARG2:
479 default:
480 FIXME("Invalid arg %ld\n", arg);
481 return GL_OPERAND0_RGB_EXT;
484 int SOURCEx_ALPHA_EXT(DWORD arg) {
485 switch(arg) {
486 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
487 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
488 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
489 case D3DTSS_COLORARG0:
490 case D3DTSS_COLORARG1:
491 case D3DTSS_COLORARG2:
492 default:
493 FIXME("Invalid arg %ld\n", arg);
494 return GL_SOURCE0_ALPHA_EXT;
497 int OPERANDx_ALPHA_EXT(DWORD arg) {
498 switch(arg) {
499 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
500 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
501 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
502 case D3DTSS_COLORARG0:
503 case D3DTSS_COLORARG1:
504 case D3DTSS_COLORARG2:
505 default:
506 FIXME("Invalid arg %ld\n", arg);
507 return GL_OPERAND0_ALPHA_EXT;
510 GLenum StencilOp(DWORD op) {
511 switch(op) {
512 case D3DSTENCILOP_KEEP : return GL_KEEP;
513 case D3DSTENCILOP_ZERO : return GL_ZERO;
514 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
515 case D3DSTENCILOP_INCRSAT : return GL_INCR;
516 case D3DSTENCILOP_DECRSAT : return GL_DECR;
517 case D3DSTENCILOP_INVERT : return GL_INVERT;
518 case D3DSTENCILOP_INCR : return GL_INCR; /* Fixme - needs to support wrap */
519 case D3DSTENCILOP_DECR : return GL_DECR; /* Fixme - needs to support wrap */
520 default:
521 FIXME("Invalid stencil op %ld\n", op);
522 return GL_ALWAYS;
526 /* Apply the current values to the specified texture stage */
527 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
528 ICOM_THIS(IDirect3DDevice8Impl,iface);
529 int i=0;
530 float col[4];
532 /* Make appropriate texture active */
533 glActiveTextureARB(GL_TEXTURE0_ARB + i);
534 checkGLcall("glActiveTextureARB");
536 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
537 for (i=1; i<29; i++) {
538 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock.texture_state[Stage][i]);
541 /* Note the D3DRS value applies to all textures, but GL has one
542 per texture, so apply it now ready to be used! */
543 col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
544 col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
545 col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
546 col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
547 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
548 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
550 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
553 /* IDirect3D IUnknown parts follow: */
554 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
556 ICOM_THIS(IDirect3DDevice8Impl,iface);
558 if (IsEqualGUID(riid, &IID_IUnknown)
559 || IsEqualGUID(riid, &IID_IClassFactory)) {
560 IDirect3DDevice8Impl_AddRef(iface);
561 *ppobj = This;
562 return D3D_OK;
565 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
566 return E_NOINTERFACE;
569 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
570 ICOM_THIS(IDirect3DDevice8Impl,iface);
571 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
572 return ++(This->ref);
575 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
576 ICOM_THIS(IDirect3DDevice8Impl,iface);
577 ULONG ref = --This->ref;
578 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
579 if (ref == 0) {
580 HeapFree(GetProcessHeap(), 0, This);
582 return ref;
585 /* IDirect3DDevice Interface follow: */
586 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
587 ICOM_THIS(IDirect3DDevice8Impl,iface);
588 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
589 return D3D_OK;
593 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
594 ICOM_THIS(IDirect3DDevice8Impl,iface);
595 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
597 * pretend we have 32MB of any type of memory queried.
599 return (1024*1024*32);
602 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
603 ICOM_THIS(IDirect3DDevice8Impl,iface);
604 FIXME("(%p) : stub\n", This); return D3D_OK;
606 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
607 ICOM_THIS(IDirect3DDevice8Impl,iface);
608 TRACE("(%p) : returning %p\n", This, This->direct3d8);
610 /* Inc ref count */
611 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
613 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
614 return D3D_OK;
616 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
617 ICOM_THIS(IDirect3DDevice8Impl,iface);
618 FIXME("(%p) : stub, calling idirect3d for now\n", This);
619 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
620 return D3D_OK;
622 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
624 HDC hdc;
625 int bpp = 0;
627 ICOM_THIS(IDirect3DDevice8Impl,iface);
628 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
629 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
630 pMode->RefreshRate = 85; /*FIXME: How to identify? */
632 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
633 bpp = GetDeviceCaps(hdc, BITSPIXEL);
634 DeleteDC(hdc);
636 switch (bpp) {
637 case 8: pMode->Format = D3DFMT_R8G8B8; break;
638 case 16: pMode->Format = D3DFMT_R5G6B5; break;
639 case 24: pMode->Format = D3DFMT_R8G8B8; break;
640 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
641 default: pMode->Format = D3DFMT_UNKNOWN;
644 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
645 return D3D_OK;
647 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
648 ICOM_THIS(IDirect3DDevice8Impl,iface);
649 TRACE("(%p) copying to %p\n", This, pParameters);
650 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
651 return D3D_OK;
653 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
654 ICOM_THIS(IDirect3DDevice8Impl,iface);
655 FIXME("(%p) : stub\n", This); return D3D_OK;
657 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
658 ICOM_THIS(IDirect3DDevice8Impl,iface);
659 FIXME("(%p) : stub\n", This); return;
661 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
662 ICOM_THIS(IDirect3DDevice8Impl,iface);
663 FIXME("(%p) : stub\n", This); return D3D_OK;
665 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
666 ICOM_THIS(IDirect3DDevice8Impl,iface);
667 FIXME("(%p) : stub\n", This); return D3D_OK;
669 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
670 ICOM_THIS(IDirect3DDevice8Impl,iface);
671 FIXME("(%p) : stub\n", This); return D3D_OK;
673 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
674 ICOM_THIS(IDirect3DDevice8Impl,iface);
675 TRACE("(%p) : complete stub!\n", This);
677 ENTER_GL();
679 glXSwapBuffers(This->display, This->win);
680 checkGLcall("glXSwapBuffers");
682 LEAVE_GL();
684 return D3D_OK;
686 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
687 ICOM_THIS(IDirect3DDevice8Impl,iface);
688 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
689 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
691 /* Note inc ref on returned surface */
692 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
694 return D3D_OK;
696 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
697 ICOM_THIS(IDirect3DDevice8Impl,iface);
698 FIXME("(%p) : stub\n", This); return D3D_OK;
700 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
701 ICOM_THIS(IDirect3DDevice8Impl,iface);
702 FIXME("(%p) : stub\n", This); return;
704 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
705 ICOM_THIS(IDirect3DDevice8Impl,iface);
706 FIXME("(%p) : stub\n", This); return;
708 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
709 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
710 IDirect3DTexture8Impl *object;
711 int i;
712 UINT tmpW;
713 UINT tmpH;
715 ICOM_THIS(IDirect3DDevice8Impl,iface);
717 /* Allocate the storage for the device */
718 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
719 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
720 object->lpVtbl = &Direct3DTexture8_Vtbl;
721 object->Device = This;
722 object->ResourceType = D3DRTYPE_TEXTURE;
723 object->ref = 1;
724 object->width = Width;
725 object->height = Height;
726 object->levels = Levels;
727 object->usage = Usage;
728 object->format = Format;
729 object->device = This;
731 /* Calculate levels for mip mapping */
732 if (Levels == 0) {
733 object->levels++;
734 tmpW = Width;
735 tmpH = Height;
736 while (tmpW > 1 && tmpH > 1) {
737 tmpW = max(1,tmpW / 2);
738 tmpH = max(1, tmpH / 2);
739 object->levels++;
741 TRACE("Calculated levels = %d\n", object->levels);
744 /* Generate all the surfaces */
745 tmpW = Width;
746 tmpH = Height;
747 /*for (i=0; i<object->levels; i++) { */
748 i=0;
750 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
751 object->surfaces[i]->Container = object;
752 object->surfaces[i]->myDesc.Usage = Usage;
753 object->surfaces[i]->myDesc.Pool = Pool ;
755 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
756 tmpW = max(1,tmpW / 2);
757 tmpH = max(1, tmpH / 2);
760 *ppTexture = (LPDIRECT3DTEXTURE8)object;
761 return D3D_OK;
763 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
765 IDirect3DVolumeTexture8Impl *object;
766 int i;
767 UINT tmpW;
768 UINT tmpH;
769 UINT tmpD;
771 ICOM_THIS(IDirect3DDevice8Impl,iface);
773 /* Allocate the storage for it */
774 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);
775 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
776 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
777 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
778 object->ref = 1;
781 object->width = Width;
782 object->height = Height;
783 object->depth = Depth;
784 object->levels = Levels;
785 object->usage = Usage;
786 object->format = Format;
787 object->device = This;
789 /* Calculate levels for mip mapping */
790 if (Levels == 0) {
791 object->levels++;
792 tmpW = Width;
793 tmpH = Height;
794 tmpD = Depth;
795 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
796 tmpW = max(1,tmpW / 2);
797 tmpH = max(1, tmpH / 2);
798 tmpD = max(1, tmpD / 2);
799 object->levels++;
801 TRACE("Calculated levels = %d\n", object->levels);
804 /* Generate all the surfaces */
805 tmpW = Width;
806 tmpH = Height;
807 tmpD = Depth;
809 /*for (i=0; i<object->levels; i++) { */
810 i=0;
812 IDirect3DVolume8Impl *volume;
814 /* Create the volume - No entry point for this seperately?? */
815 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
816 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
818 volume->lpVtbl = &Direct3DVolume8_Vtbl;
819 volume->Device = This;
820 volume->ResourceType = D3DRTYPE_VOLUME;
821 volume->Container = object;
822 volume->ref = 1;
824 volume->myDesc.Width = Width;
825 volume->myDesc.Height= Height;
826 volume->myDesc.Depth = Depth;
827 volume->myDesc.Format= Format;
828 volume->myDesc.Type = D3DRTYPE_VOLUME;
829 volume->myDesc.Pool = Pool;
830 volume->myDesc.Usage = Usage;
831 volume->bytesPerPixel = bytesPerPixel(Format);
832 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
833 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
835 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
836 volume, volume->allocatedMemory, volume->myDesc.Size);
838 tmpW = max(1,tmpW / 2);
839 tmpH = max(1, tmpH / 2);
840 tmpD = max(1, tmpD / 2);
843 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
844 return D3D_OK;
846 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
848 IDirect3DCubeTexture8Impl *object;
849 ICOM_THIS(IDirect3DDevice8Impl,iface);
850 int i,j;
851 UINT tmpW;
853 /* Allocate the storage for it */
854 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
855 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
856 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
857 object->ref = 1;
858 object->Device = This;
859 object->ResourceType = D3DRTYPE_CUBETEXTURE;
861 object->edgeLength = EdgeLength;
862 object->levels = Levels;
863 object->usage = Usage;
864 object->format = Format;
865 object->device = This;
867 /* Calculate levels for mip mapping */
868 if (Levels == 0) {
869 object->levels++;
870 tmpW = EdgeLength;
871 while (tmpW > 1) {
872 tmpW = max(1,tmpW / 2);
873 object->levels++;
875 TRACE("Calculated levels = %d\n", object->levels);
878 /* Generate all the surfaces */
879 tmpW = EdgeLength;
880 /*for (i=0; i<object->levels; i++) { */
881 i=0;
883 /* Create the 6 faces */
884 for (j=0;j<6;j++) {
885 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
886 object->surfaces[j][i]->Container = object;
887 object->surfaces[j][i]->myDesc.Usage = Usage;
888 object->surfaces[j][i]->myDesc.Pool = Pool ;
890 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
891 tmpW = max(1,tmpW / 2);
895 TRACE("(%p) : Iface@%p\n", This, object);
896 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
897 return D3D_OK;
899 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size,DWORD Usage,
900 DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8** ppVertexBuffer) {
901 IDirect3DVertexBuffer8Impl *object;
903 ICOM_THIS(IDirect3DDevice8Impl,iface);
905 /* Allocate the storage for the device */
906 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
907 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
908 object->Device = This;
909 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
910 object->ref = 1;
911 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
912 object->currentDesc.Usage = Usage;
913 object->currentDesc.Pool = Pool;
914 object->currentDesc.FVF = FVF;
915 object->currentDesc.Size = Size;
917 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
919 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
921 return D3D_OK;
923 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
925 IDirect3DIndexBuffer8Impl *object;
927 ICOM_THIS(IDirect3DDevice8Impl,iface);
928 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
930 /* Allocate the storage for the device */
931 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
932 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
933 object->ref = 1;
934 object->Device = This;
935 object->ResourceType = D3DRTYPE_INDEXBUFFER;
937 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
938 object->currentDesc.Usage = Usage;
939 object->currentDesc.Pool = Pool;
940 object->currentDesc.Format = Format;
941 object->currentDesc.Size = Length;
943 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
945 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
947 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
949 return D3D_OK;
951 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
952 ICOM_THIS(IDirect3DDevice8Impl,iface);
953 /* up ref count on surface, surface->container = This */
954 FIXME("(%p) : stub\n", This); return D3D_OK;
956 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
957 ICOM_THIS(IDirect3DDevice8Impl,iface);
958 /* surface->container = This */
959 FIXME("(%p) : stub\n", This); return D3D_OK;
961 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
962 IDirect3DSurface8Impl *object;
964 ICOM_THIS(IDirect3DDevice8Impl,iface);
966 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
967 *ppSurface = (LPDIRECT3DSURFACE8) object;
968 object->lpVtbl = &Direct3DSurface8_Vtbl;
969 object->Device = This;
970 object->ResourceType = D3DRTYPE_SURFACE;
971 object->Container = This;
973 object->ref = 1;
974 object->myDesc.Width = Width;
975 object->myDesc.Height= Height;
976 object->myDesc.Format= Format;
977 object->myDesc.Type = D3DRTYPE_SURFACE;
978 /*object->myDesc.Usage */
979 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
980 object->bytesPerPixel = bytesPerPixel(Format);
981 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
982 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
984 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);
985 return D3D_OK;
987 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
988 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
990 HRESULT rc = D3D_OK;
992 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
993 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
995 ICOM_THIS(IDirect3DDevice8Impl,iface);
996 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
997 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
999 if (src->myDesc.Format != dst->myDesc.Format) {
1000 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1001 rc = D3DERR_INVALIDCALL;
1004 /* Quick if complete copy ... */
1005 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1006 src->myDesc.Width == dst->myDesc.Width &&
1007 src->myDesc.Height == dst->myDesc.Height)) {
1008 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1009 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1011 } else {
1012 int i;
1013 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1014 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1015 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1017 void *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1018 void *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1020 /* Copy rect by rect */
1021 for (i=0; i<cRects; i++) {
1022 CONST RECT *r = &pSourceRectsArray[i];
1023 CONST POINT *p = &pDestPointsArray[i];
1024 void *from;
1025 void *to;
1026 int copyperline = (r->right - r->left) * bytesPerPixel;
1027 int j;
1029 TRACE("Copying rect %d (%d,%d),(%d,%d) -> (%ld,%ld)\n", i, r->left, r->top,
1030 r->right, r->bottom, p->x, p->y);
1032 /* Find where to start */
1033 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1034 to = copyto + (p->y * pitchFrom) + (p->x * bytesPerPixel);
1036 /* Copy line by line */
1037 for (j=0; j<(r->bottom - r->top); j++) {
1038 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1042 return D3D_OK;
1044 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1045 ICOM_THIS(IDirect3DDevice8Impl,iface);
1046 FIXME("(%p) : stub\n", This); return D3D_OK;
1048 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1049 ICOM_THIS(IDirect3DDevice8Impl,iface);
1050 FIXME("(%p) : stub\n", This); return D3D_OK;
1052 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1053 ICOM_THIS(IDirect3DDevice8Impl,iface);
1054 FIXME("(%p) : stub\n", This);
1056 return D3D_OK;
1058 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1059 ICOM_THIS(IDirect3DDevice8Impl,iface);
1060 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1061 FIXME("(%p) : stub\n", This);
1064 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1065 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1068 return D3D_OK;
1070 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1072 ICOM_THIS(IDirect3DDevice8Impl,iface);
1074 /* Note inc ref on returned surface *
1075 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1077 FIXME("(%p) : stub\n", This);
1078 return D3D_OK;
1081 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1082 ICOM_THIS(IDirect3DDevice8Impl,iface);
1083 TRACE("(%p) : stub\n", This);
1084 return D3D_OK;
1086 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1087 ICOM_THIS(IDirect3DDevice8Impl,iface);
1088 TRACE("(%p)\n", This);
1090 ENTER_GL();
1092 glFlush();
1093 checkGLcall("glFlush");
1095 /* Useful for debugging sometimes!
1096 printf("Hit Enter ...\n");
1097 getchar(); */
1099 LEAVE_GL();
1100 return D3D_OK;
1102 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1103 ICOM_THIS(IDirect3DDevice8Impl,iface);
1105 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1106 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1107 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1108 GLbitfield glMask = 0;
1109 int i;
1110 CONST D3DRECT *curRect;
1112 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1113 Count, pRects, Flags, Z, Stencil);
1115 ENTER_GL();
1116 if (Count > 0 && pRects) {
1117 glEnable(GL_SCISSOR_TEST);
1118 checkGLcall("glEnable GL_SCISSOR_TEST");
1119 curRect = pRects;
1120 } else {
1121 curRect = NULL;
1124 for (i=0;i<Count || i==0; i++) {
1126 if (curRect) {
1127 /* Note gl uses lower left, width/height */
1128 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1129 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1130 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1131 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1132 checkGLcall("glScissor");
1133 } else {
1134 TRACE("Clearing screen with glClear to color %lx\n", Color);
1137 /* Clear the whole screen */
1138 if (Flags & D3DCLEAR_STENCIL) {
1139 glClearStencil(Stencil);
1140 checkGLcall("glClearStencil");
1141 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1144 if (Flags & D3DCLEAR_ZBUFFER) {
1145 glClearDepth(Z);
1146 checkGLcall("glClearDepth");
1147 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1150 if (Flags & D3DCLEAR_TARGET) {
1151 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1152 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1153 checkGLcall("glClearColor");
1154 glMask = glMask | GL_COLOR_BUFFER_BIT;
1157 glClear(glMask);
1158 checkGLcall("glClear");
1160 if (curRect) curRect = curRect + sizeof(D3DRECT);
1163 if (Count > 0 && pRects) {
1164 glDisable(GL_SCISSOR_TEST);
1165 checkGLcall("glDisable");
1167 LEAVE_GL();
1169 return D3D_OK;
1171 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1172 ICOM_THIS(IDirect3DDevice8Impl,iface);
1173 int k;
1175 /* Most of this routine, comments included copied from ddraw tree initially: */
1176 TRACE("(%p) : State=%d\n", This, d3dts);
1178 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1179 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1180 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1182 /* Handle recording of state blocks */
1183 if (This->isRecordingState) {
1184 TRACE("Recording... not performing anything\n");
1185 return D3D_OK;
1189 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1191 where ViewMat = Camera space, WorldMat = world space.
1193 In OpenGL, camera and world space is combined into GL_MODELVIEW
1194 matrix. The Projection matrix stay projection matrix. */
1196 /* After reading through both OpenGL and Direct3D documentations, I
1197 thought that D3D matrices were written in 'line major mode' transposed
1198 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1199 works fine to transfer one matrix format to the other (it did not work
1200 when transposing)....
1202 So :
1203 1) are the documentations wrong
1204 2) does the matrix work even if they are not read correctly
1205 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1206 loading using glLoadMatrix ?
1208 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1209 to the other so that if I ever find out that I need to transpose them, I
1210 will able to do it quickly, only by changing the macro conv_mat. */
1212 switch (d3dts) {
1213 case D3DTS_WORLDMATRIX(0): {
1214 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)]);
1215 } break;
1217 case D3DTS_VIEW: {
1218 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_VIEW]);
1219 } break;
1221 case D3DTS_PROJECTION: {
1222 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_PROJECTION]);
1223 } break;
1225 default:
1226 break;
1230 * Move the GL operation to outside of switch to make it work
1231 * regardless of transform set order. Optimize later.
1233 ENTER_GL();
1234 glMatrixMode(GL_PROJECTION);
1235 checkGLcall("glMatrixMode");
1236 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
1237 checkGLcall("glLoadMatrixf");
1239 glMatrixMode(GL_MODELVIEW);
1240 checkGLcall("glMatrixMode");
1241 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1242 checkGLcall("glLoadMatrixf");
1244 /* If we are changing the View matrix, reset the light information to the new view */
1245 if (d3dts == D3DTS_VIEW) {
1246 for (k = 0; k < MAX_ACTIVE_LIGHTS; k++) {
1247 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1248 checkGLcall("glLightfv posn");
1249 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1250 checkGLcall("glLightfv dirn");
1254 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1255 checkGLcall("glMultMatrixf");
1257 LEAVE_GL();
1259 return D3D_OK;
1262 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1263 ICOM_THIS(IDirect3DDevice8Impl,iface);
1264 TRACE("(%p) : for State %d\n", This, State);
1265 memcpy(pMatrix, &This->StateBlock.transforms[State], sizeof(D3DMATRIX));
1266 return D3D_OK;
1269 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1270 ICOM_THIS(IDirect3DDevice8Impl,iface);
1271 FIXME("(%p) : stub\n", This); return D3D_OK;
1273 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1274 ICOM_THIS(IDirect3DDevice8Impl,iface);
1276 TRACE("(%p)\n", This);
1277 This->UpdateStateBlock->Changed.viewport = TRUE;
1278 This->UpdateStateBlock->Set.viewport = TRUE;
1279 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1281 /* Handle recording of state blocks */
1282 if (This->isRecordingState) {
1283 TRACE("Recording... not performing anything\n");
1284 return D3D_OK;
1287 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1288 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1290 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1291 checkGLcall("glDepthRange");
1292 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1293 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1294 checkGLcall("glViewport");
1297 return D3D_OK;
1300 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1301 ICOM_THIS(IDirect3DDevice8Impl,iface);
1302 TRACE("(%p)\n", This);
1303 memcpy(pViewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
1304 return D3D_OK;
1307 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1308 ICOM_THIS(IDirect3DDevice8Impl,iface);
1310 This->UpdateStateBlock->Changed.material = TRUE;
1311 This->UpdateStateBlock->Set.material = TRUE;
1312 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1314 /* Handle recording of state blocks */
1315 if (This->isRecordingState) {
1316 TRACE("Recording... not performing anything\n");
1317 return D3D_OK;
1320 ENTER_GL();
1321 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1322 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1323 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1324 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1325 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1327 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1328 checkGLcall("glMaterialfv");
1329 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1330 checkGLcall("glMaterialfv");
1332 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1333 checkGLcall("glMaterialfv");
1334 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1335 checkGLcall("glMaterialfv");
1336 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1337 checkGLcall("glMaterialf");
1339 LEAVE_GL();
1340 return D3D_OK;
1342 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1343 ICOM_THIS(IDirect3DDevice8Impl,iface);
1344 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1345 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1346 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1347 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1348 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1349 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1350 return D3D_OK;
1353 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1354 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1355 float rho;
1356 float quad_att;
1358 ICOM_THIS(IDirect3DDevice8Impl,iface);
1359 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1361 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,
1362 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1363 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1364 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1365 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1366 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1367 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1369 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1370 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1371 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1373 /* Handle recording of state blocks */
1374 if (This->isRecordingState) {
1375 TRACE("Recording... not performing anything\n");
1376 return D3D_OK;
1379 /* Diffuse: */
1380 colRGBA[0] = pLight->Diffuse.r;
1381 colRGBA[1] = pLight->Diffuse.g;
1382 colRGBA[2] = pLight->Diffuse.b;
1383 colRGBA[3] = pLight->Diffuse.a;
1384 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1385 checkGLcall("glLightfv");
1387 /* Specular */
1388 colRGBA[0] = pLight->Specular.r;
1389 colRGBA[1] = pLight->Specular.g;
1390 colRGBA[2] = pLight->Specular.b;
1391 colRGBA[3] = pLight->Specular.a;
1392 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1393 checkGLcall("glLightfv");
1395 /* Ambient */
1396 colRGBA[0] = pLight->Ambient.r;
1397 colRGBA[1] = pLight->Ambient.g;
1398 colRGBA[2] = pLight->Ambient.b;
1399 colRGBA[3] = pLight->Ambient.a;
1400 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1401 checkGLcall("glLightfv");
1403 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1404 glMatrixMode(GL_MODELVIEW);
1405 glPushMatrix();
1406 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1408 /* Attenuation - Are these right? guessing... */
1409 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
1410 checkGLcall("glLightf");
1411 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
1412 checkGLcall("glLightf");
1414 quad_att = 1.4/(pLight->Range*pLight->Range);
1415 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1416 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1417 checkGLcall("glLightf");
1419 switch (pLight->Type) {
1420 case D3DLIGHT_POINT:
1421 /* Position */
1422 This->lightPosn[Index][0] = pLight->Position.x;
1423 This->lightPosn[Index][1] = pLight->Position.y;
1424 This->lightPosn[Index][2] = pLight->Position.z;
1425 This->lightPosn[Index][3] = 1.0;
1426 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1427 checkGLcall("glLightfv");
1429 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1430 checkGLcall("glLightf");
1432 /* FIXME: Range */
1433 break;
1435 case D3DLIGHT_SPOT:
1436 /* Position */
1437 This->lightPosn[Index][0] = pLight->Position.x;
1438 This->lightPosn[Index][1] = pLight->Position.y;
1439 This->lightPosn[Index][2] = pLight->Position.z;
1440 This->lightPosn[Index][3] = 1.0;
1441 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1442 checkGLcall("glLightfv");
1444 /* Direction */
1445 This->lightDirn[Index][0] = pLight->Direction.x;
1446 This->lightDirn[Index][1] = pLight->Direction.y;
1447 This->lightDirn[Index][2] = pLight->Direction.z;
1448 This->lightDirn[Index][3] = 1.0;
1449 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1450 checkGLcall("glLightfv");
1453 * opengl-ish and d3d-ish spot lights use too different models for the
1454 * light "intensity" as a function of the angle towards the main light direction,
1455 * so we only can approximate very roughly.
1456 * however spot lights are rather rarely used in games (if ever used at all).
1457 * furthermore if still used, probably nobody pays attention to such details.
1459 if (pLight->Falloff == 0) {
1460 rho = 6.28f;
1461 } else {
1462 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1464 if (rho < 0.0001) rho = 0.0001f;
1465 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
1466 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
1468 /* FIXME: Range */
1469 break;
1470 case D3DLIGHT_DIRECTIONAL:
1471 /* Direction */
1472 This->lightPosn[Index][0] = -pLight->Direction.x;
1473 This->lightPosn[Index][1] = -pLight->Direction.y;
1474 This->lightPosn[Index][2] = -pLight->Direction.z;
1475 This->lightPosn[Index][3] = 0.0;
1476 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
1477 checkGLcall("glLightfv");
1479 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
1480 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
1483 break;
1484 default:
1485 FIXME("Unrecognized light type %d\n", pLight->Type);
1488 /* Restore the modelview matrix */
1489 glPopMatrix();
1491 return D3D_OK;
1493 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1494 ICOM_THIS(IDirect3DDevice8Impl,iface);
1495 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1496 memcpy(pLight, &This->StateBlock.lights[Index], sizeof(D3DLIGHT8));
1497 return D3D_OK;
1499 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1500 ICOM_THIS(IDirect3DDevice8Impl,iface);
1501 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
1503 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
1504 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
1505 This->UpdateStateBlock->lightEnable[Index] = Enable;
1507 /* Handle recording of state blocks */
1508 if (This->isRecordingState) {
1509 TRACE("Recording... not performing anything\n");
1510 return D3D_OK;
1513 if (Enable) {
1514 glEnable(GL_LIGHT0+Index);
1515 checkGLcall("glEnable GL_LIGHT0+Index");
1516 } else {
1517 glDisable(GL_LIGHT0+Index);
1518 checkGLcall("glDisable GL_LIGHT0+Index");
1520 return D3D_OK;
1522 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1523 ICOM_THIS(IDirect3DDevice8Impl,iface);
1524 TRACE("(%p) : for idx(%ld)\n", This, Index);
1525 *pEnable = This->StateBlock.lightEnable[Index];
1526 return D3D_OK;
1528 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1529 ICOM_THIS(IDirect3DDevice8Impl,iface);
1530 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
1532 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
1533 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
1534 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
1535 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
1536 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
1537 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
1539 /* Handle recording of state blocks */
1540 if (This->isRecordingState) {
1541 TRACE("Recording... not performing anything\n");
1542 return D3D_OK;
1545 /* Apply it */
1547 /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
1548 glMatrixMode(GL_MODELVIEW);
1549 glPushMatrix();
1550 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLD].u.m[0][0]);
1552 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
1553 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
1554 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
1556 glPopMatrix();
1557 checkGLcall("glClipPlane");
1559 return D3D_OK;
1561 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1562 ICOM_THIS(IDirect3DDevice8Impl,iface);
1563 TRACE("(%p) : for idx %ld\n", This, Index);
1564 pPlane[0] = This->StateBlock.clipplane[Index][0];
1565 pPlane[1] = This->StateBlock.clipplane[Index][0];
1566 pPlane[2] = This->StateBlock.clipplane[Index][0];
1567 pPlane[3] = This->StateBlock.clipplane[Index][0];
1568 return D3D_OK;
1570 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
1571 ICOM_THIS(IDirect3DDevice8Impl,iface);
1572 DWORD OldValue = This->StateBlock.renderstate[State];
1574 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
1575 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
1576 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
1577 This->UpdateStateBlock->renderstate[State] = Value;
1579 /* Handle recording of state blocks */
1580 if (This->isRecordingState) {
1581 TRACE("Recording... not performing anything\n");
1582 return D3D_OK;
1585 switch (State) {
1586 case D3DRS_FILLMODE :
1587 switch ((D3DFILLMODE) Value) {
1588 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
1589 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
1590 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
1591 default:
1592 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
1594 checkGLcall("glPolygonMode (fillmode)");
1595 break;
1597 case D3DRS_LIGHTING :
1598 if (Value) {
1599 glEnable(GL_LIGHTING);
1600 checkGLcall("glEnable GL_LIGHTING");
1601 } else {
1602 glDisable(GL_LIGHTING);
1603 checkGLcall("glDisable GL_LIGHTING");
1605 break;
1607 case D3DRS_ZENABLE :
1608 switch ((D3DZBUFFERTYPE) Value) {
1609 case D3DZB_FALSE:
1610 glDisable(GL_DEPTH_TEST);
1611 checkGLcall("glDisable GL_DEPTH_TEST");
1612 break;
1613 case D3DZB_TRUE:
1614 glEnable(GL_DEPTH_TEST);
1615 checkGLcall("glEnable GL_DEPTH_TEST");
1616 break;
1618 case D3DZB_USEW:
1619 default:
1620 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
1622 break;
1624 case D3DRS_CULLMODE :
1626 /* If we are culling "back faces with clockwise vertices" then
1627 set front faces to be counter clockwise and enable culling
1628 of back faces */
1629 switch ((D3DCULL) Value) {
1630 case D3DCULL_NONE:
1631 glDisable(GL_CULL_FACE);
1632 checkGLcall("glDisable GL_CULL_FACE");
1633 break;
1634 case D3DCULL_CW:
1635 glEnable(GL_CULL_FACE);
1636 checkGLcall("glEnable GL_CULL_FACE");
1637 glFrontFace(GL_CCW);
1638 checkGLcall("glFrontFace GL_CCW");
1639 glCullFace(GL_BACK);
1640 break;
1641 case D3DCULL_CCW:
1642 glEnable(GL_CULL_FACE);
1643 checkGLcall("glEnable GL_CULL_FACE");
1644 glFrontFace(GL_CW);
1645 checkGLcall("glFrontFace GL_CW");
1646 glCullFace(GL_BACK);
1647 break;
1648 default:
1649 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
1651 break;
1653 case D3DRS_SHADEMODE :
1654 switch ((D3DSHADEMODE) Value) {
1655 case D3DSHADE_FLAT:
1656 glShadeModel(GL_FLAT);
1657 checkGLcall("glShadeModel");
1658 break;
1659 case D3DSHADE_GOURAUD:
1660 glShadeModel(GL_SMOOTH);
1661 checkGLcall("glShadeModel");
1662 break;
1663 case D3DSHADE_PHONG:
1664 FIXME("D3DSHADE_PHONG isnt supported?\n");
1665 return D3DERR_INVALIDCALL;
1666 default:
1667 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
1669 break;
1671 case D3DRS_DITHERENABLE :
1672 if (Value) {
1673 glEnable(GL_DITHER);
1674 checkGLcall("glEnable GL_DITHER");
1675 } else {
1676 glDisable(GL_DITHER);
1677 checkGLcall("glDisable GL_DITHER");
1679 break;
1681 case D3DRS_ZWRITEENABLE :
1682 if (Value) {
1683 glDepthMask(1);
1684 checkGLcall("glDepthMask");
1685 } else {
1686 glDepthMask(0);
1687 checkGLcall("glDepthMask");
1689 break;
1691 case D3DRS_ZFUNC :
1693 int glParm = GL_LESS;
1695 switch ((D3DCMPFUNC) Value) {
1696 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1697 case D3DCMP_LESS: glParm=GL_LESS; break;
1698 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1699 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1700 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1701 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1702 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1703 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1704 default:
1705 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1707 glDepthFunc(glParm);
1708 checkGLcall("glDepthFunc");
1710 break;
1712 case D3DRS_AMBIENT :
1715 float col[4];
1716 col[0] = ((Value >> 16) & 0xFF) / 255.0;
1717 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1718 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1719 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1720 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
1721 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
1722 checkGLcall("glLightModel for MODEL_AMBIENT");
1725 break;
1727 case D3DRS_ALPHABLENDENABLE :
1728 if (Value) {
1729 glEnable(GL_BLEND);
1730 checkGLcall("glEnable GL_BLEND");
1731 } else {
1732 glDisable(GL_BLEND);
1733 checkGLcall("glDisable GL_BLEND");
1735 break;
1737 case D3DRS_SRCBLEND :
1738 case D3DRS_DESTBLEND :
1740 int newVal = GL_ZERO;
1741 switch (Value) {
1742 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
1743 case D3DBLEND_ONE : newVal = GL_ONE; break;
1744 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
1745 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
1746 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
1747 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
1748 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
1749 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
1750 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
1751 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
1752 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
1754 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
1755 This->srcBlend = newVal;
1756 This->dstBlend = newVal;
1757 break;
1759 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
1760 This->srcBlend = newVal;
1761 This->dstBlend = newVal;
1762 break;
1763 default:
1764 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
1767 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
1768 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
1769 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
1770 glBlendFunc(This->srcBlend, This->dstBlend);
1772 checkGLcall("glBlendFunc");
1774 break;
1776 case D3DRS_ALPHATESTENABLE :
1777 if (Value) {
1778 glEnable(GL_ALPHA_TEST);
1779 checkGLcall("glEnable GL_ALPHA_TEST");
1780 } else {
1781 glDisable(GL_ALPHA_TEST);
1782 checkGLcall("glDisable GL_ALPHA_TEST");
1784 break;
1786 case D3DRS_ALPHAFUNC :
1788 int glParm = GL_LESS;
1789 float ref = 1.0;
1791 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
1792 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
1794 switch ((D3DCMPFUNC) Value) {
1795 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1796 case D3DCMP_LESS: glParm=GL_LESS; break;
1797 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1798 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1799 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1800 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1801 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1802 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1803 default:
1804 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1806 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1807 glAlphaFunc(glParm, ref);
1808 checkGLcall("glAlphaFunc");
1810 break;
1812 case D3DRS_ALPHAREF :
1814 int glParm = GL_LESS;
1815 float ref = 1.0;
1817 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
1818 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
1820 ref = ((float) Value) / 255.0;
1821 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1822 glAlphaFunc(glParm, ref);
1823 checkGLcall("glAlphaFunc");
1825 break;
1827 case D3DRS_CLIPPLANEENABLE :
1828 case D3DRS_CLIPPING :
1830 /* Ensure we only do the changed clip planes */
1831 DWORD enable = 0xFFFFFFFF;
1832 DWORD disable = 0x00000000;
1834 /* If enabling / disabling all */
1835 if (State == D3DRS_CLIPPING) {
1836 if (Value) {
1837 enable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1838 disable = 0x00;
1839 } else {
1840 disable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1841 enable = 0x00;
1843 } else {
1844 enable = Value & ~OldValue;
1845 disable = ~Value & OldValue;
1848 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
1849 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
1850 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
1851 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
1852 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
1853 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
1855 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
1856 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
1857 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
1858 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
1859 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
1860 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
1862 break;
1864 case D3DRS_BLENDOP :
1866 int glParm = GL_FUNC_ADD;
1868 switch ((D3DBLENDOP) Value) {
1869 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
1870 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
1871 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
1872 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
1873 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
1874 default:
1875 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
1877 glBlendEquation(glParm);
1878 checkGLcall("glBlendEquation");
1880 break;
1882 case D3DRS_TEXTUREFACTOR :
1884 int i;
1886 /* Note the texture color applies to all textures whereas
1887 GL_TEXTURE_ENV_COLOR applies to active only */
1888 float col[4];
1889 col[0] = ((Value >> 16) & 0xFF) / 255.0;
1890 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1891 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1892 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1894 /* Set the default alpha blend color */
1895 glBlendColor(col[0], col[1], col[2], col[3]);
1896 checkGLcall("glBlendColor");
1898 /* And now the default texture color as well */
1899 for (i=0; i<8; i++) {
1901 /* Note the D3DRS value applies to all textures, but GL has one
1902 per texture, so apply it now ready to be used! */
1903 checkGLcall("Activate texture.. to update const color");
1904 glActiveTextureARB(GL_TEXTURE0_ARB + i);
1906 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1907 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1910 break;
1912 case D3DRS_SPECULARENABLE :
1914 if (Value) {
1915 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
1916 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
1917 } else {
1918 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
1919 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
1922 break;
1924 case D3DRS_STENCILENABLE :
1925 if (Value) {
1926 glEnable(GL_STENCIL_TEST);
1927 checkGLcall("glEnable GL_STENCIL_TEST");
1928 } else {
1929 glDisable(GL_STENCIL_TEST);
1930 checkGLcall("glDisable GL_STENCIL_TEST");
1932 break;
1934 case D3DRS_STENCILFUNC :
1936 int glParm = GL_ALWAYS;
1937 int ref = 0;
1938 GLuint mask = 0xFFFFFFFF;
1940 glGetIntegerv(GL_STENCIL_REF, &ref);
1941 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1942 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1943 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1945 switch ((D3DCMPFUNC) Value) {
1946 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1947 case D3DCMP_LESS: glParm=GL_LESS; break;
1948 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1949 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1950 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1951 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1952 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1953 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1954 default:
1955 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1957 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1958 glStencilFunc(glParm, ref, mask);
1959 checkGLcall("glStencilFunc");
1961 break;
1963 case D3DRS_STENCILREF :
1965 int glParm = GL_ALWAYS;
1966 int ref = 0;
1967 GLuint mask = 0xFFFFFFFF;
1969 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1970 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1971 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1972 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1974 ref = Value;
1975 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1976 glStencilFunc(glParm, ref, mask);
1977 checkGLcall("glStencilFunc");
1979 break;
1981 case D3DRS_STENCILMASK :
1983 int glParm = GL_ALWAYS;
1984 int ref = 0.0;
1985 GLuint mask = Value;
1987 glGetIntegerv(GL_STENCIL_REF, &ref);
1988 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1989 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1990 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1992 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1993 glStencilFunc(glParm, ref, mask);
1994 checkGLcall("glStencilFunc");
1996 break;
1998 case D3DRS_STENCILFAIL :
2000 GLenum fail ;
2001 GLenum zpass ;
2002 GLenum zfail ;
2004 fail = StencilOp(Value);
2005 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2006 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2007 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2008 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2010 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2011 glStencilOp(fail, zfail, zpass);
2012 checkGLcall("glStencilOp(fail, zfail, zpass);");
2014 break;
2015 case D3DRS_STENCILZFAIL :
2017 GLenum fail ;
2018 GLenum zpass ;
2019 GLenum zfail ;
2021 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2022 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2023 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2024 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2025 zfail = StencilOp(Value);
2027 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2028 glStencilOp(fail, zfail, zpass);
2029 checkGLcall("glStencilOp(fail, zfail, zpass);");
2031 break;
2032 case D3DRS_STENCILPASS :
2034 GLenum fail ;
2035 GLenum zpass ;
2036 GLenum zfail ;
2038 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2039 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2040 zpass = StencilOp(Value);
2041 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2042 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2044 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2045 glStencilOp(fail, zfail, zpass);
2046 checkGLcall("glStencilOp(fail, zfail, zpass);");
2048 break;
2050 case D3DRS_STENCILWRITEMASK :
2052 glStencilMask(Value);
2053 checkGLcall("glStencilMask");
2055 break;
2057 /* Unhandled yet...! */
2058 case D3DRS_LINEPATTERN :
2059 case D3DRS_LASTPIXEL :
2060 case D3DRS_FOGENABLE :
2061 case D3DRS_ZVISIBLE :
2062 case D3DRS_FOGCOLOR :
2063 case D3DRS_FOGTABLEMODE :
2064 case D3DRS_FOGSTART :
2065 case D3DRS_FOGEND :
2066 case D3DRS_FOGDENSITY :
2067 case D3DRS_EDGEANTIALIAS :
2068 case D3DRS_ZBIAS :
2069 case D3DRS_RANGEFOGENABLE :
2070 case D3DRS_WRAP0 :
2071 case D3DRS_WRAP1 :
2072 case D3DRS_WRAP2 :
2073 case D3DRS_WRAP3 :
2074 case D3DRS_WRAP4 :
2075 case D3DRS_WRAP5 :
2076 case D3DRS_WRAP6 :
2077 case D3DRS_WRAP7 :
2078 case D3DRS_FOGVERTEXMODE :
2079 case D3DRS_COLORVERTEX :
2080 case D3DRS_LOCALVIEWER :
2081 case D3DRS_NORMALIZENORMALS :
2082 case D3DRS_DIFFUSEMATERIALSOURCE :
2083 case D3DRS_SPECULARMATERIALSOURCE :
2084 case D3DRS_AMBIENTMATERIALSOURCE :
2085 case D3DRS_EMISSIVEMATERIALSOURCE :
2086 case D3DRS_VERTEXBLEND :
2087 case D3DRS_SOFTWAREVERTEXPROCESSING :
2088 case D3DRS_POINTSIZE :
2089 case D3DRS_POINTSIZE_MIN :
2090 case D3DRS_POINTSPRITEENABLE :
2091 case D3DRS_POINTSCALEENABLE :
2092 case D3DRS_POINTSCALE_A :
2093 case D3DRS_POINTSCALE_B :
2094 case D3DRS_POINTSCALE_C :
2095 case D3DRS_MULTISAMPLEANTIALIAS :
2096 case D3DRS_MULTISAMPLEMASK :
2097 case D3DRS_PATCHEDGESTYLE :
2098 case D3DRS_PATCHSEGMENTS :
2099 case D3DRS_DEBUGMONITORTOKEN :
2100 case D3DRS_POINTSIZE_MAX :
2101 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2102 case D3DRS_COLORWRITEENABLE :
2103 case D3DRS_TWEENFACTOR :
2104 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2105 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2106 break;
2107 default:
2108 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2111 return D3D_OK;
2113 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2114 ICOM_THIS(IDirect3DDevice8Impl,iface);
2115 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2116 *pValue = This->StateBlock.renderstate[State];
2117 return D3D_OK;
2119 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2120 ICOM_THIS(IDirect3DDevice8Impl,iface);
2122 void *memory;
2124 TRACE("(%p)\n", This);
2125 if (This->isRecordingState) {
2126 TRACE("(%p) already recording! returning error\n", This);
2127 return D3DERR_INVALIDCALL;
2130 /* Allocate Storage */
2131 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2132 This->isRecordingState = TRUE;
2133 This->UpdateStateBlock = memory;
2135 return D3D_OK;
2137 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2139 ICOM_THIS(IDirect3DDevice8Impl,iface);
2140 TRACE("(%p)\n", This);
2142 if (!This->isRecordingState) {
2143 TRACE("(%p) not recording! returning error\n", This);
2144 return D3DERR_INVALIDCALL;
2147 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2148 *pToken = (DWORD) This->UpdateStateBlock;
2149 This->isRecordingState = FALSE;
2150 This->UpdateStateBlock = &This->StateBlock;
2152 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2153 return D3D_OK;
2156 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2158 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2159 int i,j;
2161 ICOM_THIS(IDirect3DDevice8Impl,iface);
2162 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2164 /* FIXME: Only apply applicable states not all states */
2166 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2168 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2170 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2171 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2172 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2173 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2176 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2177 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2179 /* TODO: Vertex Shader Constants */
2182 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2184 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2185 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->PixelShader);
2187 /* TODO: Pixel Shader Constants */
2190 /* Others + Render & Texture */
2191 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2192 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2193 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2194 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2197 if (pSB->Set.Indices && pSB->Changed.Indices)
2198 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2200 if (pSB->Set.material && pSB->Changed.material)
2201 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2203 if (pSB->Set.viewport && pSB->Changed.viewport)
2204 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2206 for (i=0; i<MAX_STREAMS; i++) {
2207 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2208 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2211 for (i=0; i<MAX_CLIPPLANES; i++) {
2212 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2213 float clip[4];
2215 clip[0] = pSB->clipplane[i][0];
2216 clip[1] = pSB->clipplane[i][1];
2217 clip[2] = pSB->clipplane[i][2];
2218 clip[3] = pSB->clipplane[i][3];
2219 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2223 /* Render */
2224 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2226 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2227 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2231 /* Texture */
2232 for (j=0; j<8; j++) {
2233 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2235 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i])
2236 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2241 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2243 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2244 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2245 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2249 for (j=0; j<8; i++) {
2250 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2252 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2253 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2254 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2258 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2260 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2261 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2262 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2266 for (j=0; j<8; i++) {
2267 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2269 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2270 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2271 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2276 } else {
2277 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2279 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2280 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2282 return D3D_OK;
2284 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2286 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2288 ICOM_THIS(IDirect3DDevice8Impl,iface);
2290 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2292 /* If not recorded, then update can just recapture */
2293 if (updateBlock->blockType != D3DSBT_RECORDED) {
2294 DWORD tmpToken;
2295 STATEBLOCK *tmpBlock;
2296 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2297 tmpBlock = (STATEBLOCK *)tmpToken;
2298 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2299 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2301 /* FIXME: This will record states of new lights! May need to have and save set_lights
2302 across this action */
2304 } else {
2305 int i,j;
2307 /* Recorded => Only update 'changed' values */
2308 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2309 updateBlock->VertexShader = This->StateBlock.VertexShader;
2310 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2313 /* TODO: Vertex Shader Constants */
2315 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2316 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2317 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2318 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2321 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2322 &updateBlock->lights[i],
2323 sizeof(D3DLIGHT8)) != 0) {
2324 TRACE("Updating lights for light %d\n", i);
2325 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2329 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2330 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2331 updateBlock->lights[i] = This->StateBlock.lights[i];
2332 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2335 /* TODO: Pixel Shader Constants */
2337 /* Others + Render & Texture */
2338 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2339 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2340 &updateBlock->transforms[i],
2341 sizeof(D3DMATRIX)) != 0) {
2342 TRACE("Updating transform %d\n", i);
2343 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2347 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2348 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2349 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2350 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2351 updateBlock->pIndexData = This->StateBlock.pIndexData;
2352 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2355 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2356 &updateBlock->material,
2357 sizeof(D3DMATERIAL8)) != 0) {
2358 TRACE("Updating material\n");
2359 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2362 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2363 &updateBlock->viewport,
2364 sizeof(D3DVIEWPORT8)) != 0) {
2365 TRACE("Updating viewport\n");
2366 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2369 for (i=0; i<MAX_STREAMS; i++) {
2370 if (updateBlock->Set.stream_source[i] &&
2371 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2372 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2373 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2374 This->StateBlock.stream_stride[i]);
2375 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2376 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2380 for (i=0; i<MAX_CLIPPLANES; i++) {
2381 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2382 &updateBlock->clipplane[i],
2383 sizeof(updateBlock->clipplane)) != 0) {
2385 TRACE("Updating clipplane %d\n", i);
2386 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2387 sizeof(updateBlock->clipplane));
2391 /* Render */
2392 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2394 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
2395 This->StateBlock.renderstate[i])) {
2396 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2397 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2401 /* Texture */
2402 for (j=0; j<8; j++) {
2403 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2405 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
2406 This->StateBlock.texture_state[j][i])) {
2407 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
2408 updateBlock->texture_state[j][i]);
2409 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
2416 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2418 return D3D_OK;
2420 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2421 ICOM_THIS(IDirect3DDevice8Impl,iface);
2422 TRACE("(%p) : freeing token %lx\n", This, Token);
2423 HeapFree(GetProcessHeap(), 0, (void *)Token);
2424 return D3D_OK;
2427 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type,DWORD* pToken) {
2428 void *memory;
2429 STATEBLOCK *s;
2430 int i,j;
2432 ICOM_THIS(IDirect3DDevice8Impl,iface);
2433 TRACE("(%p) : for type %d\n", This, Type);
2435 /* Allocate Storage */
2436 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2437 if (memory) memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2438 *pToken = (DWORD) memory;
2439 s = memory;
2440 s->blockType = Type;
2442 TRACE("Updating changed flags appropriate for type %d\n", Type);
2444 if (Type == D3DSBT_ALL) {
2445 TRACE("ALL => Pretend everything has changed\n");
2446 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2448 } else if (Type == D3DSBT_PIXELSTATE) {
2450 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2452 /* TODO: Pixel Shader Constants */
2453 s->Changed.pixelShader = TRUE;
2454 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2455 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2457 for (j=0; j<8; i++) {
2458 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2459 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2463 } else if (Type == D3DSBT_VERTEXSTATE) {
2465 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2467 /* TODO: Vertex Shader Constants */
2468 s->Changed.vertexShader = TRUE;
2470 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2471 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2473 for (j=0; j<8; i++) {
2474 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2475 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2479 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2480 s->Changed.lightEnable[i] = TRUE;
2481 s->Changed.lights[i] = TRUE;
2484 } else {
2485 FIXME("Unrecognized state block type %d\n", Type);
2487 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2488 return D3D_OK;
2491 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2492 ICOM_THIS(IDirect3DDevice8Impl,iface);
2493 FIXME("(%p) : stub\n", This); return D3D_OK;
2495 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2496 ICOM_THIS(IDirect3DDevice8Impl,iface);
2497 FIXME("(%p) : stub\n", This); return D3D_OK;
2499 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2500 ICOM_THIS(IDirect3DDevice8Impl,iface);
2501 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2502 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
2503 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2504 return D3D_OK;
2506 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2508 IDirect3DBaseTexture8 *oldTxt;
2510 ICOM_THIS(IDirect3DDevice8Impl,iface);
2511 D3DRESOURCETYPE textureType;
2513 oldTxt = This->StateBlock.textures[Stage];
2514 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2516 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2517 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2518 This->UpdateStateBlock->textures[Stage] = pTexture;
2520 /* Handle recording of state blocks */
2521 if (This->isRecordingState) {
2522 TRACE("Recording... not performing anything\n");
2523 return D3D_OK;
2526 /* Make appropriate texture active */
2527 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2528 checkGLcall("glActiveTextureARB");
2530 /* Decrement the count of the previous texture */
2531 if (oldTxt != NULL) {
2532 IDirect3DBaseTexture8Impl_Release(oldTxt);
2535 if (pTexture) {
2536 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
2538 /* Now setup the texture appropraitly */
2539 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2541 if (textureType == D3DRTYPE_TEXTURE) {
2542 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
2543 int i;
2545 /* Standard 2D texture */
2546 TRACE("Standard 2d texture\n");
2547 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
2549 /* for (i=0; i<pTexture2->levels; i++) { */
2550 i=0;
2553 if (pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2554 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2555 checkGLcall("glBindTexture");
2556 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2557 } else {
2559 if (pTexture2->surfaces[i]->textureName == 0) {
2560 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
2561 checkGLcall("glGenTextures");
2562 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2565 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2566 checkGLcall("glBindTexture");
2568 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2569 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
2570 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2571 pTexture2->surfaces[i]->allocatedMemory);
2572 glTexImage2D(GL_TEXTURE_2D, i,
2573 fmt2glintFmt(pTexture2->format),
2574 pTexture2->surfaces[i]->myDesc.Width,
2575 pTexture2->surfaces[i]->myDesc.Height,
2577 fmt2glFmt(pTexture2->format),
2578 fmt2glType(pTexture2->format),
2579 pTexture2->surfaces[i]->allocatedMemory
2581 checkGLcall("glTexImage2D");
2584 * The following enable things to work but I dont think
2585 * they all go here - FIXME! @@@
2587 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2588 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2589 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2590 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2592 pTexture2->Dirty = FALSE;
2597 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
2598 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
2599 int i;
2601 /* Standard 3D (volume) texture */
2602 TRACE("Standard 3d texture\n");
2603 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
2605 /* for (i=0; i<pTexture2->levels; i++) { */
2606 i=0;
2609 if (pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2610 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2611 checkGLcall("glBindTexture");
2612 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2613 } else {
2615 if (pTexture2->volumes[i]->textureName == 0) {
2616 glGenTextures(1, &pTexture2->volumes[i]->textureName);
2617 checkGLcall("glGenTextures");
2618 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2621 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2622 checkGLcall("glBindTexture");
2624 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2625 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
2626 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
2627 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2628 pTexture2->volumes[i]->allocatedMemory);
2629 glTexImage3D(GL_TEXTURE_3D, i,
2630 fmt2glintFmt(pTexture2->format),
2631 pTexture2->volumes[i]->myDesc.Width,
2632 pTexture2->volumes[i]->myDesc.Height,
2633 pTexture2->volumes[i]->myDesc.Depth,
2635 fmt2glFmt(pTexture2->format),
2636 fmt2glType(pTexture2->format),
2637 pTexture2->volumes[i]->allocatedMemory
2639 checkGLcall("glTexImage3D");
2642 * The following enable things to work but I dont think
2643 * they all go here - FIXME! @@@
2645 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2646 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2647 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
2648 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2649 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2651 pTexture2->Dirty = FALSE;
2655 } else {
2656 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
2658 } else {
2659 TRACE("Setting to no texture (ie default texture)\n");
2660 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
2661 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
2662 checkGLcall("glBindTexture");
2663 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
2666 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
2667 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
2668 setupTextureStates (iface, Stage);
2670 return D3D_OK;
2673 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
2674 ICOM_THIS(IDirect3DDevice8Impl,iface);
2675 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
2676 *pValue = This->StateBlock.texture_state[Stage][Type];
2677 return D3D_OK;
2680 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
2681 ICOM_THIS(IDirect3DDevice8Impl,iface);
2683 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2685 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
2687 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
2688 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
2689 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
2691 /* Handle recording of state blocks */
2692 if (This->isRecordingState) {
2693 TRACE("Recording... not performing anything\n");
2694 return D3D_OK;
2697 /* Make appropriate texture active */
2698 TRACE("Activating appropriate texture state %ld\n", Stage);
2699 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2700 checkGLcall("glActiveTextureARB");
2702 switch (Type) {
2704 case D3DTSS_MINFILTER :
2705 if (Value == D3DTEXF_POINT) {
2706 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2707 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_NEAREST");
2708 } else if (Value == D3DTEXF_LINEAR) {
2709 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2710 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_LINEAR");
2711 } else {
2712 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", Value);
2714 break;
2717 case D3DTSS_MAGFILTER :
2718 if (Value == D3DTEXF_POINT) {
2719 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2720 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
2721 } else if (Value == D3DTEXF_LINEAR) {
2722 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2723 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
2724 } else {
2725 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
2727 break;
2729 case D3DTSS_COLORARG0 :
2730 case D3DTSS_ALPHAARG0 :
2731 /* FIXME: Mesa seems to struggle setting these at the moment */
2732 break;
2734 case D3DTSS_COLORARG1 :
2735 case D3DTSS_COLORARG2 :
2736 case D3DTSS_ALPHAARG1 :
2737 case D3DTSS_ALPHAARG2 :
2739 BOOL isAlphaReplicate = FALSE;
2740 BOOL isComplement = FALSE;
2741 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
2742 int operand= GL_SRC_COLOR;
2743 int source = GL_TEXTURE;
2745 /* Catch alpha replicate */
2746 if (Value & D3DTA_ALPHAREPLICATE) {
2747 Value = Value & ~D3DTA_ALPHAREPLICATE;
2748 isAlphaReplicate = TRUE;
2751 /* Catch Complement */
2752 if (Value & D3DTA_COMPLEMENT) {
2753 Value = Value & ~D3DTA_COMPLEMENT;
2754 isComplement = TRUE;
2757 /* Calculate the operand */
2758 if (isAlphaReplicate && !isComplement) {
2759 operand = GL_SRC_ALPHA;
2760 } else if (isAlphaReplicate && isComplement) {
2761 operand = GL_ONE_MINUS_SRC_ALPHA;
2762 } else if (isComplement) {
2763 if (isAlphaArg) {
2764 operand = GL_ONE_MINUS_SRC_COLOR;
2765 } else {
2766 operand = GL_ONE_MINUS_SRC_ALPHA;
2768 } else {
2769 if (isAlphaArg) {
2770 operand = GL_SRC_ALPHA;
2771 } else {
2772 operand = GL_SRC_COLOR;
2776 /* Calculate the source */
2777 switch (Value) {
2778 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
2779 break;
2780 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
2781 break;
2782 case D3DTA_TEXTURE: source = GL_TEXTURE;
2783 break;
2784 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
2785 break;
2787 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
2788 isnt supported until base GL supports it
2789 There is no concept of temp registers as far as I can tell */
2791 default:
2792 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
2795 if (isAlphaArg) {
2796 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
2797 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
2798 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
2799 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
2800 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
2801 } else {
2802 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
2803 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
2804 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
2805 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
2806 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
2809 break;
2811 case D3DTSS_ALPHAOP :
2812 case D3DTSS_COLOROP :
2815 int Scale = 1;
2816 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
2818 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
2819 /* TODO: Disable by making this and all later levels disabled */
2820 glDisable(GL_TEXTURE_1D);
2821 checkGLcall("Disable GL_TEXTURE_1D");
2822 glDisable(GL_TEXTURE_2D);
2823 checkGLcall("Disable GL_TEXTURE_2D");
2824 glDisable(GL_TEXTURE_3D);
2825 checkGLcall("Disable GL_TEXTURE_3D");
2826 } else {
2828 /* Enable only the appropriate texture dimension */
2829 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
2830 glEnable(GL_TEXTURE_1D);
2831 checkGLcall("Enable GL_TEXTURE_1D");
2832 } else {
2833 glDisable(GL_TEXTURE_1D);
2834 checkGLcall("Disable GL_TEXTURE_1D");
2836 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
2837 glEnable(GL_TEXTURE_2D);
2838 checkGLcall("Enable GL_TEXTURE_2D");
2839 } else {
2840 glDisable(GL_TEXTURE_2D);
2841 checkGLcall("Disable GL_TEXTURE_2D");
2843 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
2844 glEnable(GL_TEXTURE_3D);
2845 checkGLcall("Enable GL_TEXTURE_3D");
2846 } else {
2847 glDisable(GL_TEXTURE_3D);
2848 checkGLcall("Disable GL_TEXTURE_3D");
2851 /* Now set up the operand correctly */
2852 switch (Value) {
2853 case D3DTOP_DISABLE :
2854 /* Contrary to the docs, alpha can be disabled when colorop is enabled
2855 and it works, so ignore this op */
2856 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
2857 break;
2859 case D3DTOP_SELECTARG1 :
2860 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
2861 break;
2863 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
2864 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
2865 case D3DTOP_MODULATE :
2867 /* Correct scale */
2868 if (Type == D3DTSS_ALPHAOP) glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
2869 else glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
2871 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
2872 break;
2874 case D3DTOP_ADD :
2875 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
2876 break;
2879 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
2880 case D3DTOP_ADDSIGNED :
2881 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
2882 break;
2885 case D3DTOP_SUBTRACT :
2886 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
2887 case D3DTOP_SELECTARG2 :
2888 /* GL_REPLACE, swap args 0 and 1? */
2889 case D3DTOP_ADDSMOOTH :
2890 case D3DTOP_BLENDDIFFUSEALPHA :
2891 case D3DTOP_BLENDTEXTUREALPHA :
2892 case D3DTOP_BLENDFACTORALPHA :
2893 case D3DTOP_BLENDTEXTUREALPHAPM :
2894 case D3DTOP_BLENDCURRENTALPHA :
2895 case D3DTOP_PREMODULATE :
2896 case D3DTOP_MODULATEALPHA_ADDCOLOR :
2897 case D3DTOP_MODULATECOLOR_ADDALPHA :
2898 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
2899 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
2900 case D3DTOP_BUMPENVMAP :
2901 case D3DTOP_BUMPENVMAPLUMINANCE :
2902 case D3DTOP_DOTPRODUCT3 :
2903 case D3DTOP_MULTIPLYADD :
2904 case D3DTOP_LERP :
2905 default:
2906 FIXME("Unhandled texture operation %ld\n", Value);
2909 break;
2912 /* Unhandled */
2913 case D3DTSS_BUMPENVMAT00 :
2914 case D3DTSS_BUMPENVMAT01 :
2915 case D3DTSS_BUMPENVMAT10 :
2916 case D3DTSS_BUMPENVMAT11 :
2917 case D3DTSS_TEXCOORDINDEX :
2918 case D3DTSS_ADDRESSU :
2919 case D3DTSS_ADDRESSV :
2920 case D3DTSS_BORDERCOLOR :
2921 case D3DTSS_MIPFILTER :
2922 case D3DTSS_MIPMAPLODBIAS :
2923 case D3DTSS_MAXMIPLEVEL :
2924 case D3DTSS_MAXANISOTROPY :
2925 case D3DTSS_BUMPENVLSCALE :
2926 case D3DTSS_BUMPENVLOFFSET :
2927 case D3DTSS_TEXTURETRANSFORMFLAGS :
2928 case D3DTSS_ADDRESSW :
2929 case D3DTSS_RESULTARG :
2930 default:
2931 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
2932 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
2934 return D3D_OK;
2936 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
2937 ICOM_THIS(IDirect3DDevice8Impl,iface);
2938 FIXME("(%p) : stub\n", This); return D3D_OK;
2940 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
2941 ICOM_THIS(IDirect3DDevice8Impl,iface);
2942 FIXME("(%p) : stub\n", This); return D3D_OK;
2944 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
2945 ICOM_THIS(IDirect3DDevice8Impl,iface);
2946 FIXME("(%p) : stub\n", This); return D3D_OK;
2948 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
2949 ICOM_THIS(IDirect3DDevice8Impl,iface);
2950 FIXME("(%p) : stub\n", This); return D3D_OK;
2952 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
2953 ICOM_THIS(IDirect3DDevice8Impl,iface);
2954 FIXME("(%p) : stub\n", This); return D3D_OK;
2956 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
2957 ICOM_THIS(IDirect3DDevice8Impl,iface);
2958 FIXME("(%p) : stub\n", This); return D3D_OK;
2960 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
2962 IDirect3DVertexBuffer8 *pVB;
2963 D3DVERTEXBUFFER_DESC VtxBufDsc;
2965 ICOM_THIS(IDirect3DDevice8Impl,iface);
2966 pVB = This->StateBlock.stream_source[0];
2968 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
2970 IDirect3DVertexBuffer8Impl_GetDesc(pVB, &VtxBufDsc);
2971 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
2972 VtxBufDsc.FVF, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL);
2974 return D3D_OK;
2976 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
2977 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
2978 UINT idxStride = 2;
2979 IDirect3DIndexBuffer8 *pIB;
2980 IDirect3DVertexBuffer8 *pVB;
2981 D3DINDEXBUFFER_DESC IdxBufDsc;
2982 D3DVERTEXBUFFER_DESC VtxBufDsc;
2984 ICOM_THIS(IDirect3DDevice8Impl,iface);
2985 pIB = This->StateBlock.pIndexData;
2986 pVB = This->StateBlock.stream_source[0];
2988 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
2989 minIndex, NumVertices, startIndex, primCount);
2991 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
2992 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
2993 idxStride = 2;
2994 } else {
2995 idxStride = 4;
2998 IDirect3DVertexBuffer8Impl_GetDesc(pVB, &VtxBufDsc);
2999 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, VtxBufDsc.FVF, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3000 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory);
3002 return D3D_OK;
3004 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3005 ICOM_THIS(IDirect3DDevice8Impl,iface);
3007 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3009 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3011 This->StateBlock.stream_source[0] = NULL;
3012 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3013 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3014 0, 0, 0, NULL);
3015 This->StateBlock.stream_stride[0] = 0;
3017 /*stream zero settings set to null at end */
3018 return D3D_OK;
3020 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3021 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3022 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3023 UINT VertexStreamZeroStride) {
3024 int idxStride;
3025 ICOM_THIS(IDirect3DDevice8Impl,iface);
3026 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3027 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3029 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3030 if (IndexDataFormat == D3DFMT_INDEX16) {
3031 idxStride = 2;
3032 } else {
3033 idxStride = 4;
3036 This->StateBlock.stream_source[0] = NULL;
3037 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3038 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3039 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData);
3041 /*stream zero settings set to null at end */
3042 This->StateBlock.stream_stride[0] = 0;
3043 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3045 return D3D_OK;
3047 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3048 ICOM_THIS(IDirect3DDevice8Impl,iface);
3049 FIXME("(%p) : stub\n", This); return D3D_OK;
3051 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) {
3052 ICOM_THIS(IDirect3DDevice8Impl,iface);
3053 FIXME("(%p) : stub\n", This); return D3D_OK;
3055 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3056 ICOM_THIS(IDirect3DDevice8Impl,iface);
3058 This->UpdateStateBlock->VertexShader = Handle;
3059 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3060 This->UpdateStateBlock->Set.vertexShader = TRUE;
3062 /* Handle recording of state blocks */
3063 if (This->isRecordingState) {
3064 TRACE("Recording... not performing anything\n");
3065 return D3D_OK;
3068 if (Handle <= VS_HIGHESTFIXEDFXF) {
3069 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3070 return D3D_OK;
3071 } else {
3072 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3073 return D3D_OK;
3076 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3077 ICOM_THIS(IDirect3DDevice8Impl,iface);
3078 TRACE("(%p) = %ld\n", This, This->StateBlock.VertexShader);
3079 *pHandle = This->StateBlock.VertexShader;
3080 return D3D_OK;
3083 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3084 ICOM_THIS(IDirect3DDevice8Impl,iface);
3085 FIXME("(%p) : stub\n", This); return D3D_OK;
3087 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3088 ICOM_THIS(IDirect3DDevice8Impl,iface);
3089 FIXME("(%p) : stub\n", This); return D3D_OK;
3091 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3092 ICOM_THIS(IDirect3DDevice8Impl,iface);
3093 FIXME("(%p) : stub\n", This); return D3D_OK;
3095 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3096 ICOM_THIS(IDirect3DDevice8Impl,iface);
3097 FIXME("(%p) : stub\n", This); return D3D_OK;
3099 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3100 ICOM_THIS(IDirect3DDevice8Impl,iface);
3101 FIXME("(%p) : stub\n", This); return D3D_OK;
3104 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3106 IDirect3DIndexBuffer8 *oldIdxs;
3108 ICOM_THIS(IDirect3DDevice8Impl,iface);
3109 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3110 oldIdxs = This->StateBlock.pIndexData;
3112 This->UpdateStateBlock->Changed.Indices = TRUE;
3113 This->UpdateStateBlock->Set.Indices = TRUE;
3114 This->UpdateStateBlock->pIndexData = pIndexData;
3115 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3117 /* Handle recording of state blocks */
3118 if (This->isRecordingState) {
3119 TRACE("Recording... not performing anything\n");
3120 return D3D_OK;
3123 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3124 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3125 return D3D_OK;
3127 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3128 ICOM_THIS(IDirect3DDevice8Impl,iface);
3129 FIXME("(%p) : stub\n", This);
3131 *ppIndexData = This->StateBlock.pIndexData;
3132 /* up ref count on ppindexdata */
3133 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3134 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3136 return D3D_OK;
3138 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction,DWORD* pHandle) {
3139 ICOM_THIS(IDirect3DDevice8Impl,iface);
3140 FIXME("(%p) : stub\n", This); return D3D_OK;
3142 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3143 ICOM_THIS(IDirect3DDevice8Impl,iface);
3145 This->UpdateStateBlock->PixelShader = Handle;
3146 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3147 This->UpdateStateBlock->Set.pixelShader = TRUE;
3149 /* Handle recording of state blocks */
3150 if (This->isRecordingState) {
3151 TRACE("Recording... not performing anything\n");
3152 return D3D_OK;
3155 /* FIXME: Quieten when not being used */
3156 if (Handle != 0) {
3157 FIXME("(%p) : stub %ld\n", This, Handle);
3158 } else {
3159 TRACE("(%p) : stub %ld\n", This, Handle);
3162 return D3D_OK;
3164 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3165 ICOM_THIS(IDirect3DDevice8Impl,iface);
3166 TRACE("(%p) : returning %ld\n", This, This->StateBlock.PixelShader);
3167 *pHandle = This->StateBlock.PixelShader;
3168 return D3D_OK;
3171 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3172 ICOM_THIS(IDirect3DDevice8Impl,iface);
3173 FIXME("(%p) : stub\n", This); return D3D_OK;
3175 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3176 ICOM_THIS(IDirect3DDevice8Impl,iface);
3177 FIXME("(%p) : stub\n", This); return D3D_OK;
3179 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3180 ICOM_THIS(IDirect3DDevice8Impl,iface);
3181 FIXME("(%p) : stub\n", This); return D3D_OK;
3183 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3184 ICOM_THIS(IDirect3DDevice8Impl,iface);
3185 FIXME("(%p) : stub\n", This); return D3D_OK;
3187 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3188 ICOM_THIS(IDirect3DDevice8Impl,iface);
3189 FIXME("(%p) : stub\n", This); return D3D_OK;
3191 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3192 ICOM_THIS(IDirect3DDevice8Impl,iface);
3193 FIXME("(%p) : stub\n", This); return D3D_OK;
3195 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3196 ICOM_THIS(IDirect3DDevice8Impl,iface);
3197 FIXME("(%p) : stub\n", This); return D3D_OK;
3200 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3201 IDirect3DVertexBuffer8 *oldSrc;
3202 ICOM_THIS(IDirect3DDevice8Impl,iface);
3204 oldSrc = This->StateBlock.stream_source[StreamNumber];
3205 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3207 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3208 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3209 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3210 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3212 /* Handle recording of state blocks */
3213 if (This->isRecordingState) {
3214 TRACE("Recording... not performing anything\n");
3215 return D3D_OK;
3218 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3219 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3220 return D3D_OK;
3222 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3223 ICOM_THIS(IDirect3DDevice8Impl,iface);
3224 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3225 *pStream = This->StateBlock.stream_source[StreamNumber];
3226 *pStride = This->StateBlock.stream_stride[StreamNumber];
3227 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3228 return D3D_OK;
3232 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3234 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3235 IDirect3DDevice8Impl_QueryInterface,
3236 IDirect3DDevice8Impl_AddRef,
3237 IDirect3DDevice8Impl_Release,
3238 IDirect3DDevice8Impl_TestCooperativeLevel,
3239 IDirect3DDevice8Impl_GetAvailableTextureMem,
3240 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3241 IDirect3DDevice8Impl_GetDirect3D,
3242 IDirect3DDevice8Impl_GetDeviceCaps,
3243 IDirect3DDevice8Impl_GetDisplayMode,
3244 IDirect3DDevice8Impl_GetCreationParameters,
3245 IDirect3DDevice8Impl_SetCursorProperties,
3246 IDirect3DDevice8Impl_SetCursorPosition,
3247 IDirect3DDevice8Impl_ShowCursor,
3248 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3249 IDirect3DDevice8Impl_Reset,
3250 IDirect3DDevice8Impl_Present,
3251 IDirect3DDevice8Impl_GetBackBuffer,
3252 IDirect3DDevice8Impl_GetRasterStatus,
3253 IDirect3DDevice8Impl_SetGammaRamp,
3254 IDirect3DDevice8Impl_GetGammaRamp,
3255 IDirect3DDevice8Impl_CreateTexture,
3256 IDirect3DDevice8Impl_CreateVolumeTexture,
3257 IDirect3DDevice8Impl_CreateCubeTexture,
3258 IDirect3DDevice8Impl_CreateVertexBuffer,
3259 IDirect3DDevice8Impl_CreateIndexBuffer,
3260 IDirect3DDevice8Impl_CreateRenderTarget,
3261 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3262 IDirect3DDevice8Impl_CreateImageSurface,
3263 IDirect3DDevice8Impl_CopyRects,
3264 IDirect3DDevice8Impl_UpdateTexture,
3265 IDirect3DDevice8Impl_GetFrontBuffer,
3266 IDirect3DDevice8Impl_SetRenderTarget,
3267 IDirect3DDevice8Impl_GetRenderTarget,
3268 IDirect3DDevice8Impl_GetDepthStencilSurface,
3269 IDirect3DDevice8Impl_BeginScene,
3270 IDirect3DDevice8Impl_EndScene,
3271 IDirect3DDevice8Impl_Clear,
3272 IDirect3DDevice8Impl_SetTransform,
3273 IDirect3DDevice8Impl_GetTransform,
3274 IDirect3DDevice8Impl_MultiplyTransform,
3275 IDirect3DDevice8Impl_SetViewport,
3276 IDirect3DDevice8Impl_GetViewport,
3277 IDirect3DDevice8Impl_SetMaterial,
3278 IDirect3DDevice8Impl_GetMaterial,
3279 IDirect3DDevice8Impl_SetLight,
3280 IDirect3DDevice8Impl_GetLight,
3281 IDirect3DDevice8Impl_LightEnable,
3282 IDirect3DDevice8Impl_GetLightEnable,
3283 IDirect3DDevice8Impl_SetClipPlane,
3284 IDirect3DDevice8Impl_GetClipPlane,
3285 IDirect3DDevice8Impl_SetRenderState,
3286 IDirect3DDevice8Impl_GetRenderState,
3287 IDirect3DDevice8Impl_BeginStateBlock,
3288 IDirect3DDevice8Impl_EndStateBlock,
3289 IDirect3DDevice8Impl_ApplyStateBlock,
3290 IDirect3DDevice8Impl_CaptureStateBlock,
3291 IDirect3DDevice8Impl_DeleteStateBlock,
3292 IDirect3DDevice8Impl_CreateStateBlock,
3293 IDirect3DDevice8Impl_SetClipStatus,
3294 IDirect3DDevice8Impl_GetClipStatus,
3295 IDirect3DDevice8Impl_GetTexture,
3296 IDirect3DDevice8Impl_SetTexture,
3297 IDirect3DDevice8Impl_GetTextureStageState,
3298 IDirect3DDevice8Impl_SetTextureStageState,
3299 IDirect3DDevice8Impl_ValidateDevice,
3300 IDirect3DDevice8Impl_GetInfo,
3301 IDirect3DDevice8Impl_SetPaletteEntries,
3302 IDirect3DDevice8Impl_GetPaletteEntries,
3303 IDirect3DDevice8Impl_SetCurrentTexturePalette,
3304 IDirect3DDevice8Impl_GetCurrentTexturePalette,
3305 IDirect3DDevice8Impl_DrawPrimitive,
3306 IDirect3DDevice8Impl_DrawIndexedPrimitive,
3307 IDirect3DDevice8Impl_DrawPrimitiveUP,
3308 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
3309 IDirect3DDevice8Impl_ProcessVertices,
3310 IDirect3DDevice8Impl_CreateVertexShader,
3311 IDirect3DDevice8Impl_SetVertexShader,
3312 IDirect3DDevice8Impl_GetVertexShader,
3313 IDirect3DDevice8Impl_DeleteVertexShader,
3314 IDirect3DDevice8Impl_SetVertexShaderConstant,
3315 IDirect3DDevice8Impl_GetVertexShaderConstant,
3316 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
3317 IDirect3DDevice8Impl_GetVertexShaderFunction,
3318 IDirect3DDevice8Impl_SetStreamSource,
3319 IDirect3DDevice8Impl_GetStreamSource,
3320 IDirect3DDevice8Impl_SetIndices,
3321 IDirect3DDevice8Impl_GetIndices,
3322 IDirect3DDevice8Impl_CreatePixelShader,
3323 IDirect3DDevice8Impl_SetPixelShader,
3324 IDirect3DDevice8Impl_GetPixelShader,
3325 IDirect3DDevice8Impl_DeletePixelShader,
3326 IDirect3DDevice8Impl_SetPixelShaderConstant,
3327 IDirect3DDevice8Impl_GetPixelShaderConstant,
3328 IDirect3DDevice8Impl_GetPixelShaderFunction,
3329 IDirect3DDevice8Impl_DrawRectPatch,
3330 IDirect3DDevice8Impl_DrawTriPatch,
3331 IDirect3DDevice8Impl_DeletePatch
3334 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
3335 D3DLINEPATTERN lp;
3336 int i;
3338 ICOM_THIS(IDirect3DDevice8Impl,iface);
3340 /* Note this may have a large overhead but it should only be executed
3341 once, in order to initialize the complete state of the device and
3342 all opengl equivalents */
3343 TRACE("-----------------------> Setting up device defaults...\n");
3344 This->StateBlock.blockType = D3DSBT_ALL;
3346 /* FIXME: Set some of the defaults for lights, transforms etc */
3347 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
3348 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
3349 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
3351 /* Render states: */
3352 if (This->PresentParms.EnableAutoDepthStencil) {
3353 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
3354 } else {
3355 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
3357 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
3358 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3359 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
3360 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
3361 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
3362 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
3363 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
3364 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
3365 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
3366 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3367 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
3368 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
3369 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
3370 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
3371 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
3372 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
3373 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
3374 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
3375 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3376 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
3377 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
3378 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
3379 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
3380 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
3381 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
3382 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
3383 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
3384 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
3385 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
3386 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
3387 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
3388 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
3389 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
3390 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
3391 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
3392 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
3393 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
3394 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
3395 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
3396 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
3397 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
3398 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
3399 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
3400 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
3401 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
3402 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3403 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
3404 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
3405 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
3406 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3407 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
3408 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
3409 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
3410 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
3411 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
3412 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
3413 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
3414 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
3415 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
3416 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
3417 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
3418 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
3419 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
3420 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
3421 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
3422 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
3423 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
3424 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
3425 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
3426 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
3427 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
3428 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
3429 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
3430 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
3431 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
3433 /* Texture Stage States - Put directly into state block, we will call function below */
3434 for (i=0; i<8;i++) {
3435 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
3436 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
3437 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
3438 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
3439 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
3440 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
3441 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
3442 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
3443 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
3444 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
3445 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
3446 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
3447 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
3448 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
3449 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
3450 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
3451 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
3452 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
3453 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
3454 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
3455 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
3456 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
3457 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
3458 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
3459 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
3460 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
3461 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
3464 /* Under DirectX you can have texture stage operations even if no texture is
3465 bound, whereas opengl will only do texture operations when a valid texture is
3466 bound. We emulate this by creating 8 dummy textures and binding them to each
3467 texture stage, but disable all stages by default. Hence if a stage is enabled
3468 then the default texture will kick in until replaced by a SetTexture call */
3469 for (i=0; i<8; i++) {
3471 /* Make appropriate texture active */
3472 glActiveTextureARB(GL_TEXTURE0_ARB + i);
3473 checkGLcall("glActiveTextureARB");
3475 /* Define 64 dummy bytes for the texture */
3476 This->dummyTexture[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 64);
3478 /* Generate an opengl texture name */
3479 glGenTextures(1, &This->dummyTextureName[i]);
3480 checkGLcall("glGenTextures");
3481 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
3483 /* Generate a dummy 1d texture */
3484 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
3485 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
3486 checkGLcall("glBindTexture");
3488 glTexImage1D(GL_TEXTURE_1D, 1, GL_ALPHA8, 1, 0, GL_ALPHA, GL_BYTE, &This->dummyTexture[i]);
3489 checkGLcall("glTexImage1D");
3491 /* Reapply all the texture state information to this texture */
3492 setupTextureStates(iface, i);
3495 TRACE("-----------------------> Device defaults now set up...\n");
3500 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
3501 D3DRS_ALPHABLENDENABLE ,
3502 D3DRS_ALPHAFUNC ,
3503 D3DRS_ALPHAREF ,
3504 D3DRS_ALPHATESTENABLE ,
3505 D3DRS_BLENDOP ,
3506 D3DRS_COLORWRITEENABLE ,
3507 D3DRS_DESTBLEND ,
3508 D3DRS_DITHERENABLE ,
3509 D3DRS_EDGEANTIALIAS ,
3510 D3DRS_FILLMODE ,
3511 D3DRS_FOGDENSITY ,
3512 D3DRS_FOGEND ,
3513 D3DRS_FOGSTART ,
3514 D3DRS_LASTPIXEL ,
3515 D3DRS_LINEPATTERN ,
3516 D3DRS_SHADEMODE ,
3517 D3DRS_SRCBLEND ,
3518 D3DRS_STENCILENABLE ,
3519 D3DRS_STENCILFAIL ,
3520 D3DRS_STENCILFUNC ,
3521 D3DRS_STENCILMASK ,
3522 D3DRS_STENCILPASS ,
3523 D3DRS_STENCILREF ,
3524 D3DRS_STENCILWRITEMASK ,
3525 D3DRS_STENCILZFAIL ,
3526 D3DRS_TEXTUREFACTOR ,
3527 D3DRS_WRAP0 ,
3528 D3DRS_WRAP1 ,
3529 D3DRS_WRAP2 ,
3530 D3DRS_WRAP3 ,
3531 D3DRS_WRAP4 ,
3532 D3DRS_WRAP5 ,
3533 D3DRS_WRAP6 ,
3534 D3DRS_WRAP7 ,
3535 D3DRS_ZBIAS ,
3536 D3DRS_ZENABLE ,
3537 D3DRS_ZFUNC ,
3538 D3DRS_ZWRITEENABLE
3541 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
3542 D3DTSS_ADDRESSU ,
3543 D3DTSS_ADDRESSV ,
3544 D3DTSS_ADDRESSW ,
3545 D3DTSS_ALPHAARG0 ,
3546 D3DTSS_ALPHAARG1 ,
3547 D3DTSS_ALPHAARG2 ,
3548 D3DTSS_ALPHAOP ,
3549 D3DTSS_BORDERCOLOR ,
3550 D3DTSS_BUMPENVLOFFSET ,
3551 D3DTSS_BUMPENVLSCALE ,
3552 D3DTSS_BUMPENVMAT00 ,
3553 D3DTSS_BUMPENVMAT01 ,
3554 D3DTSS_BUMPENVMAT10 ,
3555 D3DTSS_BUMPENVMAT11 ,
3556 D3DTSS_COLORARG0 ,
3557 D3DTSS_COLORARG1 ,
3558 D3DTSS_COLORARG2 ,
3559 D3DTSS_COLOROP ,
3560 D3DTSS_MAGFILTER ,
3561 D3DTSS_MAXANISOTROPY ,
3562 D3DTSS_MAXMIPLEVEL ,
3563 D3DTSS_MINFILTER ,
3564 D3DTSS_MIPFILTER ,
3565 D3DTSS_MIPMAPLODBIAS ,
3566 D3DTSS_RESULTARG ,
3567 D3DTSS_TEXCOORDINDEX ,
3568 D3DTSS_TEXTURETRANSFORMFLAGS
3571 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
3572 D3DRS_AMBIENT ,
3573 D3DRS_AMBIENTMATERIALSOURCE ,
3574 D3DRS_CLIPPING ,
3575 D3DRS_CLIPPLANEENABLE ,
3576 D3DRS_COLORVERTEX ,
3577 D3DRS_DIFFUSEMATERIALSOURCE ,
3578 D3DRS_EMISSIVEMATERIALSOURCE ,
3579 D3DRS_FOGDENSITY ,
3580 D3DRS_FOGEND ,
3581 D3DRS_FOGSTART ,
3582 D3DRS_FOGTABLEMODE ,
3583 D3DRS_FOGVERTEXMODE ,
3584 D3DRS_INDEXEDVERTEXBLENDENABLE ,
3585 D3DRS_LIGHTING ,
3586 D3DRS_LOCALVIEWER ,
3587 D3DRS_MULTISAMPLEANTIALIAS ,
3588 D3DRS_MULTISAMPLEMASK ,
3589 D3DRS_NORMALIZENORMALS ,
3590 D3DRS_PATCHEDGESTYLE ,
3591 D3DRS_PATCHSEGMENTS ,
3592 D3DRS_POINTSCALE_A ,
3593 D3DRS_POINTSCALE_B ,
3594 D3DRS_POINTSCALE_C ,
3595 D3DRS_POINTSCALEENABLE ,
3596 D3DRS_POINTSIZE ,
3597 D3DRS_POINTSIZE_MAX ,
3598 D3DRS_POINTSIZE_MIN ,
3599 D3DRS_POINTSPRITEENABLE ,
3600 D3DRS_RANGEFOGENABLE ,
3601 D3DRS_SOFTWAREVERTEXPROCESSING ,
3602 D3DRS_SPECULARMATERIALSOURCE ,
3603 D3DRS_TWEENFACTOR ,
3604 D3DRS_VERTEXBLEND
3607 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
3608 D3DTSS_TEXCOORDINDEX ,
3609 D3DTSS_TEXTURETRANSFORMFLAGS