Thanks to Lucho, text support in samples now starts to
[wine/wine64.git] / dlls / d3d8 / device.c
blobb945b233a4a70f280bbfb43a69854495bc6c3718
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 : FIXME("Unsupported stencil op %ld\n", op);
519 return GL_INCR; /* Fixme - needs to support wrap */
520 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op %ld\n", op);
521 return GL_DECR; /* Fixme - needs to support wrap */
522 default:
523 FIXME("Invalid stencil op %ld\n", op);
524 return GL_ALWAYS;
528 /* Apply the current values to the specified texture stage */
529 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
530 ICOM_THIS(IDirect3DDevice8Impl,iface);
531 int i=0;
532 float col[4];
534 /* Make appropriate texture active */
535 glActiveTextureARB(GL_TEXTURE0_ARB + i);
536 checkGLcall("glActiveTextureARB");
538 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
539 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
540 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock.texture_state[Stage][i]);
543 /* Note the D3DRS value applies to all textures, but GL has one
544 per texture, so apply it now ready to be used! */
545 col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
546 col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
547 col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
548 col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
549 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
550 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
552 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
555 /* IDirect3D IUnknown parts follow: */
556 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
558 ICOM_THIS(IDirect3DDevice8Impl,iface);
560 if (IsEqualGUID(riid, &IID_IUnknown)
561 || IsEqualGUID(riid, &IID_IClassFactory)) {
562 IDirect3DDevice8Impl_AddRef(iface);
563 *ppobj = This;
564 return D3D_OK;
567 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
568 return E_NOINTERFACE;
571 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
572 ICOM_THIS(IDirect3DDevice8Impl,iface);
573 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
574 return ++(This->ref);
577 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
578 ICOM_THIS(IDirect3DDevice8Impl,iface);
579 ULONG ref = --This->ref;
580 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
581 if (ref == 0) {
582 HeapFree(GetProcessHeap(), 0, This);
584 return ref;
587 /* IDirect3DDevice Interface follow: */
588 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
589 ICOM_THIS(IDirect3DDevice8Impl,iface);
590 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
591 return D3D_OK;
595 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
596 ICOM_THIS(IDirect3DDevice8Impl,iface);
597 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
599 * pretend we have 32MB of any type of memory queried.
601 return (1024*1024*32);
604 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
605 ICOM_THIS(IDirect3DDevice8Impl,iface);
606 FIXME("(%p) : stub\n", This); return D3D_OK;
608 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
609 ICOM_THIS(IDirect3DDevice8Impl,iface);
610 TRACE("(%p) : returning %p\n", This, This->direct3d8);
612 /* Inc ref count */
613 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
615 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
616 return D3D_OK;
618 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
619 ICOM_THIS(IDirect3DDevice8Impl,iface);
620 FIXME("(%p) : stub, calling idirect3d for now\n", This);
621 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
622 return D3D_OK;
624 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
626 HDC hdc;
627 int bpp = 0;
629 ICOM_THIS(IDirect3DDevice8Impl,iface);
630 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
631 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
632 pMode->RefreshRate = 85; /*FIXME: How to identify? */
634 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
635 bpp = GetDeviceCaps(hdc, BITSPIXEL);
636 DeleteDC(hdc);
638 switch (bpp) {
639 case 8: pMode->Format = D3DFMT_R8G8B8; break;
640 case 16: pMode->Format = D3DFMT_R5G6B5; break;
641 case 24: pMode->Format = D3DFMT_R8G8B8; break;
642 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
643 default: pMode->Format = D3DFMT_UNKNOWN;
646 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
647 return D3D_OK;
649 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
650 ICOM_THIS(IDirect3DDevice8Impl,iface);
651 TRACE("(%p) copying to %p\n", This, pParameters);
652 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
653 return D3D_OK;
655 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
656 ICOM_THIS(IDirect3DDevice8Impl,iface);
657 FIXME("(%p) : stub\n", This); return D3D_OK;
659 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
660 ICOM_THIS(IDirect3DDevice8Impl,iface);
661 FIXME("(%p) : stub\n", This); return;
663 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
664 ICOM_THIS(IDirect3DDevice8Impl,iface);
665 FIXME("(%p) : stub\n", This); return D3D_OK;
667 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
668 ICOM_THIS(IDirect3DDevice8Impl,iface);
669 FIXME("(%p) : stub\n", This); return D3D_OK;
671 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
672 ICOM_THIS(IDirect3DDevice8Impl,iface);
673 FIXME("(%p) : stub\n", This); return D3D_OK;
675 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
676 ICOM_THIS(IDirect3DDevice8Impl,iface);
677 TRACE("(%p) : complete stub!\n", This);
679 ENTER_GL();
681 glXSwapBuffers(This->display, This->win);
682 checkGLcall("glXSwapBuffers");
684 LEAVE_GL();
686 return D3D_OK;
688 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
689 ICOM_THIS(IDirect3DDevice8Impl,iface);
690 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
691 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
693 /* Note inc ref on returned surface */
694 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
696 return D3D_OK;
698 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
699 ICOM_THIS(IDirect3DDevice8Impl,iface);
700 FIXME("(%p) : stub\n", This); return D3D_OK;
702 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
703 ICOM_THIS(IDirect3DDevice8Impl,iface);
704 FIXME("(%p) : stub\n", This); return;
706 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
707 ICOM_THIS(IDirect3DDevice8Impl,iface);
708 FIXME("(%p) : stub\n", This); return;
710 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
711 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
712 IDirect3DTexture8Impl *object;
713 int i;
714 UINT tmpW;
715 UINT tmpH;
717 ICOM_THIS(IDirect3DDevice8Impl,iface);
719 /* Allocate the storage for the device */
720 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
721 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
722 object->lpVtbl = &Direct3DTexture8_Vtbl;
723 object->Device = This;
724 object->ResourceType = D3DRTYPE_TEXTURE;
725 object->ref = 1;
726 object->width = Width;
727 object->height = Height;
728 object->levels = Levels;
729 object->usage = Usage;
730 object->format = Format;
731 object->device = This;
733 /* Calculate levels for mip mapping */
734 if (Levels == 0) {
735 object->levels++;
736 tmpW = Width;
737 tmpH = Height;
738 while (tmpW > 1 && tmpH > 1) {
739 tmpW = max(1,tmpW / 2);
740 tmpH = max(1, tmpH / 2);
741 object->levels++;
743 TRACE("Calculated levels = %d\n", object->levels);
746 /* Generate all the surfaces */
747 tmpW = Width;
748 tmpH = Height;
749 /*for (i=0; i<object->levels; i++) { */
750 i=0;
752 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
753 object->surfaces[i]->Container = object;
754 object->surfaces[i]->myDesc.Usage = Usage;
755 object->surfaces[i]->myDesc.Pool = Pool ;
757 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
758 tmpW = max(1,tmpW / 2);
759 tmpH = max(1, tmpH / 2);
762 *ppTexture = (LPDIRECT3DTEXTURE8)object;
763 return D3D_OK;
765 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
767 IDirect3DVolumeTexture8Impl *object;
768 int i;
769 UINT tmpW;
770 UINT tmpH;
771 UINT tmpD;
773 ICOM_THIS(IDirect3DDevice8Impl,iface);
775 /* Allocate the storage for it */
776 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);
777 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
778 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
779 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
780 object->ref = 1;
783 object->width = Width;
784 object->height = Height;
785 object->depth = Depth;
786 object->levels = Levels;
787 object->usage = Usage;
788 object->format = Format;
789 object->device = This;
791 /* Calculate levels for mip mapping */
792 if (Levels == 0) {
793 object->levels++;
794 tmpW = Width;
795 tmpH = Height;
796 tmpD = Depth;
797 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
798 tmpW = max(1,tmpW / 2);
799 tmpH = max(1, tmpH / 2);
800 tmpD = max(1, tmpD / 2);
801 object->levels++;
803 TRACE("Calculated levels = %d\n", object->levels);
806 /* Generate all the surfaces */
807 tmpW = Width;
808 tmpH = Height;
809 tmpD = Depth;
811 /*for (i=0; i<object->levels; i++) { */
812 i=0;
814 IDirect3DVolume8Impl *volume;
816 /* Create the volume - No entry point for this seperately?? */
817 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
818 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
820 volume->lpVtbl = &Direct3DVolume8_Vtbl;
821 volume->Device = This;
822 volume->ResourceType = D3DRTYPE_VOLUME;
823 volume->Container = object;
824 volume->ref = 1;
826 volume->myDesc.Width = Width;
827 volume->myDesc.Height= Height;
828 volume->myDesc.Depth = Depth;
829 volume->myDesc.Format= Format;
830 volume->myDesc.Type = D3DRTYPE_VOLUME;
831 volume->myDesc.Pool = Pool;
832 volume->myDesc.Usage = Usage;
833 volume->bytesPerPixel = bytesPerPixel(Format);
834 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
835 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
837 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
838 volume, volume->allocatedMemory, volume->myDesc.Size);
840 tmpW = max(1,tmpW / 2);
841 tmpH = max(1, tmpH / 2);
842 tmpD = max(1, tmpD / 2);
845 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
846 return D3D_OK;
848 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
850 IDirect3DCubeTexture8Impl *object;
851 ICOM_THIS(IDirect3DDevice8Impl,iface);
852 int i,j;
853 UINT tmpW;
855 /* Allocate the storage for it */
856 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
857 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
858 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
859 object->ref = 1;
860 object->Device = This;
861 object->ResourceType = D3DRTYPE_CUBETEXTURE;
863 object->edgeLength = EdgeLength;
864 object->levels = Levels;
865 object->usage = Usage;
866 object->format = Format;
867 object->device = This;
869 /* Calculate levels for mip mapping */
870 if (Levels == 0) {
871 object->levels++;
872 tmpW = EdgeLength;
873 while (tmpW > 1) {
874 tmpW = max(1,tmpW / 2);
875 object->levels++;
877 TRACE("Calculated levels = %d\n", object->levels);
880 /* Generate all the surfaces */
881 tmpW = EdgeLength;
882 /*for (i=0; i<object->levels; i++) { */
883 i=0;
885 /* Create the 6 faces */
886 for (j=0;j<6;j++) {
887 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
888 object->surfaces[j][i]->Container = object;
889 object->surfaces[j][i]->myDesc.Usage = Usage;
890 object->surfaces[j][i]->myDesc.Pool = Pool ;
892 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
893 tmpW = max(1,tmpW / 2);
897 TRACE("(%p) : Iface@%p\n", This, object);
898 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
899 return D3D_OK;
901 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size,DWORD Usage,
902 DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8** ppVertexBuffer) {
903 IDirect3DVertexBuffer8Impl *object;
905 ICOM_THIS(IDirect3DDevice8Impl,iface);
907 /* Allocate the storage for the device */
908 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
909 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
910 object->Device = This;
911 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
912 object->ref = 1;
913 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
914 object->currentDesc.Usage = Usage;
915 object->currentDesc.Pool = Pool;
916 object->currentDesc.FVF = FVF;
917 object->currentDesc.Size = Size;
919 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
921 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
923 return D3D_OK;
925 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
927 IDirect3DIndexBuffer8Impl *object;
929 ICOM_THIS(IDirect3DDevice8Impl,iface);
930 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
932 /* Allocate the storage for the device */
933 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
934 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
935 object->ref = 1;
936 object->Device = This;
937 object->ResourceType = D3DRTYPE_INDEXBUFFER;
939 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
940 object->currentDesc.Usage = Usage;
941 object->currentDesc.Pool = Pool;
942 object->currentDesc.Format = Format;
943 object->currentDesc.Size = Length;
945 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
947 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
949 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
951 return D3D_OK;
953 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
954 ICOM_THIS(IDirect3DDevice8Impl,iface);
955 /* up ref count on surface, surface->container = This */
956 FIXME("(%p) : stub\n", This); return D3D_OK;
958 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
959 ICOM_THIS(IDirect3DDevice8Impl,iface);
960 /* surface->container = This */
961 FIXME("(%p) : stub\n", This); return D3D_OK;
963 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
964 IDirect3DSurface8Impl *object;
966 ICOM_THIS(IDirect3DDevice8Impl,iface);
968 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
969 *ppSurface = (LPDIRECT3DSURFACE8) object;
970 object->lpVtbl = &Direct3DSurface8_Vtbl;
971 object->Device = This;
972 object->ResourceType = D3DRTYPE_SURFACE;
973 object->Container = This;
975 object->ref = 1;
976 object->myDesc.Width = Width;
977 object->myDesc.Height= Height;
978 object->myDesc.Format= Format;
979 object->myDesc.Type = D3DRTYPE_SURFACE;
980 /*object->myDesc.Usage */
981 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
982 object->bytesPerPixel = bytesPerPixel(Format);
983 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
984 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
986 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);
987 return D3D_OK;
989 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
990 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
992 HRESULT rc = D3D_OK;
994 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
995 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
997 ICOM_THIS(IDirect3DDevice8Impl,iface);
998 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
999 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1001 if (src->myDesc.Format != dst->myDesc.Format) {
1002 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1003 rc = D3DERR_INVALIDCALL;
1006 /* Quick if complete copy ... */
1007 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1008 src->myDesc.Width == dst->myDesc.Width &&
1009 src->myDesc.Height == dst->myDesc.Height)) {
1010 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1011 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1013 } else {
1014 int i;
1015 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1016 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1017 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1019 void *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1020 void *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1022 /* Copy rect by rect */
1023 for (i=0; i<cRects; i++) {
1024 CONST RECT *r = &pSourceRectsArray[i];
1025 CONST POINT *p = &pDestPointsArray[i];
1026 void *from;
1027 void *to;
1028 int copyperline = (r->right - r->left) * bytesPerPixel;
1029 int j;
1031 TRACE("Copying rect %d (%d,%d),(%d,%d) -> (%ld,%ld)\n", i, r->left, r->top,
1032 r->right, r->bottom, p->x, p->y);
1034 /* Find where to start */
1035 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1036 to = copyto + (p->y * pitchFrom) + (p->x * bytesPerPixel);
1038 /* Copy line by line */
1039 for (j=0; j<(r->bottom - r->top); j++) {
1040 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1044 return D3D_OK;
1046 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1047 ICOM_THIS(IDirect3DDevice8Impl,iface);
1048 FIXME("(%p) : stub\n", This); return D3D_OK;
1050 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1051 ICOM_THIS(IDirect3DDevice8Impl,iface);
1052 FIXME("(%p) : stub\n", This); return D3D_OK;
1054 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1055 ICOM_THIS(IDirect3DDevice8Impl,iface);
1056 FIXME("(%p) : stub\n", This);
1058 return D3D_OK;
1060 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1061 ICOM_THIS(IDirect3DDevice8Impl,iface);
1062 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1063 FIXME("(%p) : stub\n", This);
1066 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1067 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1070 return D3D_OK;
1072 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1074 ICOM_THIS(IDirect3DDevice8Impl,iface);
1076 /* Note inc ref on returned surface *
1077 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1079 FIXME("(%p) : stub\n", This);
1080 return D3D_OK;
1083 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1084 ICOM_THIS(IDirect3DDevice8Impl,iface);
1085 TRACE("(%p) : stub\n", This);
1086 return D3D_OK;
1088 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1089 ICOM_THIS(IDirect3DDevice8Impl,iface);
1090 TRACE("(%p)\n", This);
1092 ENTER_GL();
1094 glFlush();
1095 checkGLcall("glFlush");
1097 /* Useful for debugging sometimes!
1098 printf("Hit Enter ...\n");
1099 getchar(); */
1101 LEAVE_GL();
1102 return D3D_OK;
1104 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1105 ICOM_THIS(IDirect3DDevice8Impl,iface);
1107 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1108 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1109 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1110 GLbitfield glMask = 0;
1111 int i;
1112 CONST D3DRECT *curRect;
1114 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1115 Count, pRects, Flags, Z, Stencil);
1117 ENTER_GL();
1118 if (Count > 0 && pRects) {
1119 glEnable(GL_SCISSOR_TEST);
1120 checkGLcall("glEnable GL_SCISSOR_TEST");
1121 curRect = pRects;
1122 } else {
1123 curRect = NULL;
1126 for (i=0;i<Count || i==0; i++) {
1128 if (curRect) {
1129 /* Note gl uses lower left, width/height */
1130 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1131 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1132 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1133 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1134 checkGLcall("glScissor");
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 TRACE("Clearing screen with glClear to color %lx\n", Color);
1152 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1153 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1154 checkGLcall("glClearColor");
1155 glMask = glMask | GL_COLOR_BUFFER_BIT;
1158 glClear(glMask);
1159 checkGLcall("glClear");
1161 if (curRect) curRect = curRect + sizeof(D3DRECT);
1164 if (Count > 0 && pRects) {
1165 glDisable(GL_SCISSOR_TEST);
1166 checkGLcall("glDisable");
1168 LEAVE_GL();
1170 return D3D_OK;
1172 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1173 ICOM_THIS(IDirect3DDevice8Impl,iface);
1174 int k;
1176 /* Most of this routine, comments included copied from ddraw tree initially: */
1177 TRACE("(%p) : State=%d\n", This, d3dts);
1179 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1180 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1181 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1183 /* Handle recording of state blocks */
1184 if (This->isRecordingState) {
1185 TRACE("Recording... not performing anything\n");
1186 return D3D_OK;
1190 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1192 where ViewMat = Camera space, WorldMat = world space.
1194 In OpenGL, camera and world space is combined into GL_MODELVIEW
1195 matrix. The Projection matrix stay projection matrix. */
1197 /* After reading through both OpenGL and Direct3D documentations, I
1198 thought that D3D matrices were written in 'line major mode' transposed
1199 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1200 works fine to transfer one matrix format to the other (it did not work
1201 when transposing)....
1203 So :
1204 1) are the documentations wrong
1205 2) does the matrix work even if they are not read correctly
1206 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1207 loading using glLoadMatrix ?
1209 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1210 to the other so that if I ever find out that I need to transpose them, I
1211 will able to do it quickly, only by changing the macro conv_mat. */
1213 switch (d3dts) {
1214 case D3DTS_WORLDMATRIX(0): {
1215 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)]);
1216 } break;
1218 case D3DTS_VIEW: {
1219 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_VIEW]);
1220 } break;
1222 case D3DTS_PROJECTION: {
1223 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_PROJECTION]);
1224 } break;
1226 default:
1227 break;
1231 * Move the GL operation to outside of switch to make it work
1232 * regardless of transform set order. Optimize later.
1234 ENTER_GL();
1235 glMatrixMode(GL_PROJECTION);
1236 checkGLcall("glMatrixMode");
1237 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
1238 checkGLcall("glLoadMatrixf");
1240 glMatrixMode(GL_MODELVIEW);
1241 checkGLcall("glMatrixMode");
1242 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1243 checkGLcall("glLoadMatrixf");
1245 /* If we are changing the View matrix, reset the light information to the new view */
1246 if (d3dts == D3DTS_VIEW) {
1247 for (k = 0; k < MAX_ACTIVE_LIGHTS; k++) {
1248 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1249 checkGLcall("glLightfv posn");
1250 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1251 checkGLcall("glLightfv dirn");
1255 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1256 checkGLcall("glMultMatrixf");
1258 LEAVE_GL();
1260 return D3D_OK;
1263 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1264 ICOM_THIS(IDirect3DDevice8Impl,iface);
1265 TRACE("(%p) : for State %d\n", This, State);
1266 memcpy(pMatrix, &This->StateBlock.transforms[State], sizeof(D3DMATRIX));
1267 return D3D_OK;
1270 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1271 ICOM_THIS(IDirect3DDevice8Impl,iface);
1272 FIXME("(%p) : stub\n", This); return D3D_OK;
1274 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1275 ICOM_THIS(IDirect3DDevice8Impl,iface);
1277 TRACE("(%p)\n", This);
1278 This->UpdateStateBlock->Changed.viewport = TRUE;
1279 This->UpdateStateBlock->Set.viewport = TRUE;
1280 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1282 /* Handle recording of state blocks */
1283 if (This->isRecordingState) {
1284 TRACE("Recording... not performing anything\n");
1285 return D3D_OK;
1288 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1289 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1291 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1292 checkGLcall("glDepthRange");
1293 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1294 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1295 checkGLcall("glViewport");
1298 return D3D_OK;
1301 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1302 ICOM_THIS(IDirect3DDevice8Impl,iface);
1303 TRACE("(%p)\n", This);
1304 memcpy(pViewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
1305 return D3D_OK;
1308 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1309 ICOM_THIS(IDirect3DDevice8Impl,iface);
1311 This->UpdateStateBlock->Changed.material = TRUE;
1312 This->UpdateStateBlock->Set.material = TRUE;
1313 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1315 /* Handle recording of state blocks */
1316 if (This->isRecordingState) {
1317 TRACE("Recording... not performing anything\n");
1318 return D3D_OK;
1321 ENTER_GL();
1322 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1323 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1324 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1325 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1326 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1328 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1329 checkGLcall("glMaterialfv");
1330 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1331 checkGLcall("glMaterialfv");
1333 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1334 checkGLcall("glMaterialfv");
1335 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1336 checkGLcall("glMaterialfv");
1337 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1338 checkGLcall("glMaterialf");
1340 LEAVE_GL();
1341 return D3D_OK;
1343 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1344 ICOM_THIS(IDirect3DDevice8Impl,iface);
1345 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1346 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1347 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1348 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1349 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1350 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1351 return D3D_OK;
1354 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1355 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1356 float rho;
1357 float quad_att;
1359 ICOM_THIS(IDirect3DDevice8Impl,iface);
1360 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1362 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,
1363 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1364 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1365 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1366 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1367 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1368 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1370 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1371 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1372 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1374 /* Handle recording of state blocks */
1375 if (This->isRecordingState) {
1376 TRACE("Recording... not performing anything\n");
1377 return D3D_OK;
1380 /* Diffuse: */
1381 colRGBA[0] = pLight->Diffuse.r;
1382 colRGBA[1] = pLight->Diffuse.g;
1383 colRGBA[2] = pLight->Diffuse.b;
1384 colRGBA[3] = pLight->Diffuse.a;
1385 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1386 checkGLcall("glLightfv");
1388 /* Specular */
1389 colRGBA[0] = pLight->Specular.r;
1390 colRGBA[1] = pLight->Specular.g;
1391 colRGBA[2] = pLight->Specular.b;
1392 colRGBA[3] = pLight->Specular.a;
1393 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1394 checkGLcall("glLightfv");
1396 /* Ambient */
1397 colRGBA[0] = pLight->Ambient.r;
1398 colRGBA[1] = pLight->Ambient.g;
1399 colRGBA[2] = pLight->Ambient.b;
1400 colRGBA[3] = pLight->Ambient.a;
1401 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1402 checkGLcall("glLightfv");
1404 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1405 glMatrixMode(GL_MODELVIEW);
1406 glPushMatrix();
1407 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1409 /* Attenuation - Are these right? guessing... */
1410 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
1411 checkGLcall("glLightf");
1412 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
1413 checkGLcall("glLightf");
1415 quad_att = 1.4/(pLight->Range*pLight->Range);
1416 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1417 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1418 checkGLcall("glLightf");
1420 switch (pLight->Type) {
1421 case D3DLIGHT_POINT:
1422 /* Position */
1423 This->lightPosn[Index][0] = pLight->Position.x;
1424 This->lightPosn[Index][1] = pLight->Position.y;
1425 This->lightPosn[Index][2] = pLight->Position.z;
1426 This->lightPosn[Index][3] = 1.0;
1427 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1428 checkGLcall("glLightfv");
1430 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1431 checkGLcall("glLightf");
1433 /* FIXME: Range */
1434 break;
1436 case D3DLIGHT_SPOT:
1437 /* Position */
1438 This->lightPosn[Index][0] = pLight->Position.x;
1439 This->lightPosn[Index][1] = pLight->Position.y;
1440 This->lightPosn[Index][2] = pLight->Position.z;
1441 This->lightPosn[Index][3] = 1.0;
1442 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1443 checkGLcall("glLightfv");
1445 /* Direction */
1446 This->lightDirn[Index][0] = pLight->Direction.x;
1447 This->lightDirn[Index][1] = pLight->Direction.y;
1448 This->lightDirn[Index][2] = pLight->Direction.z;
1449 This->lightDirn[Index][3] = 1.0;
1450 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1451 checkGLcall("glLightfv");
1454 * opengl-ish and d3d-ish spot lights use too different models for the
1455 * light "intensity" as a function of the angle towards the main light direction,
1456 * so we only can approximate very roughly.
1457 * however spot lights are rather rarely used in games (if ever used at all).
1458 * furthermore if still used, probably nobody pays attention to such details.
1460 if (pLight->Falloff == 0) {
1461 rho = 6.28f;
1462 } else {
1463 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1465 if (rho < 0.0001) rho = 0.0001f;
1466 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
1467 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
1469 /* FIXME: Range */
1470 break;
1471 case D3DLIGHT_DIRECTIONAL:
1472 /* Direction */
1473 This->lightPosn[Index][0] = -pLight->Direction.x;
1474 This->lightPosn[Index][1] = -pLight->Direction.y;
1475 This->lightPosn[Index][2] = -pLight->Direction.z;
1476 This->lightPosn[Index][3] = 0.0;
1477 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
1478 checkGLcall("glLightfv");
1480 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
1481 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
1484 break;
1485 default:
1486 FIXME("Unrecognized light type %d\n", pLight->Type);
1489 /* Restore the modelview matrix */
1490 glPopMatrix();
1492 return D3D_OK;
1494 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1495 ICOM_THIS(IDirect3DDevice8Impl,iface);
1496 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1497 memcpy(pLight, &This->StateBlock.lights[Index], sizeof(D3DLIGHT8));
1498 return D3D_OK;
1500 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1501 ICOM_THIS(IDirect3DDevice8Impl,iface);
1502 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
1504 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
1505 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
1506 This->UpdateStateBlock->lightEnable[Index] = Enable;
1508 /* Handle recording of state blocks */
1509 if (This->isRecordingState) {
1510 TRACE("Recording... not performing anything\n");
1511 return D3D_OK;
1514 if (Enable) {
1515 glEnable(GL_LIGHT0+Index);
1516 checkGLcall("glEnable GL_LIGHT0+Index");
1517 } else {
1518 glDisable(GL_LIGHT0+Index);
1519 checkGLcall("glDisable GL_LIGHT0+Index");
1521 return D3D_OK;
1523 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1524 ICOM_THIS(IDirect3DDevice8Impl,iface);
1525 TRACE("(%p) : for idx(%ld)\n", This, Index);
1526 *pEnable = This->StateBlock.lightEnable[Index];
1527 return D3D_OK;
1529 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1530 ICOM_THIS(IDirect3DDevice8Impl,iface);
1531 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
1533 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
1534 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
1535 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
1536 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
1537 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
1538 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
1540 /* Handle recording of state blocks */
1541 if (This->isRecordingState) {
1542 TRACE("Recording... not performing anything\n");
1543 return D3D_OK;
1546 /* Apply it */
1548 /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
1549 glMatrixMode(GL_MODELVIEW);
1550 glPushMatrix();
1551 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLD].u.m[0][0]);
1553 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
1554 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
1555 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
1557 glPopMatrix();
1558 checkGLcall("glClipPlane");
1560 return D3D_OK;
1562 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1563 ICOM_THIS(IDirect3DDevice8Impl,iface);
1564 TRACE("(%p) : for idx %ld\n", This, Index);
1565 pPlane[0] = This->StateBlock.clipplane[Index][0];
1566 pPlane[1] = This->StateBlock.clipplane[Index][0];
1567 pPlane[2] = This->StateBlock.clipplane[Index][0];
1568 pPlane[3] = This->StateBlock.clipplane[Index][0];
1569 return D3D_OK;
1571 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
1572 ICOM_THIS(IDirect3DDevice8Impl,iface);
1573 DWORD OldValue = This->StateBlock.renderstate[State];
1575 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
1576 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
1577 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
1578 This->UpdateStateBlock->renderstate[State] = Value;
1580 /* Handle recording of state blocks */
1581 if (This->isRecordingState) {
1582 TRACE("Recording... not performing anything\n");
1583 return D3D_OK;
1586 switch (State) {
1587 case D3DRS_FILLMODE :
1588 switch ((D3DFILLMODE) Value) {
1589 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
1590 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
1591 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
1592 default:
1593 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
1595 checkGLcall("glPolygonMode (fillmode)");
1596 break;
1598 case D3DRS_LIGHTING :
1599 if (Value) {
1600 glEnable(GL_LIGHTING);
1601 checkGLcall("glEnable GL_LIGHTING");
1602 } else {
1603 glDisable(GL_LIGHTING);
1604 checkGLcall("glDisable GL_LIGHTING");
1606 break;
1608 case D3DRS_ZENABLE :
1609 switch ((D3DZBUFFERTYPE) Value) {
1610 case D3DZB_FALSE:
1611 glDisable(GL_DEPTH_TEST);
1612 checkGLcall("glDisable GL_DEPTH_TEST");
1613 break;
1614 case D3DZB_TRUE:
1615 glEnable(GL_DEPTH_TEST);
1616 checkGLcall("glEnable GL_DEPTH_TEST");
1617 break;
1619 case D3DZB_USEW:
1620 default:
1621 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
1623 break;
1625 case D3DRS_CULLMODE :
1627 /* If we are culling "back faces with clockwise vertices" then
1628 set front faces to be counter clockwise and enable culling
1629 of back faces */
1630 switch ((D3DCULL) Value) {
1631 case D3DCULL_NONE:
1632 glDisable(GL_CULL_FACE);
1633 checkGLcall("glDisable GL_CULL_FACE");
1634 break;
1635 case D3DCULL_CW:
1636 glEnable(GL_CULL_FACE);
1637 checkGLcall("glEnable GL_CULL_FACE");
1638 glFrontFace(GL_CCW);
1639 checkGLcall("glFrontFace GL_CCW");
1640 glCullFace(GL_BACK);
1641 break;
1642 case D3DCULL_CCW:
1643 glEnable(GL_CULL_FACE);
1644 checkGLcall("glEnable GL_CULL_FACE");
1645 glFrontFace(GL_CW);
1646 checkGLcall("glFrontFace GL_CW");
1647 glCullFace(GL_BACK);
1648 break;
1649 default:
1650 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
1652 break;
1654 case D3DRS_SHADEMODE :
1655 switch ((D3DSHADEMODE) Value) {
1656 case D3DSHADE_FLAT:
1657 glShadeModel(GL_FLAT);
1658 checkGLcall("glShadeModel");
1659 break;
1660 case D3DSHADE_GOURAUD:
1661 glShadeModel(GL_SMOOTH);
1662 checkGLcall("glShadeModel");
1663 break;
1664 case D3DSHADE_PHONG:
1665 FIXME("D3DSHADE_PHONG isnt supported?\n");
1666 return D3DERR_INVALIDCALL;
1667 default:
1668 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
1670 break;
1672 case D3DRS_DITHERENABLE :
1673 if (Value) {
1674 glEnable(GL_DITHER);
1675 checkGLcall("glEnable GL_DITHER");
1676 } else {
1677 glDisable(GL_DITHER);
1678 checkGLcall("glDisable GL_DITHER");
1680 break;
1682 case D3DRS_ZWRITEENABLE :
1683 if (Value) {
1684 glDepthMask(1);
1685 checkGLcall("glDepthMask");
1686 } else {
1687 glDepthMask(0);
1688 checkGLcall("glDepthMask");
1690 break;
1692 case D3DRS_ZFUNC :
1694 int glParm = GL_LESS;
1696 switch ((D3DCMPFUNC) Value) {
1697 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1698 case D3DCMP_LESS: glParm=GL_LESS; break;
1699 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1700 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1701 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1702 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1703 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1704 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1705 default:
1706 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1708 glDepthFunc(glParm);
1709 checkGLcall("glDepthFunc");
1711 break;
1713 case D3DRS_AMBIENT :
1716 float col[4];
1717 col[0] = ((Value >> 16) & 0xFF) / 255.0;
1718 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1719 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1720 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1721 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
1722 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
1723 checkGLcall("glLightModel for MODEL_AMBIENT");
1726 break;
1728 case D3DRS_ALPHABLENDENABLE :
1729 if (Value) {
1730 glEnable(GL_BLEND);
1731 checkGLcall("glEnable GL_BLEND");
1732 } else {
1733 glDisable(GL_BLEND);
1734 checkGLcall("glDisable GL_BLEND");
1736 break;
1738 case D3DRS_SRCBLEND :
1739 case D3DRS_DESTBLEND :
1741 int newVal = GL_ZERO;
1742 switch (Value) {
1743 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
1744 case D3DBLEND_ONE : newVal = GL_ONE; break;
1745 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
1746 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
1747 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
1748 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
1749 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
1750 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
1751 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
1752 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
1753 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
1755 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
1756 This->srcBlend = newVal;
1757 This->dstBlend = newVal;
1758 break;
1760 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
1761 This->srcBlend = newVal;
1762 This->dstBlend = newVal;
1763 break;
1764 default:
1765 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
1768 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
1769 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
1770 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
1771 glBlendFunc(This->srcBlend, This->dstBlend);
1773 checkGLcall("glBlendFunc");
1775 break;
1777 case D3DRS_ALPHATESTENABLE :
1778 if (Value) {
1779 glEnable(GL_ALPHA_TEST);
1780 checkGLcall("glEnable GL_ALPHA_TEST");
1781 } else {
1782 glDisable(GL_ALPHA_TEST);
1783 checkGLcall("glDisable GL_ALPHA_TEST");
1785 break;
1787 case D3DRS_ALPHAFUNC :
1789 int glParm = GL_LESS;
1790 float ref = 1.0;
1792 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
1793 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
1795 switch ((D3DCMPFUNC) Value) {
1796 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1797 case D3DCMP_LESS: glParm=GL_LESS; break;
1798 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1799 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1800 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1801 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1802 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1803 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1804 default:
1805 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1807 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1808 glAlphaFunc(glParm, ref);
1809 checkGLcall("glAlphaFunc");
1811 break;
1813 case D3DRS_ALPHAREF :
1815 int glParm = GL_LESS;
1816 float ref = 1.0;
1818 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
1819 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
1821 ref = ((float) Value) / 255.0;
1822 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
1823 glAlphaFunc(glParm, ref);
1824 checkGLcall("glAlphaFunc");
1826 break;
1828 case D3DRS_CLIPPLANEENABLE :
1829 case D3DRS_CLIPPING :
1831 /* Ensure we only do the changed clip planes */
1832 DWORD enable = 0xFFFFFFFF;
1833 DWORD disable = 0x00000000;
1835 /* If enabling / disabling all */
1836 if (State == D3DRS_CLIPPING) {
1837 if (Value) {
1838 enable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1839 disable = 0x00;
1840 } else {
1841 disable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
1842 enable = 0x00;
1844 } else {
1845 enable = Value & ~OldValue;
1846 disable = ~Value & OldValue;
1849 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
1850 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
1851 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
1852 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
1853 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
1854 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
1856 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
1857 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
1858 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
1859 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
1860 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
1861 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
1863 break;
1865 case D3DRS_BLENDOP :
1867 int glParm = GL_FUNC_ADD;
1869 switch ((D3DBLENDOP) Value) {
1870 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
1871 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
1872 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
1873 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
1874 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
1875 default:
1876 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
1878 TRACE("glBlendEquation(%x)\n", glParm);
1879 glBlendEquation(glParm);
1880 checkGLcall("glBlendEquation");
1882 break;
1884 case D3DRS_TEXTUREFACTOR :
1886 int i;
1888 /* Note the texture color applies to all textures whereas
1889 GL_TEXTURE_ENV_COLOR applies to active only */
1890 float col[4];
1891 col[0] = ((Value >> 16) & 0xFF) / 255.0;
1892 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1893 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1894 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1896 /* Set the default alpha blend color */
1897 glBlendColor(col[0], col[1], col[2], col[3]);
1898 checkGLcall("glBlendColor");
1900 /* And now the default texture color as well */
1901 for (i=0; i<8; i++) {
1903 /* Note the D3DRS value applies to all textures, but GL has one
1904 per texture, so apply it now ready to be used! */
1905 checkGLcall("Activate texture.. to update const color");
1906 glActiveTextureARB(GL_TEXTURE0_ARB + i);
1908 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1909 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1912 break;
1914 case D3DRS_SPECULARENABLE :
1916 if (Value) {
1917 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
1918 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
1919 } else {
1920 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
1921 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
1924 break;
1926 case D3DRS_STENCILENABLE :
1927 if (Value) {
1928 glEnable(GL_STENCIL_TEST);
1929 checkGLcall("glEnable GL_STENCIL_TEST");
1930 } else {
1931 glDisable(GL_STENCIL_TEST);
1932 checkGLcall("glDisable GL_STENCIL_TEST");
1934 break;
1936 case D3DRS_STENCILFUNC :
1938 int glParm = GL_ALWAYS;
1939 int ref = 0;
1940 GLuint mask = 0xFFFFFFFF;
1942 glGetIntegerv(GL_STENCIL_REF, &ref);
1943 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1944 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1945 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1947 switch ((D3DCMPFUNC) Value) {
1948 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1949 case D3DCMP_LESS: glParm=GL_LESS; break;
1950 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1951 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1952 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1953 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1954 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1955 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1956 default:
1957 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1959 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1960 glStencilFunc(glParm, ref, mask);
1961 checkGLcall("glStencilFunc");
1963 break;
1965 case D3DRS_STENCILREF :
1967 int glParm = GL_ALWAYS;
1968 int ref = 0;
1969 GLuint mask = 0xFFFFFFFF;
1971 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1972 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1973 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1974 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1976 ref = Value;
1977 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1978 glStencilFunc(glParm, ref, mask);
1979 checkGLcall("glStencilFunc");
1981 break;
1983 case D3DRS_STENCILMASK :
1985 int glParm = GL_ALWAYS;
1986 int ref = 0.0;
1987 GLuint mask = Value;
1989 glGetIntegerv(GL_STENCIL_REF, &ref);
1990 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1991 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1992 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1994 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1995 glStencilFunc(glParm, ref, mask);
1996 checkGLcall("glStencilFunc");
1998 break;
2000 case D3DRS_STENCILFAIL :
2002 GLenum fail ;
2003 GLenum zpass ;
2004 GLenum zfail ;
2006 fail = StencilOp(Value);
2007 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2008 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2009 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2010 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2012 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2013 glStencilOp(fail, zfail, zpass);
2014 checkGLcall("glStencilOp(fail, zfail, zpass);");
2016 break;
2017 case D3DRS_STENCILZFAIL :
2019 GLenum fail ;
2020 GLenum zpass ;
2021 GLenum zfail ;
2023 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2024 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2025 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2026 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2027 zfail = StencilOp(Value);
2029 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2030 glStencilOp(fail, zfail, zpass);
2031 checkGLcall("glStencilOp(fail, zfail, zpass);");
2033 break;
2034 case D3DRS_STENCILPASS :
2036 GLenum fail ;
2037 GLenum zpass ;
2038 GLenum zfail ;
2040 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2041 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2042 zpass = StencilOp(Value);
2043 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2044 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2046 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2047 glStencilOp(fail, zfail, zpass);
2048 checkGLcall("glStencilOp(fail, zfail, zpass);");
2050 break;
2052 case D3DRS_STENCILWRITEMASK :
2054 glStencilMask(Value);
2055 TRACE("glStencilMask(%lu)\n", Value);
2056 checkGLcall("glStencilMask");
2058 break;
2060 /* Unhandled yet...! */
2061 case D3DRS_LINEPATTERN :
2062 case D3DRS_LASTPIXEL :
2063 case D3DRS_FOGENABLE :
2064 case D3DRS_ZVISIBLE :
2065 case D3DRS_FOGCOLOR :
2066 case D3DRS_FOGTABLEMODE :
2067 case D3DRS_FOGSTART :
2068 case D3DRS_FOGEND :
2069 case D3DRS_FOGDENSITY :
2070 case D3DRS_EDGEANTIALIAS :
2071 case D3DRS_ZBIAS :
2072 case D3DRS_RANGEFOGENABLE :
2073 case D3DRS_WRAP0 :
2074 case D3DRS_WRAP1 :
2075 case D3DRS_WRAP2 :
2076 case D3DRS_WRAP3 :
2077 case D3DRS_WRAP4 :
2078 case D3DRS_WRAP5 :
2079 case D3DRS_WRAP6 :
2080 case D3DRS_WRAP7 :
2081 case D3DRS_FOGVERTEXMODE :
2082 case D3DRS_COLORVERTEX :
2083 case D3DRS_LOCALVIEWER :
2084 case D3DRS_NORMALIZENORMALS :
2085 case D3DRS_DIFFUSEMATERIALSOURCE :
2086 case D3DRS_SPECULARMATERIALSOURCE :
2087 case D3DRS_AMBIENTMATERIALSOURCE :
2088 case D3DRS_EMISSIVEMATERIALSOURCE :
2089 case D3DRS_VERTEXBLEND :
2090 case D3DRS_SOFTWAREVERTEXPROCESSING :
2091 case D3DRS_POINTSIZE :
2092 case D3DRS_POINTSIZE_MIN :
2093 case D3DRS_POINTSPRITEENABLE :
2094 case D3DRS_POINTSCALEENABLE :
2095 case D3DRS_POINTSCALE_A :
2096 case D3DRS_POINTSCALE_B :
2097 case D3DRS_POINTSCALE_C :
2098 case D3DRS_MULTISAMPLEANTIALIAS :
2099 case D3DRS_MULTISAMPLEMASK :
2100 case D3DRS_PATCHEDGESTYLE :
2101 case D3DRS_PATCHSEGMENTS :
2102 case D3DRS_DEBUGMONITORTOKEN :
2103 case D3DRS_POINTSIZE_MAX :
2104 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2105 case D3DRS_COLORWRITEENABLE :
2106 case D3DRS_TWEENFACTOR :
2107 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2108 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2109 break;
2110 default:
2111 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2114 return D3D_OK;
2116 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2117 ICOM_THIS(IDirect3DDevice8Impl,iface);
2118 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2119 *pValue = This->StateBlock.renderstate[State];
2120 return D3D_OK;
2122 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2123 ICOM_THIS(IDirect3DDevice8Impl,iface);
2125 void *memory;
2127 TRACE("(%p)\n", This);
2128 if (This->isRecordingState) {
2129 TRACE("(%p) already recording! returning error\n", This);
2130 return D3DERR_INVALIDCALL;
2133 /* Allocate Storage */
2134 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2135 This->isRecordingState = TRUE;
2136 This->UpdateStateBlock = memory;
2138 return D3D_OK;
2140 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2142 ICOM_THIS(IDirect3DDevice8Impl,iface);
2143 TRACE("(%p)\n", This);
2145 if (!This->isRecordingState) {
2146 TRACE("(%p) not recording! returning error\n", This);
2147 return D3DERR_INVALIDCALL;
2150 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2151 *pToken = (DWORD) This->UpdateStateBlock;
2152 This->isRecordingState = FALSE;
2153 This->UpdateStateBlock = &This->StateBlock;
2155 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2156 return D3D_OK;
2159 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2161 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2162 int i,j;
2164 ICOM_THIS(IDirect3DDevice8Impl,iface);
2165 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2167 /* FIXME: Only apply applicable states not all states */
2169 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2171 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2173 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2174 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2175 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2176 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2179 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2180 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2182 /* TODO: Vertex Shader Constants */
2185 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2187 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2188 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->PixelShader);
2190 /* TODO: Pixel Shader Constants */
2193 /* Others + Render & Texture */
2194 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2195 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2196 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2197 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2200 if (pSB->Set.Indices && pSB->Changed.Indices)
2201 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2203 if (pSB->Set.material && pSB->Changed.material)
2204 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2206 if (pSB->Set.viewport && pSB->Changed.viewport)
2207 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2209 for (i=0; i<MAX_STREAMS; i++) {
2210 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2211 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2214 for (i=0; i<MAX_CLIPPLANES; i++) {
2215 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2216 float clip[4];
2218 clip[0] = pSB->clipplane[i][0];
2219 clip[1] = pSB->clipplane[i][1];
2220 clip[2] = pSB->clipplane[i][2];
2221 clip[3] = pSB->clipplane[i][3];
2222 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2226 /* Render */
2227 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2229 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2230 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2234 /* Texture */
2235 for (j=0; j<8; j++) {
2236 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2238 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i])
2239 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2242 if (pSB->Set.textures[j] && pSB->Changed.textures[j]) {
2243 IDirect3DDevice8Impl_SetTexture(iface, j, pSB->textures[j]);
2248 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2250 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2251 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2252 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2256 for (j=0; j<8; i++) {
2257 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2259 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2260 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2261 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2265 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2267 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2268 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2269 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2273 for (j=0; j<8; i++) {
2274 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2276 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2277 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2278 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2283 } else {
2284 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2286 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2287 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2289 return D3D_OK;
2291 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2293 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2295 ICOM_THIS(IDirect3DDevice8Impl,iface);
2297 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2299 /* If not recorded, then update can just recapture */
2300 if (updateBlock->blockType != D3DSBT_RECORDED) {
2301 DWORD tmpToken;
2302 STATEBLOCK *tmpBlock;
2303 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2304 tmpBlock = (STATEBLOCK *)tmpToken;
2305 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2306 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2308 /* FIXME: This will record states of new lights! May need to have and save set_lights
2309 across this action */
2311 } else {
2312 int i,j;
2314 /* Recorded => Only update 'changed' values */
2315 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2316 updateBlock->VertexShader = This->StateBlock.VertexShader;
2317 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2320 /* TODO: Vertex Shader Constants */
2322 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2323 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2324 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2325 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2328 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2329 &updateBlock->lights[i],
2330 sizeof(D3DLIGHT8)) != 0) {
2331 TRACE("Updating lights for light %d\n", i);
2332 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2336 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2337 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2338 updateBlock->lights[i] = This->StateBlock.lights[i];
2339 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2342 /* TODO: Pixel Shader Constants */
2344 /* Others + Render & Texture */
2345 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2346 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2347 &updateBlock->transforms[i],
2348 sizeof(D3DMATRIX)) != 0) {
2349 TRACE("Updating transform %d\n", i);
2350 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2354 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2355 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2356 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2357 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2358 updateBlock->pIndexData = This->StateBlock.pIndexData;
2359 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2362 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2363 &updateBlock->material,
2364 sizeof(D3DMATERIAL8)) != 0) {
2365 TRACE("Updating material\n");
2366 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2369 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2370 &updateBlock->viewport,
2371 sizeof(D3DVIEWPORT8)) != 0) {
2372 TRACE("Updating viewport\n");
2373 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2376 for (i=0; i<MAX_STREAMS; i++) {
2377 if (updateBlock->Set.stream_source[i] &&
2378 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2379 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2380 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2381 This->StateBlock.stream_stride[i]);
2382 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2383 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2387 for (i=0; i<MAX_CLIPPLANES; i++) {
2388 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2389 &updateBlock->clipplane[i],
2390 sizeof(updateBlock->clipplane)) != 0) {
2392 TRACE("Updating clipplane %d\n", i);
2393 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2394 sizeof(updateBlock->clipplane));
2398 /* Render */
2399 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2401 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
2402 This->StateBlock.renderstate[i])) {
2403 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2404 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2408 /* Texture */
2409 for (j=0; j<8; j++) {
2410 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2412 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
2413 This->StateBlock.texture_state[j][i])) {
2414 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
2415 updateBlock->texture_state[j][i]);
2416 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
2419 if (updateBlock->Set.textures[j] && (updateBlock->textures[j] != This->StateBlock.textures[j])) {
2420 TRACE("Updating texture %d to %p (was %p)\n", j, This->StateBlock.textures[j], updateBlock->textures[j]);
2421 updateBlock->textures[j] = This->StateBlock.textures[j];
2428 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2430 return D3D_OK;
2432 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2433 ICOM_THIS(IDirect3DDevice8Impl,iface);
2434 TRACE("(%p) : freeing token %lx\n", This, Token);
2435 HeapFree(GetProcessHeap(), 0, (void *)Token);
2436 return D3D_OK;
2439 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type,DWORD* pToken) {
2440 void *memory;
2441 STATEBLOCK *s;
2442 int i,j;
2444 ICOM_THIS(IDirect3DDevice8Impl,iface);
2445 TRACE("(%p) : for type %d\n", This, Type);
2447 /* Allocate Storage */
2448 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2449 if (memory) memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2450 *pToken = (DWORD) memory;
2451 s = memory;
2452 s->blockType = Type;
2454 TRACE("Updating changed flags appropriate for type %d\n", Type);
2456 if (Type == D3DSBT_ALL) {
2457 TRACE("ALL => Pretend everything has changed\n");
2458 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2460 } else if (Type == D3DSBT_PIXELSTATE) {
2462 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2464 /* TODO: Pixel Shader Constants */
2465 s->Changed.pixelShader = TRUE;
2466 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2467 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2469 for (j=0; j<8; i++) {
2470 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2471 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2475 } else if (Type == D3DSBT_VERTEXSTATE) {
2477 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2479 /* TODO: Vertex Shader Constants */
2480 s->Changed.vertexShader = TRUE;
2482 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2483 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2485 for (j=0; j<8; i++) {
2486 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2487 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2491 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2492 s->Changed.lightEnable[i] = TRUE;
2493 s->Changed.lights[i] = TRUE;
2496 } else {
2497 FIXME("Unrecognized state block type %d\n", Type);
2499 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2500 return D3D_OK;
2503 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2504 ICOM_THIS(IDirect3DDevice8Impl,iface);
2505 FIXME("(%p) : stub\n", This); return D3D_OK;
2507 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2508 ICOM_THIS(IDirect3DDevice8Impl,iface);
2509 FIXME("(%p) : stub\n", This); return D3D_OK;
2511 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2512 ICOM_THIS(IDirect3DDevice8Impl,iface);
2513 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2514 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
2515 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2516 return D3D_OK;
2518 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2520 IDirect3DBaseTexture8 *oldTxt;
2522 ICOM_THIS(IDirect3DDevice8Impl,iface);
2523 D3DRESOURCETYPE textureType;
2525 oldTxt = This->StateBlock.textures[Stage];
2526 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2528 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2529 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2530 This->UpdateStateBlock->textures[Stage] = pTexture;
2532 /* Handle recording of state blocks */
2533 if (This->isRecordingState) {
2534 TRACE("Recording... not performing anything\n");
2535 return D3D_OK;
2538 /* Make appropriate texture active */
2539 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2540 checkGLcall("glActiveTextureARB");
2542 /* Decrement the count of the previous texture */
2543 /* FIXME PERF: If old == new and not dirty then skip all this */
2544 if (oldTxt != NULL) {
2545 IDirect3DBaseTexture8Impl_Release(oldTxt);
2548 if (pTexture) {
2549 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
2551 /* Now setup the texture appropraitly */
2552 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2554 if (textureType == D3DRTYPE_TEXTURE) {
2555 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
2556 int i;
2558 /* Standard 2D texture */
2559 TRACE("Standard 2d texture\n");
2560 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
2562 /* for (i=0; i<pTexture2->levels; i++) { */
2563 i=0;
2566 if (pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2567 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2568 checkGLcall("glBindTexture");
2569 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2570 } else {
2572 if (pTexture2->surfaces[i]->textureName == 0) {
2573 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
2574 checkGLcall("glGenTextures");
2575 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2578 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2579 checkGLcall("glBindTexture");
2581 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2582 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
2583 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2584 pTexture2->surfaces[i]->allocatedMemory);
2585 glTexImage2D(GL_TEXTURE_2D, i,
2586 fmt2glintFmt(pTexture2->format),
2587 pTexture2->surfaces[i]->myDesc.Width,
2588 pTexture2->surfaces[i]->myDesc.Height,
2590 fmt2glFmt(pTexture2->format),
2591 fmt2glType(pTexture2->format),
2592 pTexture2->surfaces[i]->allocatedMemory
2594 checkGLcall("glTexImage2D");
2597 * The following enable things to work but I dont think
2598 * they all go here - FIXME! @@@
2600 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2601 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2602 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2603 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2605 pTexture2->Dirty = FALSE;
2610 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
2611 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
2612 int i;
2614 /* Standard 3D (volume) texture */
2615 TRACE("Standard 3d texture\n");
2616 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
2618 /* for (i=0; i<pTexture2->levels; i++) { */
2619 i=0;
2622 if (pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2623 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2624 checkGLcall("glBindTexture");
2625 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2626 } else {
2628 if (pTexture2->volumes[i]->textureName == 0) {
2629 glGenTextures(1, &pTexture2->volumes[i]->textureName);
2630 checkGLcall("glGenTextures");
2631 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2634 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2635 checkGLcall("glBindTexture");
2637 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2638 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
2639 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
2640 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2641 pTexture2->volumes[i]->allocatedMemory);
2642 glTexImage3D(GL_TEXTURE_3D, i,
2643 fmt2glintFmt(pTexture2->format),
2644 pTexture2->volumes[i]->myDesc.Width,
2645 pTexture2->volumes[i]->myDesc.Height,
2646 pTexture2->volumes[i]->myDesc.Depth,
2648 fmt2glFmt(pTexture2->format),
2649 fmt2glType(pTexture2->format),
2650 pTexture2->volumes[i]->allocatedMemory
2652 checkGLcall("glTexImage3D");
2655 * The following enable things to work but I dont think
2656 * they all go here - FIXME! @@@
2658 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2659 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2660 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
2661 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2662 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2664 pTexture2->Dirty = FALSE;
2668 } else {
2669 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
2671 } else {
2672 TRACE("Setting to no texture (ie default texture)\n");
2673 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
2674 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
2675 checkGLcall("glBindTexture");
2676 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
2679 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
2680 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
2681 setupTextureStates (iface, Stage);
2683 return D3D_OK;
2686 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
2687 ICOM_THIS(IDirect3DDevice8Impl,iface);
2688 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
2689 *pValue = This->StateBlock.texture_state[Stage][Type];
2690 return D3D_OK;
2693 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
2694 ICOM_THIS(IDirect3DDevice8Impl,iface);
2696 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2698 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
2700 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
2701 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
2702 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
2704 /* Handle recording of state blocks */
2705 if (This->isRecordingState) {
2706 TRACE("Recording... not performing anything\n");
2707 return D3D_OK;
2710 /* Make appropriate texture active */
2711 TRACE("Activating appropriate texture state %ld\n", Stage);
2712 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2713 checkGLcall("glActiveTextureARB");
2715 switch (Type) {
2717 case D3DTSS_MINFILTER :
2718 if (Value == D3DTEXF_POINT) {
2719 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2720 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_NEAREST");
2721 } else if (Value == D3DTEXF_LINEAR) {
2722 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2723 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_LINEAR");
2724 } else {
2725 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", Value);
2727 break;
2730 case D3DTSS_MAGFILTER :
2731 if (Value == D3DTEXF_POINT) {
2732 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2733 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
2734 } else if (Value == D3DTEXF_LINEAR) {
2735 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2736 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
2737 } else {
2738 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
2740 break;
2742 case D3DTSS_COLORARG0 :
2743 case D3DTSS_ALPHAARG0 :
2744 /* FIXME: Mesa seems to struggle setting these at the moment */
2745 break;
2747 case D3DTSS_COLORARG1 :
2748 case D3DTSS_COLORARG2 :
2749 case D3DTSS_ALPHAARG1 :
2750 case D3DTSS_ALPHAARG2 :
2752 BOOL isAlphaReplicate = FALSE;
2753 BOOL isComplement = FALSE;
2754 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
2755 int operand= GL_SRC_COLOR;
2756 int source = GL_TEXTURE;
2758 /* Catch alpha replicate */
2759 if (Value & D3DTA_ALPHAREPLICATE) {
2760 Value = Value & ~D3DTA_ALPHAREPLICATE;
2761 isAlphaReplicate = TRUE;
2764 /* Catch Complement */
2765 if (Value & D3DTA_COMPLEMENT) {
2766 Value = Value & ~D3DTA_COMPLEMENT;
2767 isComplement = TRUE;
2770 /* Calculate the operand */
2771 if (isAlphaReplicate && !isComplement) {
2772 operand = GL_SRC_ALPHA;
2773 } else if (isAlphaReplicate && isComplement) {
2774 operand = GL_ONE_MINUS_SRC_ALPHA;
2775 } else if (isComplement) {
2776 if (isAlphaArg) {
2777 operand = GL_ONE_MINUS_SRC_COLOR;
2778 } else {
2779 operand = GL_ONE_MINUS_SRC_ALPHA;
2781 } else {
2782 if (isAlphaArg) {
2783 operand = GL_SRC_ALPHA;
2784 } else {
2785 operand = GL_SRC_COLOR;
2789 /* Calculate the source */
2790 switch (Value) {
2791 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
2792 break;
2793 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
2794 break;
2795 case D3DTA_TEXTURE: source = GL_TEXTURE;
2796 break;
2797 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
2798 break;
2800 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
2801 isnt supported until base GL supports it
2802 There is no concept of temp registers as far as I can tell */
2804 default:
2805 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
2808 if (isAlphaArg) {
2809 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
2810 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
2811 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
2812 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
2813 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
2814 } else {
2815 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
2816 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
2817 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
2818 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
2819 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
2822 break;
2824 case D3DTSS_ALPHAOP :
2825 case D3DTSS_COLOROP :
2828 int Scale = 1;
2829 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
2831 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
2832 /* TODO: Disable by making this and all later levels disabled */
2833 glDisable(GL_TEXTURE_1D);
2834 checkGLcall("Disable GL_TEXTURE_1D");
2835 glDisable(GL_TEXTURE_2D);
2836 checkGLcall("Disable GL_TEXTURE_2D");
2837 glDisable(GL_TEXTURE_3D);
2838 checkGLcall("Disable GL_TEXTURE_3D");
2839 } else {
2841 /* Enable only the appropriate texture dimension */
2842 if (Type==D3DTSS_COLOROP) {
2843 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
2844 glEnable(GL_TEXTURE_1D);
2845 checkGLcall("Enable GL_TEXTURE_1D");
2846 } else {
2847 glDisable(GL_TEXTURE_1D);
2848 checkGLcall("Disable GL_TEXTURE_1D");
2850 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
2851 glEnable(GL_TEXTURE_2D);
2852 checkGLcall("Enable GL_TEXTURE_2D");
2853 } else {
2854 glDisable(GL_TEXTURE_2D);
2855 checkGLcall("Disable GL_TEXTURE_2D");
2857 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
2858 glEnable(GL_TEXTURE_3D);
2859 checkGLcall("Enable GL_TEXTURE_3D");
2860 } else {
2861 glDisable(GL_TEXTURE_3D);
2862 checkGLcall("Disable GL_TEXTURE_3D");
2866 /* Now set up the operand correctly */
2867 switch (Value) {
2868 case D3DTOP_DISABLE :
2869 /* Contrary to the docs, alpha can be disabled when colorop is enabled
2870 and it works, so ignore this op */
2871 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
2872 break;
2874 case D3DTOP_SELECTARG1 :
2875 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
2876 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
2877 break;
2879 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
2880 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
2881 case D3DTOP_MODULATE :
2883 /* Correct scale */
2884 if (Type == D3DTSS_ALPHAOP) {
2885 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
2886 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
2887 } else {
2888 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
2889 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
2891 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
2892 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
2893 break;
2895 case D3DTOP_ADD :
2896 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
2897 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
2898 break;
2900 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
2901 case D3DTOP_ADDSIGNED :
2902 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
2903 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
2904 break;
2906 case D3DTOP_DOTPRODUCT3 :
2907 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
2908 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
2909 break;*/
2911 case D3DTOP_SUBTRACT :
2912 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
2913 case D3DTOP_SELECTARG2 :
2914 /* GL_REPLACE, swap args 0 and 1? */
2915 case D3DTOP_ADDSMOOTH :
2916 case D3DTOP_BLENDDIFFUSEALPHA :
2917 case D3DTOP_BLENDTEXTUREALPHA :
2918 case D3DTOP_BLENDFACTORALPHA :
2919 case D3DTOP_BLENDTEXTUREALPHAPM :
2920 case D3DTOP_BLENDCURRENTALPHA :
2921 case D3DTOP_PREMODULATE :
2922 case D3DTOP_MODULATEALPHA_ADDCOLOR :
2923 case D3DTOP_MODULATECOLOR_ADDALPHA :
2924 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
2925 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
2926 case D3DTOP_BUMPENVMAP :
2927 case D3DTOP_BUMPENVMAPLUMINANCE :
2928 case D3DTOP_MULTIPLYADD :
2929 case D3DTOP_LERP :
2930 default:
2931 FIXME("Unhandled texture operation %ld\n", Value);
2934 break;
2937 /* Unhandled */
2938 case D3DTSS_BUMPENVMAT00 :
2939 case D3DTSS_BUMPENVMAT01 :
2940 case D3DTSS_BUMPENVMAT10 :
2941 case D3DTSS_BUMPENVMAT11 :
2942 case D3DTSS_TEXCOORDINDEX :
2943 case D3DTSS_ADDRESSU :
2944 case D3DTSS_ADDRESSV :
2945 case D3DTSS_BORDERCOLOR :
2946 case D3DTSS_MIPFILTER :
2947 case D3DTSS_MIPMAPLODBIAS :
2948 case D3DTSS_MAXMIPLEVEL :
2949 case D3DTSS_MAXANISOTROPY :
2950 case D3DTSS_BUMPENVLSCALE :
2951 case D3DTSS_BUMPENVLOFFSET :
2952 case D3DTSS_TEXTURETRANSFORMFLAGS :
2953 case D3DTSS_ADDRESSW :
2954 case D3DTSS_RESULTARG :
2955 default:
2956 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
2957 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
2959 return D3D_OK;
2961 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
2962 ICOM_THIS(IDirect3DDevice8Impl,iface);
2963 FIXME("(%p) : stub\n", This); return D3D_OK;
2965 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
2966 ICOM_THIS(IDirect3DDevice8Impl,iface);
2967 FIXME("(%p) : stub\n", This); return D3D_OK;
2969 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
2970 ICOM_THIS(IDirect3DDevice8Impl,iface);
2971 FIXME("(%p) : stub\n", This); return D3D_OK;
2973 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
2974 ICOM_THIS(IDirect3DDevice8Impl,iface);
2975 FIXME("(%p) : stub\n", This); return D3D_OK;
2977 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
2978 ICOM_THIS(IDirect3DDevice8Impl,iface);
2979 FIXME("(%p) : stub\n", This); return D3D_OK;
2981 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
2982 ICOM_THIS(IDirect3DDevice8Impl,iface);
2983 FIXME("(%p) : stub\n", This); return D3D_OK;
2985 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
2987 IDirect3DVertexBuffer8 *pVB;
2989 ICOM_THIS(IDirect3DDevice8Impl,iface);
2990 pVB = This->StateBlock.stream_source[0];
2992 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
2994 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
2995 This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL);
2997 return D3D_OK;
2999 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3000 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3001 UINT idxStride = 2;
3002 IDirect3DIndexBuffer8 *pIB;
3003 IDirect3DVertexBuffer8 *pVB;
3004 D3DINDEXBUFFER_DESC IdxBufDsc;
3006 ICOM_THIS(IDirect3DDevice8Impl,iface);
3007 pIB = This->StateBlock.pIndexData;
3008 pVB = This->StateBlock.stream_source[0];
3010 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3011 minIndex, NumVertices, startIndex, primCount);
3013 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3014 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3015 idxStride = 2;
3016 } else {
3017 idxStride = 4;
3020 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3021 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory);
3023 return D3D_OK;
3025 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3026 ICOM_THIS(IDirect3DDevice8Impl,iface);
3028 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3030 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3032 This->StateBlock.stream_source[0] = NULL;
3033 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3034 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3035 0, 0, 0, NULL);
3036 This->StateBlock.stream_stride[0] = 0;
3038 /*stream zero settings set to null at end */
3039 return D3D_OK;
3041 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3042 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3043 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3044 UINT VertexStreamZeroStride) {
3045 int idxStride;
3046 ICOM_THIS(IDirect3DDevice8Impl,iface);
3047 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3048 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3050 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3051 if (IndexDataFormat == D3DFMT_INDEX16) {
3052 idxStride = 2;
3053 } else {
3054 idxStride = 4;
3057 This->StateBlock.stream_source[0] = NULL;
3058 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3059 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3060 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData);
3062 /*stream zero settings set to null at end */
3063 This->StateBlock.stream_stride[0] = 0;
3064 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3066 return D3D_OK;
3068 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3069 ICOM_THIS(IDirect3DDevice8Impl,iface);
3070 FIXME("(%p) : stub\n", This); return D3D_OK;
3072 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) {
3073 ICOM_THIS(IDirect3DDevice8Impl,iface);
3074 FIXME("(%p) : stub\n", This); return D3D_OK;
3076 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3077 ICOM_THIS(IDirect3DDevice8Impl,iface);
3079 This->UpdateStateBlock->VertexShader = Handle;
3080 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3081 This->UpdateStateBlock->Set.vertexShader = TRUE;
3083 /* Handle recording of state blocks */
3084 if (This->isRecordingState) {
3085 TRACE("Recording... not performing anything\n");
3086 return D3D_OK;
3089 if (Handle <= VS_HIGHESTFIXEDFXF) {
3090 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3091 return D3D_OK;
3092 } else {
3093 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3094 return D3D_OK;
3097 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3098 ICOM_THIS(IDirect3DDevice8Impl,iface);
3099 TRACE("(%p) = %ld\n", This, This->StateBlock.VertexShader);
3100 *pHandle = This->StateBlock.VertexShader;
3101 return D3D_OK;
3104 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3105 ICOM_THIS(IDirect3DDevice8Impl,iface);
3106 FIXME("(%p) : stub\n", This); return D3D_OK;
3108 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3109 ICOM_THIS(IDirect3DDevice8Impl,iface);
3110 FIXME("(%p) : stub\n", This); return D3D_OK;
3112 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3113 ICOM_THIS(IDirect3DDevice8Impl,iface);
3114 FIXME("(%p) : stub\n", This); return D3D_OK;
3116 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3117 ICOM_THIS(IDirect3DDevice8Impl,iface);
3118 FIXME("(%p) : stub\n", This); return D3D_OK;
3120 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3121 ICOM_THIS(IDirect3DDevice8Impl,iface);
3122 FIXME("(%p) : stub\n", This); return D3D_OK;
3125 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3127 IDirect3DIndexBuffer8 *oldIdxs;
3129 ICOM_THIS(IDirect3DDevice8Impl,iface);
3130 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3131 oldIdxs = This->StateBlock.pIndexData;
3133 This->UpdateStateBlock->Changed.Indices = TRUE;
3134 This->UpdateStateBlock->Set.Indices = TRUE;
3135 This->UpdateStateBlock->pIndexData = pIndexData;
3136 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3138 /* Handle recording of state blocks */
3139 if (This->isRecordingState) {
3140 TRACE("Recording... not performing anything\n");
3141 return D3D_OK;
3144 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3145 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3146 return D3D_OK;
3148 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3149 ICOM_THIS(IDirect3DDevice8Impl,iface);
3150 FIXME("(%p) : stub\n", This);
3152 *ppIndexData = This->StateBlock.pIndexData;
3153 /* up ref count on ppindexdata */
3154 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3155 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3157 return D3D_OK;
3159 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction,DWORD* pHandle) {
3160 ICOM_THIS(IDirect3DDevice8Impl,iface);
3161 FIXME("(%p) : stub\n", This); return D3D_OK;
3163 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3164 ICOM_THIS(IDirect3DDevice8Impl,iface);
3166 This->UpdateStateBlock->PixelShader = Handle;
3167 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3168 This->UpdateStateBlock->Set.pixelShader = TRUE;
3170 /* Handle recording of state blocks */
3171 if (This->isRecordingState) {
3172 TRACE("Recording... not performing anything\n");
3173 return D3D_OK;
3176 /* FIXME: Quieten when not being used */
3177 if (Handle != 0) {
3178 FIXME("(%p) : stub %ld\n", This, Handle);
3179 } else {
3180 TRACE("(%p) : stub %ld\n", This, Handle);
3183 return D3D_OK;
3185 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3186 ICOM_THIS(IDirect3DDevice8Impl,iface);
3187 TRACE("(%p) : returning %ld\n", This, This->StateBlock.PixelShader);
3188 *pHandle = This->StateBlock.PixelShader;
3189 return D3D_OK;
3192 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3193 ICOM_THIS(IDirect3DDevice8Impl,iface);
3194 FIXME("(%p) : stub\n", This); return D3D_OK;
3196 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3197 ICOM_THIS(IDirect3DDevice8Impl,iface);
3198 FIXME("(%p) : stub\n", This); return D3D_OK;
3200 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3201 ICOM_THIS(IDirect3DDevice8Impl,iface);
3202 FIXME("(%p) : stub\n", This); return D3D_OK;
3204 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3205 ICOM_THIS(IDirect3DDevice8Impl,iface);
3206 FIXME("(%p) : stub\n", This); return D3D_OK;
3208 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3209 ICOM_THIS(IDirect3DDevice8Impl,iface);
3210 FIXME("(%p) : stub\n", This); return D3D_OK;
3212 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3213 ICOM_THIS(IDirect3DDevice8Impl,iface);
3214 FIXME("(%p) : stub\n", This); return D3D_OK;
3216 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3217 ICOM_THIS(IDirect3DDevice8Impl,iface);
3218 FIXME("(%p) : stub\n", This); return D3D_OK;
3221 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3222 IDirect3DVertexBuffer8 *oldSrc;
3223 ICOM_THIS(IDirect3DDevice8Impl,iface);
3225 oldSrc = This->StateBlock.stream_source[StreamNumber];
3226 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3228 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3229 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3230 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3231 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3233 /* Handle recording of state blocks */
3234 if (This->isRecordingState) {
3235 TRACE("Recording... not performing anything\n");
3236 return D3D_OK;
3239 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3240 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3241 return D3D_OK;
3243 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3244 ICOM_THIS(IDirect3DDevice8Impl,iface);
3245 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3246 *pStream = This->StateBlock.stream_source[StreamNumber];
3247 *pStride = This->StateBlock.stream_stride[StreamNumber];
3248 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3249 return D3D_OK;
3253 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3255 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3256 IDirect3DDevice8Impl_QueryInterface,
3257 IDirect3DDevice8Impl_AddRef,
3258 IDirect3DDevice8Impl_Release,
3259 IDirect3DDevice8Impl_TestCooperativeLevel,
3260 IDirect3DDevice8Impl_GetAvailableTextureMem,
3261 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3262 IDirect3DDevice8Impl_GetDirect3D,
3263 IDirect3DDevice8Impl_GetDeviceCaps,
3264 IDirect3DDevice8Impl_GetDisplayMode,
3265 IDirect3DDevice8Impl_GetCreationParameters,
3266 IDirect3DDevice8Impl_SetCursorProperties,
3267 IDirect3DDevice8Impl_SetCursorPosition,
3268 IDirect3DDevice8Impl_ShowCursor,
3269 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3270 IDirect3DDevice8Impl_Reset,
3271 IDirect3DDevice8Impl_Present,
3272 IDirect3DDevice8Impl_GetBackBuffer,
3273 IDirect3DDevice8Impl_GetRasterStatus,
3274 IDirect3DDevice8Impl_SetGammaRamp,
3275 IDirect3DDevice8Impl_GetGammaRamp,
3276 IDirect3DDevice8Impl_CreateTexture,
3277 IDirect3DDevice8Impl_CreateVolumeTexture,
3278 IDirect3DDevice8Impl_CreateCubeTexture,
3279 IDirect3DDevice8Impl_CreateVertexBuffer,
3280 IDirect3DDevice8Impl_CreateIndexBuffer,
3281 IDirect3DDevice8Impl_CreateRenderTarget,
3282 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3283 IDirect3DDevice8Impl_CreateImageSurface,
3284 IDirect3DDevice8Impl_CopyRects,
3285 IDirect3DDevice8Impl_UpdateTexture,
3286 IDirect3DDevice8Impl_GetFrontBuffer,
3287 IDirect3DDevice8Impl_SetRenderTarget,
3288 IDirect3DDevice8Impl_GetRenderTarget,
3289 IDirect3DDevice8Impl_GetDepthStencilSurface,
3290 IDirect3DDevice8Impl_BeginScene,
3291 IDirect3DDevice8Impl_EndScene,
3292 IDirect3DDevice8Impl_Clear,
3293 IDirect3DDevice8Impl_SetTransform,
3294 IDirect3DDevice8Impl_GetTransform,
3295 IDirect3DDevice8Impl_MultiplyTransform,
3296 IDirect3DDevice8Impl_SetViewport,
3297 IDirect3DDevice8Impl_GetViewport,
3298 IDirect3DDevice8Impl_SetMaterial,
3299 IDirect3DDevice8Impl_GetMaterial,
3300 IDirect3DDevice8Impl_SetLight,
3301 IDirect3DDevice8Impl_GetLight,
3302 IDirect3DDevice8Impl_LightEnable,
3303 IDirect3DDevice8Impl_GetLightEnable,
3304 IDirect3DDevice8Impl_SetClipPlane,
3305 IDirect3DDevice8Impl_GetClipPlane,
3306 IDirect3DDevice8Impl_SetRenderState,
3307 IDirect3DDevice8Impl_GetRenderState,
3308 IDirect3DDevice8Impl_BeginStateBlock,
3309 IDirect3DDevice8Impl_EndStateBlock,
3310 IDirect3DDevice8Impl_ApplyStateBlock,
3311 IDirect3DDevice8Impl_CaptureStateBlock,
3312 IDirect3DDevice8Impl_DeleteStateBlock,
3313 IDirect3DDevice8Impl_CreateStateBlock,
3314 IDirect3DDevice8Impl_SetClipStatus,
3315 IDirect3DDevice8Impl_GetClipStatus,
3316 IDirect3DDevice8Impl_GetTexture,
3317 IDirect3DDevice8Impl_SetTexture,
3318 IDirect3DDevice8Impl_GetTextureStageState,
3319 IDirect3DDevice8Impl_SetTextureStageState,
3320 IDirect3DDevice8Impl_ValidateDevice,
3321 IDirect3DDevice8Impl_GetInfo,
3322 IDirect3DDevice8Impl_SetPaletteEntries,
3323 IDirect3DDevice8Impl_GetPaletteEntries,
3324 IDirect3DDevice8Impl_SetCurrentTexturePalette,
3325 IDirect3DDevice8Impl_GetCurrentTexturePalette,
3326 IDirect3DDevice8Impl_DrawPrimitive,
3327 IDirect3DDevice8Impl_DrawIndexedPrimitive,
3328 IDirect3DDevice8Impl_DrawPrimitiveUP,
3329 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
3330 IDirect3DDevice8Impl_ProcessVertices,
3331 IDirect3DDevice8Impl_CreateVertexShader,
3332 IDirect3DDevice8Impl_SetVertexShader,
3333 IDirect3DDevice8Impl_GetVertexShader,
3334 IDirect3DDevice8Impl_DeleteVertexShader,
3335 IDirect3DDevice8Impl_SetVertexShaderConstant,
3336 IDirect3DDevice8Impl_GetVertexShaderConstant,
3337 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
3338 IDirect3DDevice8Impl_GetVertexShaderFunction,
3339 IDirect3DDevice8Impl_SetStreamSource,
3340 IDirect3DDevice8Impl_GetStreamSource,
3341 IDirect3DDevice8Impl_SetIndices,
3342 IDirect3DDevice8Impl_GetIndices,
3343 IDirect3DDevice8Impl_CreatePixelShader,
3344 IDirect3DDevice8Impl_SetPixelShader,
3345 IDirect3DDevice8Impl_GetPixelShader,
3346 IDirect3DDevice8Impl_DeletePixelShader,
3347 IDirect3DDevice8Impl_SetPixelShaderConstant,
3348 IDirect3DDevice8Impl_GetPixelShaderConstant,
3349 IDirect3DDevice8Impl_GetPixelShaderFunction,
3350 IDirect3DDevice8Impl_DrawRectPatch,
3351 IDirect3DDevice8Impl_DrawTriPatch,
3352 IDirect3DDevice8Impl_DeletePatch
3355 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
3356 D3DLINEPATTERN lp;
3357 int i;
3359 ICOM_THIS(IDirect3DDevice8Impl,iface);
3361 /* Note this may have a large overhead but it should only be executed
3362 once, in order to initialize the complete state of the device and
3363 all opengl equivalents */
3364 TRACE("-----------------------> Setting up device defaults...\n");
3365 This->StateBlock.blockType = D3DSBT_ALL;
3367 /* FIXME: Set some of the defaults for lights, transforms etc */
3368 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
3369 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
3370 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
3372 /* Render states: */
3373 if (This->PresentParms.EnableAutoDepthStencil) {
3374 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
3375 } else {
3376 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
3378 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
3379 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3380 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
3381 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
3382 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
3383 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
3384 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
3385 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
3386 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
3387 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3388 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
3389 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
3390 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
3391 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
3392 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
3393 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
3394 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
3395 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
3396 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3397 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
3398 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
3399 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
3400 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
3401 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
3402 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
3403 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
3404 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
3405 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
3406 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
3407 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
3408 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
3409 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
3410 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
3411 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
3412 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
3413 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
3414 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
3415 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
3416 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
3417 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
3418 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
3419 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
3420 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
3421 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
3422 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
3423 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3424 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
3425 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
3426 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
3427 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3428 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
3429 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
3430 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
3431 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
3432 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
3433 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
3434 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
3435 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
3436 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
3437 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
3438 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
3439 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
3440 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
3441 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
3442 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
3443 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
3444 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
3445 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
3446 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
3447 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
3448 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
3449 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
3450 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
3451 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
3452 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
3454 /* Texture Stage States - Put directly into state block, we will call function below */
3455 for (i=0; i<8;i++) {
3456 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
3457 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
3458 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
3459 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
3460 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
3461 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
3462 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
3463 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
3464 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
3465 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
3466 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
3467 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
3468 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
3469 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
3470 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
3471 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
3472 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
3473 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
3474 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
3475 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
3476 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
3477 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
3478 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
3479 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
3480 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
3481 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
3482 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
3485 /* Under DirectX you can have texture stage operations even if no texture is
3486 bound, whereas opengl will only do texture operations when a valid texture is
3487 bound. We emulate this by creating 8 dummy textures and binding them to each
3488 texture stage, but disable all stages by default. Hence if a stage is enabled
3489 then the default texture will kick in until replaced by a SetTexture call */
3491 for (i=0; i<8; i++) {
3492 GLubyte white = 255;
3494 /* Note this avoids calling settexture, so pretend it has been called */
3495 This->StateBlock.Set.textures[i] = TRUE;
3496 This->StateBlock.Changed.textures[i] = TRUE;
3497 This->StateBlock.textures[i] = NULL;
3499 /* Make appropriate texture active */
3500 glActiveTextureARB(GL_TEXTURE0_ARB + i);
3501 checkGLcall("glActiveTextureARB");
3503 /* Generate an opengl texture name */
3504 glGenTextures(1, &This->dummyTextureName[i]);
3505 checkGLcall("glGenTextures");
3506 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
3508 /* Generate a dummy 1d texture */
3509 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
3510 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
3511 checkGLcall("glBindTexture");
3513 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
3514 checkGLcall("glTexImage1D");
3516 /* Reapply all the texture state information to this texture */
3517 setupTextureStates(iface, i);
3520 TRACE("-----------------------> Device defaults now set up...\n");
3525 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
3526 D3DRS_ALPHABLENDENABLE ,
3527 D3DRS_ALPHAFUNC ,
3528 D3DRS_ALPHAREF ,
3529 D3DRS_ALPHATESTENABLE ,
3530 D3DRS_BLENDOP ,
3531 D3DRS_COLORWRITEENABLE ,
3532 D3DRS_DESTBLEND ,
3533 D3DRS_DITHERENABLE ,
3534 D3DRS_EDGEANTIALIAS ,
3535 D3DRS_FILLMODE ,
3536 D3DRS_FOGDENSITY ,
3537 D3DRS_FOGEND ,
3538 D3DRS_FOGSTART ,
3539 D3DRS_LASTPIXEL ,
3540 D3DRS_LINEPATTERN ,
3541 D3DRS_SHADEMODE ,
3542 D3DRS_SRCBLEND ,
3543 D3DRS_STENCILENABLE ,
3544 D3DRS_STENCILFAIL ,
3545 D3DRS_STENCILFUNC ,
3546 D3DRS_STENCILMASK ,
3547 D3DRS_STENCILPASS ,
3548 D3DRS_STENCILREF ,
3549 D3DRS_STENCILWRITEMASK ,
3550 D3DRS_STENCILZFAIL ,
3551 D3DRS_TEXTUREFACTOR ,
3552 D3DRS_WRAP0 ,
3553 D3DRS_WRAP1 ,
3554 D3DRS_WRAP2 ,
3555 D3DRS_WRAP3 ,
3556 D3DRS_WRAP4 ,
3557 D3DRS_WRAP5 ,
3558 D3DRS_WRAP6 ,
3559 D3DRS_WRAP7 ,
3560 D3DRS_ZBIAS ,
3561 D3DRS_ZENABLE ,
3562 D3DRS_ZFUNC ,
3563 D3DRS_ZWRITEENABLE
3566 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
3567 D3DTSS_ADDRESSU ,
3568 D3DTSS_ADDRESSV ,
3569 D3DTSS_ADDRESSW ,
3570 D3DTSS_ALPHAARG0 ,
3571 D3DTSS_ALPHAARG1 ,
3572 D3DTSS_ALPHAARG2 ,
3573 D3DTSS_ALPHAOP ,
3574 D3DTSS_BORDERCOLOR ,
3575 D3DTSS_BUMPENVLOFFSET ,
3576 D3DTSS_BUMPENVLSCALE ,
3577 D3DTSS_BUMPENVMAT00 ,
3578 D3DTSS_BUMPENVMAT01 ,
3579 D3DTSS_BUMPENVMAT10 ,
3580 D3DTSS_BUMPENVMAT11 ,
3581 D3DTSS_COLORARG0 ,
3582 D3DTSS_COLORARG1 ,
3583 D3DTSS_COLORARG2 ,
3584 D3DTSS_COLOROP ,
3585 D3DTSS_MAGFILTER ,
3586 D3DTSS_MAXANISOTROPY ,
3587 D3DTSS_MAXMIPLEVEL ,
3588 D3DTSS_MINFILTER ,
3589 D3DTSS_MIPFILTER ,
3590 D3DTSS_MIPMAPLODBIAS ,
3591 D3DTSS_RESULTARG ,
3592 D3DTSS_TEXCOORDINDEX ,
3593 D3DTSS_TEXTURETRANSFORMFLAGS
3596 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
3597 D3DRS_AMBIENT ,
3598 D3DRS_AMBIENTMATERIALSOURCE ,
3599 D3DRS_CLIPPING ,
3600 D3DRS_CLIPPLANEENABLE ,
3601 D3DRS_COLORVERTEX ,
3602 D3DRS_DIFFUSEMATERIALSOURCE ,
3603 D3DRS_EMISSIVEMATERIALSOURCE ,
3604 D3DRS_FOGDENSITY ,
3605 D3DRS_FOGEND ,
3606 D3DRS_FOGSTART ,
3607 D3DRS_FOGTABLEMODE ,
3608 D3DRS_FOGVERTEXMODE ,
3609 D3DRS_INDEXEDVERTEXBLENDENABLE ,
3610 D3DRS_LIGHTING ,
3611 D3DRS_LOCALVIEWER ,
3612 D3DRS_MULTISAMPLEANTIALIAS ,
3613 D3DRS_MULTISAMPLEMASK ,
3614 D3DRS_NORMALIZENORMALS ,
3615 D3DRS_PATCHEDGESTYLE ,
3616 D3DRS_PATCHSEGMENTS ,
3617 D3DRS_POINTSCALE_A ,
3618 D3DRS_POINTSCALE_B ,
3619 D3DRS_POINTSCALE_C ,
3620 D3DRS_POINTSCALEENABLE ,
3621 D3DRS_POINTSIZE ,
3622 D3DRS_POINTSIZE_MAX ,
3623 D3DRS_POINTSIZE_MIN ,
3624 D3DRS_POINTSPRITEENABLE ,
3625 D3DRS_RANGEFOGENABLE ,
3626 D3DRS_SOFTWAREVERTEXPROCESSING ,
3627 D3DRS_SPECULARMATERIALSOURCE ,
3628 D3DRS_TWEENFACTOR ,
3629 D3DRS_VERTEXBLEND
3632 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
3633 D3DTSS_TEXCOORDINDEX ,
3634 D3DTSS_TEXTURETRANSFORMFLAGS