- Stencil mapping now works (it helps to actually allocate a stencil
[wine/gsoc_dplay.git] / dlls / d3d8 / device.c
blobbbfd58a4135e60c7db6a162e3601205215b1e502
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<29; 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 glBlendEquation(glParm);
1879 checkGLcall("glBlendEquation");
1881 break;
1883 case D3DRS_TEXTUREFACTOR :
1885 int i;
1887 /* Note the texture color applies to all textures whereas
1888 GL_TEXTURE_ENV_COLOR applies to active only */
1889 float col[4];
1890 col[0] = ((Value >> 16) & 0xFF) / 255.0;
1891 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
1892 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
1893 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
1895 /* Set the default alpha blend color */
1896 glBlendColor(col[0], col[1], col[2], col[3]);
1897 checkGLcall("glBlendColor");
1899 /* And now the default texture color as well */
1900 for (i=0; i<8; i++) {
1902 /* Note the D3DRS value applies to all textures, but GL has one
1903 per texture, so apply it now ready to be used! */
1904 checkGLcall("Activate texture.. to update const color");
1905 glActiveTextureARB(GL_TEXTURE0_ARB + i);
1907 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1908 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1911 break;
1913 case D3DRS_SPECULARENABLE :
1915 if (Value) {
1916 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
1917 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
1918 } else {
1919 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
1920 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
1923 break;
1925 case D3DRS_STENCILENABLE :
1926 if (Value) {
1927 glEnable(GL_STENCIL_TEST);
1928 checkGLcall("glEnable GL_STENCIL_TEST");
1929 } else {
1930 glDisable(GL_STENCIL_TEST);
1931 checkGLcall("glDisable GL_STENCIL_TEST");
1933 break;
1935 case D3DRS_STENCILFUNC :
1937 int glParm = GL_ALWAYS;
1938 int ref = 0;
1939 GLuint mask = 0xFFFFFFFF;
1941 glGetIntegerv(GL_STENCIL_REF, &ref);
1942 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1943 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1944 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1946 switch ((D3DCMPFUNC) Value) {
1947 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1948 case D3DCMP_LESS: glParm=GL_LESS; break;
1949 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1950 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1951 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1952 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1953 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1954 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1955 default:
1956 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1958 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1959 glStencilFunc(glParm, ref, mask);
1960 checkGLcall("glStencilFunc");
1962 break;
1964 case D3DRS_STENCILREF :
1966 int glParm = GL_ALWAYS;
1967 int ref = 0;
1968 GLuint mask = 0xFFFFFFFF;
1970 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1971 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1972 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
1973 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
1975 ref = Value;
1976 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1977 glStencilFunc(glParm, ref, mask);
1978 checkGLcall("glStencilFunc");
1980 break;
1982 case D3DRS_STENCILMASK :
1984 int glParm = GL_ALWAYS;
1985 int ref = 0.0;
1986 GLuint mask = Value;
1988 glGetIntegerv(GL_STENCIL_REF, &ref);
1989 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
1990 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
1991 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
1993 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
1994 glStencilFunc(glParm, ref, mask);
1995 checkGLcall("glStencilFunc");
1997 break;
1999 case D3DRS_STENCILFAIL :
2001 GLenum fail ;
2002 GLenum zpass ;
2003 GLenum zfail ;
2005 fail = StencilOp(Value);
2006 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2007 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2008 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2009 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2011 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2012 glStencilOp(fail, zfail, zpass);
2013 checkGLcall("glStencilOp(fail, zfail, zpass);");
2015 break;
2016 case D3DRS_STENCILZFAIL :
2018 GLenum fail ;
2019 GLenum zpass ;
2020 GLenum zfail ;
2022 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2023 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2024 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2025 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2026 zfail = StencilOp(Value);
2028 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2029 glStencilOp(fail, zfail, zpass);
2030 checkGLcall("glStencilOp(fail, zfail, zpass);");
2032 break;
2033 case D3DRS_STENCILPASS :
2035 GLenum fail ;
2036 GLenum zpass ;
2037 GLenum zfail ;
2039 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2040 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2041 zpass = StencilOp(Value);
2042 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2043 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2045 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2046 glStencilOp(fail, zfail, zpass);
2047 checkGLcall("glStencilOp(fail, zfail, zpass);");
2049 break;
2051 case D3DRS_STENCILWRITEMASK :
2053 glStencilMask(Value);
2054 TRACE("glStencilMask(%lu)\n", Value);
2055 checkGLcall("glStencilMask");
2057 break;
2059 /* Unhandled yet...! */
2060 case D3DRS_LINEPATTERN :
2061 case D3DRS_LASTPIXEL :
2062 case D3DRS_FOGENABLE :
2063 case D3DRS_ZVISIBLE :
2064 case D3DRS_FOGCOLOR :
2065 case D3DRS_FOGTABLEMODE :
2066 case D3DRS_FOGSTART :
2067 case D3DRS_FOGEND :
2068 case D3DRS_FOGDENSITY :
2069 case D3DRS_EDGEANTIALIAS :
2070 case D3DRS_ZBIAS :
2071 case D3DRS_RANGEFOGENABLE :
2072 case D3DRS_WRAP0 :
2073 case D3DRS_WRAP1 :
2074 case D3DRS_WRAP2 :
2075 case D3DRS_WRAP3 :
2076 case D3DRS_WRAP4 :
2077 case D3DRS_WRAP5 :
2078 case D3DRS_WRAP6 :
2079 case D3DRS_WRAP7 :
2080 case D3DRS_FOGVERTEXMODE :
2081 case D3DRS_COLORVERTEX :
2082 case D3DRS_LOCALVIEWER :
2083 case D3DRS_NORMALIZENORMALS :
2084 case D3DRS_DIFFUSEMATERIALSOURCE :
2085 case D3DRS_SPECULARMATERIALSOURCE :
2086 case D3DRS_AMBIENTMATERIALSOURCE :
2087 case D3DRS_EMISSIVEMATERIALSOURCE :
2088 case D3DRS_VERTEXBLEND :
2089 case D3DRS_SOFTWAREVERTEXPROCESSING :
2090 case D3DRS_POINTSIZE :
2091 case D3DRS_POINTSIZE_MIN :
2092 case D3DRS_POINTSPRITEENABLE :
2093 case D3DRS_POINTSCALEENABLE :
2094 case D3DRS_POINTSCALE_A :
2095 case D3DRS_POINTSCALE_B :
2096 case D3DRS_POINTSCALE_C :
2097 case D3DRS_MULTISAMPLEANTIALIAS :
2098 case D3DRS_MULTISAMPLEMASK :
2099 case D3DRS_PATCHEDGESTYLE :
2100 case D3DRS_PATCHSEGMENTS :
2101 case D3DRS_DEBUGMONITORTOKEN :
2102 case D3DRS_POINTSIZE_MAX :
2103 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2104 case D3DRS_COLORWRITEENABLE :
2105 case D3DRS_TWEENFACTOR :
2106 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2107 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2108 break;
2109 default:
2110 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2113 return D3D_OK;
2115 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2116 ICOM_THIS(IDirect3DDevice8Impl,iface);
2117 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2118 *pValue = This->StateBlock.renderstate[State];
2119 return D3D_OK;
2121 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2122 ICOM_THIS(IDirect3DDevice8Impl,iface);
2124 void *memory;
2126 TRACE("(%p)\n", This);
2127 if (This->isRecordingState) {
2128 TRACE("(%p) already recording! returning error\n", This);
2129 return D3DERR_INVALIDCALL;
2132 /* Allocate Storage */
2133 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2134 This->isRecordingState = TRUE;
2135 This->UpdateStateBlock = memory;
2137 return D3D_OK;
2139 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2141 ICOM_THIS(IDirect3DDevice8Impl,iface);
2142 TRACE("(%p)\n", This);
2144 if (!This->isRecordingState) {
2145 TRACE("(%p) not recording! returning error\n", This);
2146 return D3DERR_INVALIDCALL;
2149 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2150 *pToken = (DWORD) This->UpdateStateBlock;
2151 This->isRecordingState = FALSE;
2152 This->UpdateStateBlock = &This->StateBlock;
2154 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2155 return D3D_OK;
2158 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2160 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2161 int i,j;
2163 ICOM_THIS(IDirect3DDevice8Impl,iface);
2164 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2166 /* FIXME: Only apply applicable states not all states */
2168 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2170 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2172 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2173 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2174 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2175 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2178 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2179 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2181 /* TODO: Vertex Shader Constants */
2184 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2186 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2187 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->PixelShader);
2189 /* TODO: Pixel Shader Constants */
2192 /* Others + Render & Texture */
2193 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2194 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2195 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2196 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2199 if (pSB->Set.Indices && pSB->Changed.Indices)
2200 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2202 if (pSB->Set.material && pSB->Changed.material)
2203 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2205 if (pSB->Set.viewport && pSB->Changed.viewport)
2206 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2208 for (i=0; i<MAX_STREAMS; i++) {
2209 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2210 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2213 for (i=0; i<MAX_CLIPPLANES; i++) {
2214 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2215 float clip[4];
2217 clip[0] = pSB->clipplane[i][0];
2218 clip[1] = pSB->clipplane[i][1];
2219 clip[2] = pSB->clipplane[i][2];
2220 clip[3] = pSB->clipplane[i][3];
2221 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2225 /* Render */
2226 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2228 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2229 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2233 /* Texture */
2234 for (j=0; j<8; j++) {
2235 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2237 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i])
2238 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2243 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2245 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2246 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2247 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2251 for (j=0; j<8; i++) {
2252 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2254 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2255 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2256 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2260 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2262 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2263 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2264 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2268 for (j=0; j<8; i++) {
2269 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2271 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2272 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2273 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2278 } else {
2279 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2281 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2282 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2284 return D3D_OK;
2286 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2288 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2290 ICOM_THIS(IDirect3DDevice8Impl,iface);
2292 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2294 /* If not recorded, then update can just recapture */
2295 if (updateBlock->blockType != D3DSBT_RECORDED) {
2296 DWORD tmpToken;
2297 STATEBLOCK *tmpBlock;
2298 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2299 tmpBlock = (STATEBLOCK *)tmpToken;
2300 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2301 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2303 /* FIXME: This will record states of new lights! May need to have and save set_lights
2304 across this action */
2306 } else {
2307 int i,j;
2309 /* Recorded => Only update 'changed' values */
2310 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2311 updateBlock->VertexShader = This->StateBlock.VertexShader;
2312 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2315 /* TODO: Vertex Shader Constants */
2317 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2318 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2319 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2320 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2323 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2324 &updateBlock->lights[i],
2325 sizeof(D3DLIGHT8)) != 0) {
2326 TRACE("Updating lights for light %d\n", i);
2327 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2331 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2332 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2333 updateBlock->lights[i] = This->StateBlock.lights[i];
2334 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2337 /* TODO: Pixel Shader Constants */
2339 /* Others + Render & Texture */
2340 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2341 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2342 &updateBlock->transforms[i],
2343 sizeof(D3DMATRIX)) != 0) {
2344 TRACE("Updating transform %d\n", i);
2345 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2349 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2350 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2351 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2352 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2353 updateBlock->pIndexData = This->StateBlock.pIndexData;
2354 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2357 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2358 &updateBlock->material,
2359 sizeof(D3DMATERIAL8)) != 0) {
2360 TRACE("Updating material\n");
2361 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2364 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2365 &updateBlock->viewport,
2366 sizeof(D3DVIEWPORT8)) != 0) {
2367 TRACE("Updating viewport\n");
2368 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2371 for (i=0; i<MAX_STREAMS; i++) {
2372 if (updateBlock->Set.stream_source[i] &&
2373 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2374 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2375 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2376 This->StateBlock.stream_stride[i]);
2377 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2378 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2382 for (i=0; i<MAX_CLIPPLANES; i++) {
2383 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2384 &updateBlock->clipplane[i],
2385 sizeof(updateBlock->clipplane)) != 0) {
2387 TRACE("Updating clipplane %d\n", i);
2388 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2389 sizeof(updateBlock->clipplane));
2393 /* Render */
2394 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2396 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
2397 This->StateBlock.renderstate[i])) {
2398 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2399 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2403 /* Texture */
2404 for (j=0; j<8; j++) {
2405 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2407 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
2408 This->StateBlock.texture_state[j][i])) {
2409 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
2410 updateBlock->texture_state[j][i]);
2411 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
2418 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2420 return D3D_OK;
2422 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2423 ICOM_THIS(IDirect3DDevice8Impl,iface);
2424 TRACE("(%p) : freeing token %lx\n", This, Token);
2425 HeapFree(GetProcessHeap(), 0, (void *)Token);
2426 return D3D_OK;
2429 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type,DWORD* pToken) {
2430 void *memory;
2431 STATEBLOCK *s;
2432 int i,j;
2434 ICOM_THIS(IDirect3DDevice8Impl,iface);
2435 TRACE("(%p) : for type %d\n", This, Type);
2437 /* Allocate Storage */
2438 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2439 if (memory) memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2440 *pToken = (DWORD) memory;
2441 s = memory;
2442 s->blockType = Type;
2444 TRACE("Updating changed flags appropriate for type %d\n", Type);
2446 if (Type == D3DSBT_ALL) {
2447 TRACE("ALL => Pretend everything has changed\n");
2448 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2450 } else if (Type == D3DSBT_PIXELSTATE) {
2452 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2454 /* TODO: Pixel Shader Constants */
2455 s->Changed.pixelShader = TRUE;
2456 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2457 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2459 for (j=0; j<8; i++) {
2460 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2461 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2465 } else if (Type == D3DSBT_VERTEXSTATE) {
2467 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2469 /* TODO: Vertex Shader Constants */
2470 s->Changed.vertexShader = TRUE;
2472 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2473 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2475 for (j=0; j<8; i++) {
2476 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2477 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2481 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2482 s->Changed.lightEnable[i] = TRUE;
2483 s->Changed.lights[i] = TRUE;
2486 } else {
2487 FIXME("Unrecognized state block type %d\n", Type);
2489 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2490 return D3D_OK;
2493 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2494 ICOM_THIS(IDirect3DDevice8Impl,iface);
2495 FIXME("(%p) : stub\n", This); return D3D_OK;
2497 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2498 ICOM_THIS(IDirect3DDevice8Impl,iface);
2499 FIXME("(%p) : stub\n", This); return D3D_OK;
2501 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2502 ICOM_THIS(IDirect3DDevice8Impl,iface);
2503 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2504 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
2505 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2506 return D3D_OK;
2508 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2510 IDirect3DBaseTexture8 *oldTxt;
2512 ICOM_THIS(IDirect3DDevice8Impl,iface);
2513 D3DRESOURCETYPE textureType;
2515 oldTxt = This->StateBlock.textures[Stage];
2516 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2518 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2519 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2520 This->UpdateStateBlock->textures[Stage] = pTexture;
2522 /* Handle recording of state blocks */
2523 if (This->isRecordingState) {
2524 TRACE("Recording... not performing anything\n");
2525 return D3D_OK;
2528 /* Make appropriate texture active */
2529 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2530 checkGLcall("glActiveTextureARB");
2532 /* Decrement the count of the previous texture */
2533 if (oldTxt != NULL) {
2534 IDirect3DBaseTexture8Impl_Release(oldTxt);
2537 if (pTexture) {
2538 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
2540 /* Now setup the texture appropraitly */
2541 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2543 if (textureType == D3DRTYPE_TEXTURE) {
2544 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
2545 int i;
2547 /* Standard 2D texture */
2548 TRACE("Standard 2d texture\n");
2549 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
2551 /* for (i=0; i<pTexture2->levels; i++) { */
2552 i=0;
2555 if (pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2556 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2557 checkGLcall("glBindTexture");
2558 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2559 } else {
2561 if (pTexture2->surfaces[i]->textureName == 0) {
2562 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
2563 checkGLcall("glGenTextures");
2564 TRACE("Texture %p given name %d\n", pTexture2->surfaces[i], pTexture2->surfaces[i]->textureName);
2567 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
2568 checkGLcall("glBindTexture");
2570 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2571 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
2572 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2573 pTexture2->surfaces[i]->allocatedMemory);
2574 glTexImage2D(GL_TEXTURE_2D, i,
2575 fmt2glintFmt(pTexture2->format),
2576 pTexture2->surfaces[i]->myDesc.Width,
2577 pTexture2->surfaces[i]->myDesc.Height,
2579 fmt2glFmt(pTexture2->format),
2580 fmt2glType(pTexture2->format),
2581 pTexture2->surfaces[i]->allocatedMemory
2583 checkGLcall("glTexImage2D");
2586 * The following enable things to work but I dont think
2587 * they all go here - FIXME! @@@
2589 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2590 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2591 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2592 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2594 pTexture2->Dirty = FALSE;
2599 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
2600 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
2601 int i;
2603 /* Standard 3D (volume) texture */
2604 TRACE("Standard 3d texture\n");
2605 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
2607 /* for (i=0; i<pTexture2->levels; i++) { */
2608 i=0;
2611 if (pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
2612 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2613 checkGLcall("glBindTexture");
2614 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2615 } else {
2617 if (pTexture2->volumes[i]->textureName == 0) {
2618 glGenTextures(1, &pTexture2->volumes[i]->textureName);
2619 checkGLcall("glGenTextures");
2620 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
2623 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
2624 checkGLcall("glBindTexture");
2626 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
2627 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
2628 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
2629 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
2630 pTexture2->volumes[i]->allocatedMemory);
2631 glTexImage3D(GL_TEXTURE_3D, i,
2632 fmt2glintFmt(pTexture2->format),
2633 pTexture2->volumes[i]->myDesc.Width,
2634 pTexture2->volumes[i]->myDesc.Height,
2635 pTexture2->volumes[i]->myDesc.Depth,
2637 fmt2glFmt(pTexture2->format),
2638 fmt2glType(pTexture2->format),
2639 pTexture2->volumes[i]->allocatedMemory
2641 checkGLcall("glTexImage3D");
2644 * The following enable things to work but I dont think
2645 * they all go here - FIXME! @@@
2647 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT );
2648 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT );
2649 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT );
2650 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
2651 glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
2653 pTexture2->Dirty = FALSE;
2657 } else {
2658 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
2660 } else {
2661 TRACE("Setting to no texture (ie default texture)\n");
2662 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
2663 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
2664 checkGLcall("glBindTexture");
2665 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
2668 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
2669 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
2670 setupTextureStates (iface, Stage);
2672 return D3D_OK;
2675 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
2676 ICOM_THIS(IDirect3DDevice8Impl,iface);
2677 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
2678 *pValue = This->StateBlock.texture_state[Stage][Type];
2679 return D3D_OK;
2682 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
2683 ICOM_THIS(IDirect3DDevice8Impl,iface);
2685 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2687 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
2689 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
2690 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
2691 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
2693 /* Handle recording of state blocks */
2694 if (This->isRecordingState) {
2695 TRACE("Recording... not performing anything\n");
2696 return D3D_OK;
2699 /* Make appropriate texture active */
2700 TRACE("Activating appropriate texture state %ld\n", Stage);
2701 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2702 checkGLcall("glActiveTextureARB");
2704 switch (Type) {
2706 case D3DTSS_MINFILTER :
2707 if (Value == D3DTEXF_POINT) {
2708 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2709 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_NEAREST");
2710 } else if (Value == D3DTEXF_LINEAR) {
2711 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2712 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, GL_LINEAR");
2713 } else {
2714 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", Value);
2716 break;
2719 case D3DTSS_MAGFILTER :
2720 if (Value == D3DTEXF_POINT) {
2721 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2722 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
2723 } else if (Value == D3DTEXF_LINEAR) {
2724 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2725 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
2726 } else {
2727 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
2729 break;
2731 case D3DTSS_COLORARG0 :
2732 case D3DTSS_ALPHAARG0 :
2733 /* FIXME: Mesa seems to struggle setting these at the moment */
2734 break;
2736 case D3DTSS_COLORARG1 :
2737 case D3DTSS_COLORARG2 :
2738 case D3DTSS_ALPHAARG1 :
2739 case D3DTSS_ALPHAARG2 :
2741 BOOL isAlphaReplicate = FALSE;
2742 BOOL isComplement = FALSE;
2743 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
2744 int operand= GL_SRC_COLOR;
2745 int source = GL_TEXTURE;
2747 /* Catch alpha replicate */
2748 if (Value & D3DTA_ALPHAREPLICATE) {
2749 Value = Value & ~D3DTA_ALPHAREPLICATE;
2750 isAlphaReplicate = TRUE;
2753 /* Catch Complement */
2754 if (Value & D3DTA_COMPLEMENT) {
2755 Value = Value & ~D3DTA_COMPLEMENT;
2756 isComplement = TRUE;
2759 /* Calculate the operand */
2760 if (isAlphaReplicate && !isComplement) {
2761 operand = GL_SRC_ALPHA;
2762 } else if (isAlphaReplicate && isComplement) {
2763 operand = GL_ONE_MINUS_SRC_ALPHA;
2764 } else if (isComplement) {
2765 if (isAlphaArg) {
2766 operand = GL_ONE_MINUS_SRC_COLOR;
2767 } else {
2768 operand = GL_ONE_MINUS_SRC_ALPHA;
2770 } else {
2771 if (isAlphaArg) {
2772 operand = GL_SRC_ALPHA;
2773 } else {
2774 operand = GL_SRC_COLOR;
2778 /* Calculate the source */
2779 switch (Value) {
2780 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
2781 break;
2782 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
2783 break;
2784 case D3DTA_TEXTURE: source = GL_TEXTURE;
2785 break;
2786 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
2787 break;
2789 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
2790 isnt supported until base GL supports it
2791 There is no concept of temp registers as far as I can tell */
2793 default:
2794 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
2797 if (isAlphaArg) {
2798 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
2799 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
2800 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
2801 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
2802 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
2803 } else {
2804 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
2805 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
2806 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
2807 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
2808 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
2811 break;
2813 case D3DTSS_ALPHAOP :
2814 case D3DTSS_COLOROP :
2817 int Scale = 1;
2818 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
2820 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
2821 /* TODO: Disable by making this and all later levels disabled */
2822 glDisable(GL_TEXTURE_1D);
2823 checkGLcall("Disable GL_TEXTURE_1D");
2824 glDisable(GL_TEXTURE_2D);
2825 checkGLcall("Disable GL_TEXTURE_2D");
2826 glDisable(GL_TEXTURE_3D);
2827 checkGLcall("Disable GL_TEXTURE_3D");
2828 } else {
2830 /* Enable only the appropriate texture dimension */
2831 if (Type==D3DTSS_ALPHAOP && Value != D3DTOP_DISABLE) {
2832 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
2833 glEnable(GL_TEXTURE_1D);
2834 checkGLcall("Enable GL_TEXTURE_1D");
2835 } else {
2836 glDisable(GL_TEXTURE_1D);
2837 checkGLcall("Disable GL_TEXTURE_1D");
2839 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
2840 glEnable(GL_TEXTURE_2D);
2841 checkGLcall("Enable GL_TEXTURE_2D");
2842 } else {
2843 glDisable(GL_TEXTURE_2D);
2844 checkGLcall("Disable GL_TEXTURE_2D");
2846 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
2847 glEnable(GL_TEXTURE_3D);
2848 checkGLcall("Enable GL_TEXTURE_3D");
2849 } else {
2850 glDisable(GL_TEXTURE_3D);
2851 checkGLcall("Disable GL_TEXTURE_3D");
2855 /* Now set up the operand correctly */
2856 switch (Value) {
2857 case D3DTOP_DISABLE :
2858 /* Contrary to the docs, alpha can be disabled when colorop is enabled
2859 and it works, so ignore this op */
2860 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
2861 break;
2863 case D3DTOP_SELECTARG1 :
2864 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
2865 break;
2867 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
2868 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
2869 case D3DTOP_MODULATE :
2871 /* Correct scale */
2872 if (Type == D3DTSS_ALPHAOP) glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
2873 else glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
2874 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
2875 break;
2877 case D3DTOP_ADD :
2878 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
2879 break;
2881 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
2882 case D3DTOP_ADDSIGNED :
2883 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
2884 break;
2886 case D3DTOP_DOTPRODUCT3 :
2887 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
2888 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
2889 break;*/
2891 case D3DTOP_SUBTRACT :
2892 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
2893 case D3DTOP_SELECTARG2 :
2894 /* GL_REPLACE, swap args 0 and 1? */
2895 case D3DTOP_ADDSMOOTH :
2896 case D3DTOP_BLENDDIFFUSEALPHA :
2897 case D3DTOP_BLENDTEXTUREALPHA :
2898 case D3DTOP_BLENDFACTORALPHA :
2899 case D3DTOP_BLENDTEXTUREALPHAPM :
2900 case D3DTOP_BLENDCURRENTALPHA :
2901 case D3DTOP_PREMODULATE :
2902 case D3DTOP_MODULATEALPHA_ADDCOLOR :
2903 case D3DTOP_MODULATECOLOR_ADDALPHA :
2904 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
2905 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
2906 case D3DTOP_BUMPENVMAP :
2907 case D3DTOP_BUMPENVMAPLUMINANCE :
2908 case D3DTOP_MULTIPLYADD :
2909 case D3DTOP_LERP :
2910 default:
2911 FIXME("Unhandled texture operation %ld\n", Value);
2914 break;
2917 /* Unhandled */
2918 case D3DTSS_BUMPENVMAT00 :
2919 case D3DTSS_BUMPENVMAT01 :
2920 case D3DTSS_BUMPENVMAT10 :
2921 case D3DTSS_BUMPENVMAT11 :
2922 case D3DTSS_TEXCOORDINDEX :
2923 case D3DTSS_ADDRESSU :
2924 case D3DTSS_ADDRESSV :
2925 case D3DTSS_BORDERCOLOR :
2926 case D3DTSS_MIPFILTER :
2927 case D3DTSS_MIPMAPLODBIAS :
2928 case D3DTSS_MAXMIPLEVEL :
2929 case D3DTSS_MAXANISOTROPY :
2930 case D3DTSS_BUMPENVLSCALE :
2931 case D3DTSS_BUMPENVLOFFSET :
2932 case D3DTSS_TEXTURETRANSFORMFLAGS :
2933 case D3DTSS_ADDRESSW :
2934 case D3DTSS_RESULTARG :
2935 default:
2936 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
2937 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
2939 return D3D_OK;
2941 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
2942 ICOM_THIS(IDirect3DDevice8Impl,iface);
2943 FIXME("(%p) : stub\n", This); return D3D_OK;
2945 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
2946 ICOM_THIS(IDirect3DDevice8Impl,iface);
2947 FIXME("(%p) : stub\n", This); return D3D_OK;
2949 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
2950 ICOM_THIS(IDirect3DDevice8Impl,iface);
2951 FIXME("(%p) : stub\n", This); return D3D_OK;
2953 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
2954 ICOM_THIS(IDirect3DDevice8Impl,iface);
2955 FIXME("(%p) : stub\n", This); return D3D_OK;
2957 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
2958 ICOM_THIS(IDirect3DDevice8Impl,iface);
2959 FIXME("(%p) : stub\n", This); return D3D_OK;
2961 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
2962 ICOM_THIS(IDirect3DDevice8Impl,iface);
2963 FIXME("(%p) : stub\n", This); return D3D_OK;
2965 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
2967 IDirect3DVertexBuffer8 *pVB;
2968 D3DVERTEXBUFFER_DESC VtxBufDsc;
2970 ICOM_THIS(IDirect3DDevice8Impl,iface);
2971 pVB = This->StateBlock.stream_source[0];
2973 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
2975 IDirect3DVertexBuffer8Impl_GetDesc(pVB, &VtxBufDsc);
2976 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
2977 VtxBufDsc.FVF, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL);
2979 return D3D_OK;
2981 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
2982 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
2983 UINT idxStride = 2;
2984 IDirect3DIndexBuffer8 *pIB;
2985 IDirect3DVertexBuffer8 *pVB;
2986 D3DINDEXBUFFER_DESC IdxBufDsc;
2987 D3DVERTEXBUFFER_DESC VtxBufDsc;
2989 ICOM_THIS(IDirect3DDevice8Impl,iface);
2990 pIB = This->StateBlock.pIndexData;
2991 pVB = This->StateBlock.stream_source[0];
2993 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
2994 minIndex, NumVertices, startIndex, primCount);
2996 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
2997 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
2998 idxStride = 2;
2999 } else {
3000 idxStride = 4;
3003 IDirect3DVertexBuffer8Impl_GetDesc(pVB, &VtxBufDsc);
3004 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, VtxBufDsc.FVF, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3005 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory);
3007 return D3D_OK;
3009 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3010 ICOM_THIS(IDirect3DDevice8Impl,iface);
3012 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3014 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3016 This->StateBlock.stream_source[0] = NULL;
3017 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3018 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3019 0, 0, 0, NULL);
3020 This->StateBlock.stream_stride[0] = 0;
3022 /*stream zero settings set to null at end */
3023 return D3D_OK;
3025 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3026 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3027 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3028 UINT VertexStreamZeroStride) {
3029 int idxStride;
3030 ICOM_THIS(IDirect3DDevice8Impl,iface);
3031 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3032 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3034 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3035 if (IndexDataFormat == D3DFMT_INDEX16) {
3036 idxStride = 2;
3037 } else {
3038 idxStride = 4;
3041 This->StateBlock.stream_source[0] = NULL;
3042 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3043 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3044 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData);
3046 /*stream zero settings set to null at end */
3047 This->StateBlock.stream_stride[0] = 0;
3048 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3050 return D3D_OK;
3052 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3053 ICOM_THIS(IDirect3DDevice8Impl,iface);
3054 FIXME("(%p) : stub\n", This); return D3D_OK;
3056 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) {
3057 ICOM_THIS(IDirect3DDevice8Impl,iface);
3058 FIXME("(%p) : stub\n", This); return D3D_OK;
3060 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3061 ICOM_THIS(IDirect3DDevice8Impl,iface);
3063 This->UpdateStateBlock->VertexShader = Handle;
3064 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3065 This->UpdateStateBlock->Set.vertexShader = TRUE;
3067 /* Handle recording of state blocks */
3068 if (This->isRecordingState) {
3069 TRACE("Recording... not performing anything\n");
3070 return D3D_OK;
3073 if (Handle <= VS_HIGHESTFIXEDFXF) {
3074 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3075 return D3D_OK;
3076 } else {
3077 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3078 return D3D_OK;
3081 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3082 ICOM_THIS(IDirect3DDevice8Impl,iface);
3083 TRACE("(%p) = %ld\n", This, This->StateBlock.VertexShader);
3084 *pHandle = This->StateBlock.VertexShader;
3085 return D3D_OK;
3088 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3089 ICOM_THIS(IDirect3DDevice8Impl,iface);
3090 FIXME("(%p) : stub\n", This); return D3D_OK;
3092 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3093 ICOM_THIS(IDirect3DDevice8Impl,iface);
3094 FIXME("(%p) : stub\n", This); return D3D_OK;
3096 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3097 ICOM_THIS(IDirect3DDevice8Impl,iface);
3098 FIXME("(%p) : stub\n", This); return D3D_OK;
3100 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3101 ICOM_THIS(IDirect3DDevice8Impl,iface);
3102 FIXME("(%p) : stub\n", This); return D3D_OK;
3104 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3105 ICOM_THIS(IDirect3DDevice8Impl,iface);
3106 FIXME("(%p) : stub\n", This); return D3D_OK;
3109 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3111 IDirect3DIndexBuffer8 *oldIdxs;
3113 ICOM_THIS(IDirect3DDevice8Impl,iface);
3114 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3115 oldIdxs = This->StateBlock.pIndexData;
3117 This->UpdateStateBlock->Changed.Indices = TRUE;
3118 This->UpdateStateBlock->Set.Indices = TRUE;
3119 This->UpdateStateBlock->pIndexData = pIndexData;
3120 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3122 /* Handle recording of state blocks */
3123 if (This->isRecordingState) {
3124 TRACE("Recording... not performing anything\n");
3125 return D3D_OK;
3128 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3129 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3130 return D3D_OK;
3132 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3133 ICOM_THIS(IDirect3DDevice8Impl,iface);
3134 FIXME("(%p) : stub\n", This);
3136 *ppIndexData = This->StateBlock.pIndexData;
3137 /* up ref count on ppindexdata */
3138 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3139 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3141 return D3D_OK;
3143 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction,DWORD* pHandle) {
3144 ICOM_THIS(IDirect3DDevice8Impl,iface);
3145 FIXME("(%p) : stub\n", This); return D3D_OK;
3147 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3148 ICOM_THIS(IDirect3DDevice8Impl,iface);
3150 This->UpdateStateBlock->PixelShader = Handle;
3151 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3152 This->UpdateStateBlock->Set.pixelShader = TRUE;
3154 /* Handle recording of state blocks */
3155 if (This->isRecordingState) {
3156 TRACE("Recording... not performing anything\n");
3157 return D3D_OK;
3160 /* FIXME: Quieten when not being used */
3161 if (Handle != 0) {
3162 FIXME("(%p) : stub %ld\n", This, Handle);
3163 } else {
3164 TRACE("(%p) : stub %ld\n", This, Handle);
3167 return D3D_OK;
3169 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3170 ICOM_THIS(IDirect3DDevice8Impl,iface);
3171 TRACE("(%p) : returning %ld\n", This, This->StateBlock.PixelShader);
3172 *pHandle = This->StateBlock.PixelShader;
3173 return D3D_OK;
3176 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3177 ICOM_THIS(IDirect3DDevice8Impl,iface);
3178 FIXME("(%p) : stub\n", This); return D3D_OK;
3180 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData,DWORD ConstantCount) {
3181 ICOM_THIS(IDirect3DDevice8Impl,iface);
3182 FIXME("(%p) : stub\n", This); return D3D_OK;
3184 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData,DWORD ConstantCount) {
3185 ICOM_THIS(IDirect3DDevice8Impl,iface);
3186 FIXME("(%p) : stub\n", This); return D3D_OK;
3188 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle,void* pData,DWORD* pSizeOfData) {
3189 ICOM_THIS(IDirect3DDevice8Impl,iface);
3190 FIXME("(%p) : stub\n", This); return D3D_OK;
3192 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3193 ICOM_THIS(IDirect3DDevice8Impl,iface);
3194 FIXME("(%p) : stub\n", This); return D3D_OK;
3196 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3197 ICOM_THIS(IDirect3DDevice8Impl,iface);
3198 FIXME("(%p) : stub\n", This); return D3D_OK;
3200 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3201 ICOM_THIS(IDirect3DDevice8Impl,iface);
3202 FIXME("(%p) : stub\n", This); return D3D_OK;
3205 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3206 IDirect3DVertexBuffer8 *oldSrc;
3207 ICOM_THIS(IDirect3DDevice8Impl,iface);
3209 oldSrc = This->StateBlock.stream_source[StreamNumber];
3210 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3212 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3213 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3214 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3215 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3217 /* Handle recording of state blocks */
3218 if (This->isRecordingState) {
3219 TRACE("Recording... not performing anything\n");
3220 return D3D_OK;
3223 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3224 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3225 return D3D_OK;
3227 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3228 ICOM_THIS(IDirect3DDevice8Impl,iface);
3229 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3230 *pStream = This->StateBlock.stream_source[StreamNumber];
3231 *pStride = This->StateBlock.stream_stride[StreamNumber];
3232 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3233 return D3D_OK;
3237 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3239 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3240 IDirect3DDevice8Impl_QueryInterface,
3241 IDirect3DDevice8Impl_AddRef,
3242 IDirect3DDevice8Impl_Release,
3243 IDirect3DDevice8Impl_TestCooperativeLevel,
3244 IDirect3DDevice8Impl_GetAvailableTextureMem,
3245 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3246 IDirect3DDevice8Impl_GetDirect3D,
3247 IDirect3DDevice8Impl_GetDeviceCaps,
3248 IDirect3DDevice8Impl_GetDisplayMode,
3249 IDirect3DDevice8Impl_GetCreationParameters,
3250 IDirect3DDevice8Impl_SetCursorProperties,
3251 IDirect3DDevice8Impl_SetCursorPosition,
3252 IDirect3DDevice8Impl_ShowCursor,
3253 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3254 IDirect3DDevice8Impl_Reset,
3255 IDirect3DDevice8Impl_Present,
3256 IDirect3DDevice8Impl_GetBackBuffer,
3257 IDirect3DDevice8Impl_GetRasterStatus,
3258 IDirect3DDevice8Impl_SetGammaRamp,
3259 IDirect3DDevice8Impl_GetGammaRamp,
3260 IDirect3DDevice8Impl_CreateTexture,
3261 IDirect3DDevice8Impl_CreateVolumeTexture,
3262 IDirect3DDevice8Impl_CreateCubeTexture,
3263 IDirect3DDevice8Impl_CreateVertexBuffer,
3264 IDirect3DDevice8Impl_CreateIndexBuffer,
3265 IDirect3DDevice8Impl_CreateRenderTarget,
3266 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3267 IDirect3DDevice8Impl_CreateImageSurface,
3268 IDirect3DDevice8Impl_CopyRects,
3269 IDirect3DDevice8Impl_UpdateTexture,
3270 IDirect3DDevice8Impl_GetFrontBuffer,
3271 IDirect3DDevice8Impl_SetRenderTarget,
3272 IDirect3DDevice8Impl_GetRenderTarget,
3273 IDirect3DDevice8Impl_GetDepthStencilSurface,
3274 IDirect3DDevice8Impl_BeginScene,
3275 IDirect3DDevice8Impl_EndScene,
3276 IDirect3DDevice8Impl_Clear,
3277 IDirect3DDevice8Impl_SetTransform,
3278 IDirect3DDevice8Impl_GetTransform,
3279 IDirect3DDevice8Impl_MultiplyTransform,
3280 IDirect3DDevice8Impl_SetViewport,
3281 IDirect3DDevice8Impl_GetViewport,
3282 IDirect3DDevice8Impl_SetMaterial,
3283 IDirect3DDevice8Impl_GetMaterial,
3284 IDirect3DDevice8Impl_SetLight,
3285 IDirect3DDevice8Impl_GetLight,
3286 IDirect3DDevice8Impl_LightEnable,
3287 IDirect3DDevice8Impl_GetLightEnable,
3288 IDirect3DDevice8Impl_SetClipPlane,
3289 IDirect3DDevice8Impl_GetClipPlane,
3290 IDirect3DDevice8Impl_SetRenderState,
3291 IDirect3DDevice8Impl_GetRenderState,
3292 IDirect3DDevice8Impl_BeginStateBlock,
3293 IDirect3DDevice8Impl_EndStateBlock,
3294 IDirect3DDevice8Impl_ApplyStateBlock,
3295 IDirect3DDevice8Impl_CaptureStateBlock,
3296 IDirect3DDevice8Impl_DeleteStateBlock,
3297 IDirect3DDevice8Impl_CreateStateBlock,
3298 IDirect3DDevice8Impl_SetClipStatus,
3299 IDirect3DDevice8Impl_GetClipStatus,
3300 IDirect3DDevice8Impl_GetTexture,
3301 IDirect3DDevice8Impl_SetTexture,
3302 IDirect3DDevice8Impl_GetTextureStageState,
3303 IDirect3DDevice8Impl_SetTextureStageState,
3304 IDirect3DDevice8Impl_ValidateDevice,
3305 IDirect3DDevice8Impl_GetInfo,
3306 IDirect3DDevice8Impl_SetPaletteEntries,
3307 IDirect3DDevice8Impl_GetPaletteEntries,
3308 IDirect3DDevice8Impl_SetCurrentTexturePalette,
3309 IDirect3DDevice8Impl_GetCurrentTexturePalette,
3310 IDirect3DDevice8Impl_DrawPrimitive,
3311 IDirect3DDevice8Impl_DrawIndexedPrimitive,
3312 IDirect3DDevice8Impl_DrawPrimitiveUP,
3313 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
3314 IDirect3DDevice8Impl_ProcessVertices,
3315 IDirect3DDevice8Impl_CreateVertexShader,
3316 IDirect3DDevice8Impl_SetVertexShader,
3317 IDirect3DDevice8Impl_GetVertexShader,
3318 IDirect3DDevice8Impl_DeleteVertexShader,
3319 IDirect3DDevice8Impl_SetVertexShaderConstant,
3320 IDirect3DDevice8Impl_GetVertexShaderConstant,
3321 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
3322 IDirect3DDevice8Impl_GetVertexShaderFunction,
3323 IDirect3DDevice8Impl_SetStreamSource,
3324 IDirect3DDevice8Impl_GetStreamSource,
3325 IDirect3DDevice8Impl_SetIndices,
3326 IDirect3DDevice8Impl_GetIndices,
3327 IDirect3DDevice8Impl_CreatePixelShader,
3328 IDirect3DDevice8Impl_SetPixelShader,
3329 IDirect3DDevice8Impl_GetPixelShader,
3330 IDirect3DDevice8Impl_DeletePixelShader,
3331 IDirect3DDevice8Impl_SetPixelShaderConstant,
3332 IDirect3DDevice8Impl_GetPixelShaderConstant,
3333 IDirect3DDevice8Impl_GetPixelShaderFunction,
3334 IDirect3DDevice8Impl_DrawRectPatch,
3335 IDirect3DDevice8Impl_DrawTriPatch,
3336 IDirect3DDevice8Impl_DeletePatch
3339 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
3340 D3DLINEPATTERN lp;
3341 int i;
3343 ICOM_THIS(IDirect3DDevice8Impl,iface);
3345 /* Note this may have a large overhead but it should only be executed
3346 once, in order to initialize the complete state of the device and
3347 all opengl equivalents */
3348 TRACE("-----------------------> Setting up device defaults...\n");
3349 This->StateBlock.blockType = D3DSBT_ALL;
3351 /* FIXME: Set some of the defaults for lights, transforms etc */
3352 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
3353 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
3354 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
3356 /* Render states: */
3357 if (This->PresentParms.EnableAutoDepthStencil) {
3358 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
3359 } else {
3360 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
3362 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
3363 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
3364 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
3365 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
3366 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
3367 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
3368 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
3369 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
3370 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
3371 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3372 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
3373 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
3374 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
3375 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
3376 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
3377 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
3378 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
3379 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
3380 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3381 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
3382 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
3383 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
3384 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
3385 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
3386 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
3387 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
3388 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
3389 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
3390 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
3391 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
3392 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
3393 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
3394 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
3395 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
3396 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
3397 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
3398 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
3399 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
3400 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
3401 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
3402 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
3403 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
3404 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
3405 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
3406 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
3407 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3408 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
3409 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
3410 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
3411 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
3412 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
3413 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
3414 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
3415 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
3416 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
3417 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
3418 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
3419 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
3420 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
3421 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
3422 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
3423 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
3424 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
3425 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
3426 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
3427 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
3428 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
3429 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
3430 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
3431 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
3432 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
3433 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
3434 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
3435 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
3436 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
3438 /* Texture Stage States - Put directly into state block, we will call function below */
3439 for (i=0; i<8;i++) {
3440 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
3441 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
3442 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
3443 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
3444 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
3445 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
3446 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
3447 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
3448 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
3449 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
3450 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
3451 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
3452 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
3453 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
3454 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
3455 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
3456 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
3457 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
3458 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
3459 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
3460 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
3461 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
3462 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
3463 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
3464 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
3465 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
3466 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
3469 /* Under DirectX you can have texture stage operations even if no texture is
3470 bound, whereas opengl will only do texture operations when a valid texture is
3471 bound. We emulate this by creating 8 dummy textures and binding them to each
3472 texture stage, but disable all stages by default. Hence if a stage is enabled
3473 then the default texture will kick in until replaced by a SetTexture call */
3474 for (i=0; i<8; i++) {
3475 GLubyte white = 255;
3477 /* Make appropriate texture active */
3478 glActiveTextureARB(GL_TEXTURE0_ARB + i);
3479 checkGLcall("glActiveTextureARB");
3481 /* Generate an opengl texture name */
3482 glGenTextures(1, &This->dummyTextureName[i]);
3483 checkGLcall("glGenTextures");
3484 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
3486 /* Generate a dummy 1d texture */
3487 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
3488 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
3489 checkGLcall("glBindTexture");
3491 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
3492 checkGLcall("glTexImage1D");
3494 /* Reapply all the texture state information to this texture */
3495 setupTextureStates(iface, i);
3498 TRACE("-----------------------> Device defaults now set up...\n");
3503 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
3504 D3DRS_ALPHABLENDENABLE ,
3505 D3DRS_ALPHAFUNC ,
3506 D3DRS_ALPHAREF ,
3507 D3DRS_ALPHATESTENABLE ,
3508 D3DRS_BLENDOP ,
3509 D3DRS_COLORWRITEENABLE ,
3510 D3DRS_DESTBLEND ,
3511 D3DRS_DITHERENABLE ,
3512 D3DRS_EDGEANTIALIAS ,
3513 D3DRS_FILLMODE ,
3514 D3DRS_FOGDENSITY ,
3515 D3DRS_FOGEND ,
3516 D3DRS_FOGSTART ,
3517 D3DRS_LASTPIXEL ,
3518 D3DRS_LINEPATTERN ,
3519 D3DRS_SHADEMODE ,
3520 D3DRS_SRCBLEND ,
3521 D3DRS_STENCILENABLE ,
3522 D3DRS_STENCILFAIL ,
3523 D3DRS_STENCILFUNC ,
3524 D3DRS_STENCILMASK ,
3525 D3DRS_STENCILPASS ,
3526 D3DRS_STENCILREF ,
3527 D3DRS_STENCILWRITEMASK ,
3528 D3DRS_STENCILZFAIL ,
3529 D3DRS_TEXTUREFACTOR ,
3530 D3DRS_WRAP0 ,
3531 D3DRS_WRAP1 ,
3532 D3DRS_WRAP2 ,
3533 D3DRS_WRAP3 ,
3534 D3DRS_WRAP4 ,
3535 D3DRS_WRAP5 ,
3536 D3DRS_WRAP6 ,
3537 D3DRS_WRAP7 ,
3538 D3DRS_ZBIAS ,
3539 D3DRS_ZENABLE ,
3540 D3DRS_ZFUNC ,
3541 D3DRS_ZWRITEENABLE
3544 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
3545 D3DTSS_ADDRESSU ,
3546 D3DTSS_ADDRESSV ,
3547 D3DTSS_ADDRESSW ,
3548 D3DTSS_ALPHAARG0 ,
3549 D3DTSS_ALPHAARG1 ,
3550 D3DTSS_ALPHAARG2 ,
3551 D3DTSS_ALPHAOP ,
3552 D3DTSS_BORDERCOLOR ,
3553 D3DTSS_BUMPENVLOFFSET ,
3554 D3DTSS_BUMPENVLSCALE ,
3555 D3DTSS_BUMPENVMAT00 ,
3556 D3DTSS_BUMPENVMAT01 ,
3557 D3DTSS_BUMPENVMAT10 ,
3558 D3DTSS_BUMPENVMAT11 ,
3559 D3DTSS_COLORARG0 ,
3560 D3DTSS_COLORARG1 ,
3561 D3DTSS_COLORARG2 ,
3562 D3DTSS_COLOROP ,
3563 D3DTSS_MAGFILTER ,
3564 D3DTSS_MAXANISOTROPY ,
3565 D3DTSS_MAXMIPLEVEL ,
3566 D3DTSS_MINFILTER ,
3567 D3DTSS_MIPFILTER ,
3568 D3DTSS_MIPMAPLODBIAS ,
3569 D3DTSS_RESULTARG ,
3570 D3DTSS_TEXCOORDINDEX ,
3571 D3DTSS_TEXTURETRANSFORMFLAGS
3574 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
3575 D3DRS_AMBIENT ,
3576 D3DRS_AMBIENTMATERIALSOURCE ,
3577 D3DRS_CLIPPING ,
3578 D3DRS_CLIPPLANEENABLE ,
3579 D3DRS_COLORVERTEX ,
3580 D3DRS_DIFFUSEMATERIALSOURCE ,
3581 D3DRS_EMISSIVEMATERIALSOURCE ,
3582 D3DRS_FOGDENSITY ,
3583 D3DRS_FOGEND ,
3584 D3DRS_FOGSTART ,
3585 D3DRS_FOGTABLEMODE ,
3586 D3DRS_FOGVERTEXMODE ,
3587 D3DRS_INDEXEDVERTEXBLENDENABLE ,
3588 D3DRS_LIGHTING ,
3589 D3DRS_LOCALVIEWER ,
3590 D3DRS_MULTISAMPLEANTIALIAS ,
3591 D3DRS_MULTISAMPLEMASK ,
3592 D3DRS_NORMALIZENORMALS ,
3593 D3DRS_PATCHEDGESTYLE ,
3594 D3DRS_PATCHSEGMENTS ,
3595 D3DRS_POINTSCALE_A ,
3596 D3DRS_POINTSCALE_B ,
3597 D3DRS_POINTSCALE_C ,
3598 D3DRS_POINTSCALEENABLE ,
3599 D3DRS_POINTSIZE ,
3600 D3DRS_POINTSIZE_MAX ,
3601 D3DRS_POINTSIZE_MIN ,
3602 D3DRS_POINTSPRITEENABLE ,
3603 D3DRS_RANGEFOGENABLE ,
3604 D3DRS_SOFTWAREVERTEXPROCESSING ,
3605 D3DRS_SPECULARMATERIALSOURCE ,
3606 D3DRS_TWEENFACTOR ,
3607 D3DRS_VERTEXBLEND
3610 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
3611 D3DTSS_TEXCOORDINDEX ,
3612 D3DTSS_TEXTURETRANSFORMFLAGS