Change RECT to use LONG to match win32 standard headers and fix format
[wine/multimedia.git] / dlls / d3d8 / device.c
blob77eea5dd1dd27ccba50775f803251fff2dabc5d5
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>
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "wingdi.h"
29 #include "wine/debug.h"
31 #include "d3d8_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
35 /* Some #defines for additional diagnostics */
37 /* Per-vertex trace: */
38 #if 0
39 #define VTRACE(A) TRACE A
40 #else
41 #define VTRACE(A)
42 #endif
45 static VERTEXSHADER8* VertexShaders[64];
46 static PIXELSHADER8* PixelShaders[64];
48 /* CreateVertexShader can return > 0xFFFF */
49 #define VS_HIGHESTFIXEDFXF 0xF0000000
51 /* Used for CreateStateBlock */
52 #define NUM_SAVEDPIXELSTATES_R 38
53 #define NUM_SAVEDPIXELSTATES_T 27
54 #define NUM_SAVEDVERTEXSTATES_R 33
55 #define NUM_SAVEDVERTEXSTATES_T 2
58 * Utility functions or macros
60 #define conv_mat(mat,gl_mat) \
61 do { \
62 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
63 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
64 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
65 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
66 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
67 } while (0)
69 #define VERTEX_SHADER(Handle) \
70 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
72 #define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
75 * Globals
77 extern DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R];
78 extern DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T];
79 extern DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R];
80 extern DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T];
82 static const float idmatrix[16] = {
83 1.0, 0.0, 0.0, 0.0,
84 0.0, 1.0, 0.0, 0.0,
85 0.0, 0.0, 1.0, 0.0,
86 0.0, 0.0, 0.0, 1.0
90 /* Routine common to the draw primitive and draw indexed primitive routines */
91 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
92 int PrimitiveType,
93 long NumPrimitives,
94 BOOL isIndexed,
96 /* For Both:*/
97 D3DFORMAT fvf,
98 const void *vertexBufData,
100 /* for Indexed: */
101 long StartVertexIndex,
102 long StartIdx,
103 short idxBytes,
104 const void *idxData,
105 int minIndex) {
107 int NumVertexes = NumPrimitives;
108 VERTEXSHADER8* vertex_shader = NULL;
109 VSHADERINPUTDATA8 vertex_shader_input;
110 BOOL useVertexShaderFunction = FALSE;
112 ICOM_THIS(IDirect3DDevice8Impl,iface);
114 /* Dont understand how to handle multiple streams, but if a fixed
115 FVF is passed in rather than a handle, it must use stream 0 */
117 if (This->StateBlock.VertexShader > VS_HIGHESTFIXEDFXF) {
118 vertex_shader = VERTEX_SHADER(This->StateBlock.VertexShader);
119 if (NULL == vertex_shader) {
120 ERR("trying to use unitialised vertex shader: %lu\n", This->StateBlock.VertexShader);
121 return ;
123 if (NULL == vertex_shader->function) {
124 TRACE("vertex shader declared without program, using FVF pure mode\n");
125 } else {
126 useVertexShaderFunction = TRUE;
128 fvf = (D3DFORMAT) vertex_shader->fvf;
129 TRACE("vertex shader declared FVF: %lx\n", vertex_shader->fvf);
130 memset(&vertex_shader_input, 0, sizeof(VSHADERINPUTDATA8));
134 int skip = This->StateBlock.stream_stride[0];
135 GLenum primType = GL_POINTS;
136 BOOL normal;
137 BOOL isRHW;
138 BOOL isPtSize;
139 BOOL isDiffuse;
140 BOOL isSpecular;
141 int numBlends;
142 BOOL isLastUByte4;
143 int numTextures;
144 int textureNo;
145 const void *curVtx = NULL;
146 const short *pIdxBufS = NULL;
147 const long *pIdxBufL = NULL;
148 const void *curPos;
149 BOOL isLightingOn = FALSE;
150 BOOL enableTexture = FALSE;
151 int vx_index;
153 float x=0.0, y=0.0, z=0.0; /* x,y,z coordinates */
154 float nx=0.0, ny=0.0, nz=0.0; /* normal x,y,z coordinates */
155 float rhw=0.0; /* rhw */
156 float ptSize=0.0; /* Point size */
157 DWORD diffuseColor=0; /* Diffusre Color */
158 DWORD specularColor=0; /* Specular Color */
160 ENTER_GL();
162 if (isIndexed) {
163 if (idxBytes == 2) pIdxBufS = (short *) idxData;
164 else pIdxBufL = (long *) idxData;
167 /* Check vertex formats expected ? */
168 normal = fvf & D3DFVF_NORMAL;
169 isRHW = fvf & D3DFVF_XYZRHW;
170 numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2; /* WARNING can be < 0 because -2 */
171 isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
172 isPtSize = fvf & D3DFVF_PSIZE;
173 isDiffuse = fvf & D3DFVF_DIFFUSE;
174 isSpecular = fvf & D3DFVF_SPECULAR;
175 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
177 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d)\n",
178 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends);
180 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
181 set by the appropriate render state */
182 if (!normal) {
183 isLightingOn = glIsEnabled(GL_LIGHTING);
184 glDisable(GL_LIGHTING);
185 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
188 if (isRHW) {
189 double height, width, minZ, maxZ;
191 * Already transformed vertex do not need transform
192 * matrices. Reset all matrices to identity.
193 * Leave the default matrix in world mode.
195 glMatrixMode(GL_PROJECTION);
196 checkGLcall("glMatrixMode");
197 glLoadIdentity();
198 checkGLcall("glLoadIdentity");
199 glMatrixMode(GL_MODELVIEW);
200 checkGLcall("glMatrixMode");
201 glLoadIdentity();
202 checkGLcall("glLoadIdentity");
203 height = This->StateBlock.viewport.Height;
204 width = This->StateBlock.viewport.Width;
205 minZ = This->StateBlock.viewport.MinZ;
206 maxZ = This->StateBlock.viewport.MaxZ;
207 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
208 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
209 checkGLcall("glOrtho");
210 } else {
211 glMatrixMode(GL_PROJECTION);
212 checkGLcall("glMatrixMode");
213 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
214 checkGLcall("glLoadMatrixf");
215 glMatrixMode(GL_MODELVIEW);
216 checkGLcall("glMatrixMode");
217 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
218 checkGLcall("glLoadMatrixf");
219 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
220 checkGLcall("glMultMatrixf");
223 /* Set OpenGL to the appropriate Primitive Type */
224 switch (PrimitiveType) {
225 case D3DPT_POINTLIST:
226 TRACE("POINTS\n");
227 primType = GL_POINTS;
228 NumVertexes = NumPrimitives;
229 break;
231 case D3DPT_LINELIST:
232 TRACE("LINES\n");
233 primType = GL_LINES;
234 NumVertexes = NumPrimitives * 2;
235 break;
237 case D3DPT_LINESTRIP:
238 TRACE("LINE_STRIP\n");
239 primType = GL_LINE_STRIP;
240 NumVertexes = NumPrimitives + 1;
241 break;
243 case D3DPT_TRIANGLELIST:
244 TRACE("TRIANGLES\n");
245 primType = GL_TRIANGLES;
246 NumVertexes = NumPrimitives * 3;
247 break;
249 case D3DPT_TRIANGLESTRIP:
250 TRACE("TRIANGLE_STRIP\n");
251 primType = GL_TRIANGLE_STRIP;
252 NumVertexes = NumPrimitives + 2;
253 break;
255 case D3DPT_TRIANGLEFAN:
256 TRACE("TRIANGLE_FAN\n");
257 primType = GL_TRIANGLE_FAN;
258 NumVertexes = NumPrimitives + 2;
259 break;
261 default:
262 FIXME("Unhandled primitive\n");
263 break;
266 /* Fixme, Ideally, only use this per-vertex code for software HAL
267 but until opengl supports all the functions returned to setup
268 vertex arrays, we need to drop down to the slow mechanism for
269 certain functions */
271 if (isPtSize || isDiffuse || useVertexShaderFunction==TRUE || (numBlends > 0)) {
272 TRACE("Using slow per-vertex code\n");
274 /* Enable this one to be able to debug what is going on, but it is slower
275 than the pointer/array version */
276 VTRACE(("glBegin(%x)\n", primType));
277 glBegin(primType);
279 /* Draw the primitives */
280 curVtx = vertexBufData + (StartVertexIndex * skip);
282 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
284 if (!isIndexed) {
285 curPos = curVtx;
286 } else {
287 if (idxBytes == 2) {
288 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
289 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
290 } else {
291 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
292 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
296 /* Work through the vertex buffer */
297 x = *(float *)curPos;
298 curPos = curPos + sizeof(float);
299 y = *(float *)curPos;
300 curPos = curPos + sizeof(float);
301 z = *(float *)curPos;
302 curPos = curPos + sizeof(float);
303 VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
305 if (TRUE == useVertexShaderFunction) {
306 vertex_shader_input.V[D3DVSDE_POSITION].x = x;
307 vertex_shader_input.V[D3DVSDE_POSITION].y = y;
308 vertex_shader_input.V[D3DVSDE_POSITION].z = z;
309 vertex_shader_input.V[D3DVSDE_POSITION].w = 1.0f;
312 /* RHW follows, only if transformed */
313 if (isRHW) {
314 rhw = *(float *)curPos;
315 curPos = curPos + sizeof(float);
316 VTRACE(("rhw=%f\n", rhw));
318 if (TRUE == useVertexShaderFunction) {
319 vertex_shader_input.V[D3DVSDE_POSITION].w = rhw;
323 /* Blending data */
324 if (numBlends > 0) {
325 UINT i;
326 D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
327 DWORD skippedBlendLastUByte4 = 0;
329 for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
330 ((float*)&skippedBlend)[i] = *(float *)curPos;
331 curPos = curPos + sizeof(float);
334 if (isLastUByte4) {
335 skippedBlendLastUByte4 = *(DWORD*)curPos;
336 curPos = curPos + sizeof(DWORD);
339 if (TRUE == useVertexShaderFunction) {
340 vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].x = skippedBlend.x;
341 vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].y = skippedBlend.y;
342 vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].z = skippedBlend.z;
343 vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].w = skippedBlend.w;
345 if (isLastUByte4) {
346 vertex_shader_input.V[D3DVSDE_BLENDINDICES].x = (float) skippedBlendLastUByte4;
347 vertex_shader_input.V[D3DVSDE_BLENDINDICES].y = (float) skippedBlendLastUByte4;
348 vertex_shader_input.V[D3DVSDE_BLENDINDICES].z = (float) skippedBlendLastUByte4;
349 vertex_shader_input.V[D3DVSDE_BLENDINDICES].w = (float) skippedBlendLastUByte4;
354 /* Vertex Normal Data (untransformed only) */
355 if (normal) {
356 nx = *(float *)curPos;
357 curPos = curPos + sizeof(float);
358 ny = *(float *)curPos;
359 curPos = curPos + sizeof(float);
360 nz = *(float *)curPos;
361 curPos = curPos + sizeof(float);
362 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
364 if (TRUE == useVertexShaderFunction) {
365 vertex_shader_input.V[D3DVSDE_NORMAL].x = nx;
366 vertex_shader_input.V[D3DVSDE_NORMAL].y = ny;
367 vertex_shader_input.V[D3DVSDE_NORMAL].z = nz;
368 vertex_shader_input.V[D3DVSDE_NORMAL].w = 1.0f;
372 if (isPtSize) {
373 ptSize = *(float *)curPos;
374 VTRACE(("ptSize=%f\n", ptSize));
375 curPos = curPos + sizeof(float);
377 if (TRUE == useVertexShaderFunction) {
378 vertex_shader_input.V[D3DVSDE_PSIZE].x = ptSize;
379 vertex_shader_input.V[D3DVSDE_PSIZE].y = 0.0f;
380 vertex_shader_input.V[D3DVSDE_PSIZE].z = 0.0f;
381 vertex_shader_input.V[D3DVSDE_PSIZE].w = 1.0f;
385 if (isDiffuse) {
386 diffuseColor = *(DWORD *)curPos;
387 VTRACE(("diffuseColor=%lx\n", diffuseColor));
388 curPos = curPos + sizeof(DWORD);
390 if (TRUE == useVertexShaderFunction) {
391 vertex_shader_input.V[D3DVSDE_DIFFUSE].x = (float) (((diffuseColor >> 16) & 0xFF) / 255.0f);
392 vertex_shader_input.V[D3DVSDE_DIFFUSE].y = (float) (((diffuseColor >> 8) & 0xFF) / 255.0f);
393 vertex_shader_input.V[D3DVSDE_DIFFUSE].z = (float) (((diffuseColor >> 0) & 0xFF) / 255.0f);
394 vertex_shader_input.V[D3DVSDE_DIFFUSE].w = (float) (((diffuseColor >> 24) & 0xFF) / 255.0f);
398 if (isSpecular) {
399 specularColor = *(DWORD *)curPos;
400 VTRACE(("specularColor=%lx\n", specularColor));
401 curPos = curPos + sizeof(DWORD);
403 if (TRUE == useVertexShaderFunction) {
404 vertex_shader_input.V[D3DVSDE_SPECULAR].x = (float) (((specularColor >> 16) & 0xFF) / 255.0f);
405 vertex_shader_input.V[D3DVSDE_SPECULAR].y = (float) (((specularColor >> 8) & 0xFF) / 255.0f);
406 vertex_shader_input.V[D3DVSDE_SPECULAR].z = (float) (((specularColor >> 0) & 0xFF) / 255.0f);
407 vertex_shader_input.V[D3DVSDE_SPECULAR].w = (float) (((specularColor >> 24) & 0xFF) / 255.0f);
411 /* ToDo: Texture coords */
412 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
413 float s, t, r, q;
415 if (!(This->isMultiTexture) && textureNo > 0) {
416 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
417 continue ;
419 if (textureNo > This->TextureUnits) {
420 FIXME("Program using more concurrent textures than this opengl implementation support\n");
421 break ;
424 /* Query tex coords */
425 if (This->StateBlock.textures[textureNo] != NULL) {
426 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
427 case D3DRTYPE_TEXTURE:
428 s = *(float *)curPos;
429 curPos = curPos + sizeof(float);
430 t = *(float *)curPos;
431 curPos = curPos + sizeof(float);
432 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s,t));
434 if (TRUE == useVertexShaderFunction) {
435 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].x = s;
436 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].y = t;
437 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].z = 0.0f;
438 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].w = 1.0f;
439 } else {
440 if (This->isMultiTexture) {
441 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
442 } else {
443 glTexCoord2f(s, t);
446 break;
448 case D3DRTYPE_VOLUMETEXTURE:
449 s = *(float *)curPos;
450 curPos = curPos + sizeof(float);
451 t = *(float *)curPos;
452 curPos = curPos + sizeof(float);
453 r = *(float *)curPos;
454 curPos = curPos + sizeof(float);
455 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r));
457 if (TRUE == useVertexShaderFunction) {
458 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].x = s;
459 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].y = t;
460 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].z = r;
461 vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].w = 1.0f;
462 } else {
463 if (This->isMultiTexture) {
464 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
465 } else {
466 glTexCoord3f(s, t, r);
469 break;
471 default:
472 r = 0.0f; q = 0.0f; /* Avoid compiler warnings, need these vars later for other textures */
473 FIXME("Unhandled texture type\n");
475 } else {
476 /* Note I have seen a program actually do this, so just hide it and continue */
477 VTRACE(("Very odd - texture requested in FVF but not bound!\n"));
482 /** if vertex shader program specified ... using it */
483 if (TRUE == useVertexShaderFunction) {
484 VSHADEROUTPUTDATA8 vs_o;
485 memset(&vs_o, 0, sizeof(VSHADEROUTPUTDATA8));
486 vshader_program_execute_SW(vertex_shader, &vertex_shader_input, &vs_o);
488 TRACE_VECTOR(vs_o.oPos);
489 TRACE_VECTOR(vs_o.oD[0]);
490 TRACE_VECTOR(vs_o.oT[0]);
491 TRACE_VECTOR(vs_o.oT[1]);
493 x = vs_o.oPos.x;
494 y = vs_o.oPos.y;
495 z = vs_o.oPos.z;
497 if (1.0f != vs_o.oPos.w || isRHW) {
498 rhw = vs_o.oPos.w;
500 /*TRACE_VECTOR(vs_o.oPos);*/
501 if (isDiffuse) {
502 /*diffuseColor = D3DCOLOR_COLORVALUE(vs_o.oD[0].x, vs_o.oD[0].y, vs_o.oD[0].z, vs_o.oD[0].w);*/
503 /*TRACE_VECTOR(vs_o.oD[0]);*/
504 /*glColor4f(vs_o.oD[0].x, vs_o.oD[0].y, vs_o.oD[0].z, vs_o.oD[0].w); */
505 glMaterialfv(GL_FRONT, GL_DIFFUSE, (float*) &vs_o.oD[0]);
506 checkGLcall("glMaterialfv");
508 if (isSpecular) {
509 /*specularColor = D3DCOLOR_COLORVALUE(vs_o.oD[1].x, vs_o.oD[1].y, vs_o.oD[1].z, vs_o.oD[1].w);*/
510 /*TRACE_VECTOR(vs_o.oD[1]);*/
511 glMaterialfv(GL_FRONT, GL_SPECULAR, (float*) &vs_o.oD[1]);
512 checkGLcall("glMaterialfv");
514 /** reupdate textures coords binding using vs_o.oT[0->3] */
515 for (textureNo = 0; textureNo < 4/*min(numTextures, 4)*/; ++textureNo) {
516 float s, t, r, q;
518 if (!(This->isMultiTexture) && textureNo > 0) {
519 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
520 continue ;
522 /* Query tex coords */
523 if (This->StateBlock.textures[textureNo] != NULL) {
524 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
525 case D3DRTYPE_TEXTURE:
526 /*TRACE_VECTOR(vs_o.oT[textureNo]);*/
527 s = vs_o.oT[textureNo].x;
528 t = vs_o.oT[textureNo].y;
529 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s,t));
530 if (This->isMultiTexture) {
531 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
532 checkGLcall("glMultiTexCoord2fARB");
533 } else {
534 glTexCoord2f(s, t);
535 checkGLcall("gTexCoord2f");
537 break;
539 case D3DRTYPE_VOLUMETEXTURE:
540 /*TRACE_VECTOR(vs_o.oT[textureNo]);*/
541 s = vs_o.oT[textureNo].x;
542 t = vs_o.oT[textureNo].y;
543 r = vs_o.oT[textureNo].z;
544 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r));
545 if (This->isMultiTexture) {
546 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
547 checkGLcall("glMultiTexCoord2fARB");
548 } else {
549 glTexCoord3f(s, t, r);
550 checkGLcall("gTexCoord3f");
552 break;
554 default:
555 /* Avoid compiler warnings, need these vars later for other textures */
556 r = 0.0f; q = 0.0f;
557 FIXME("Unhandled texture type\n");
562 if (1.0f == rhw || rhw < 0.01f) {
563 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
564 glVertex3f(x, y, z);
565 checkGLcall("glVertex3f");
566 } else {
567 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
568 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
569 checkGLcall("glVertex4f");
571 } else {
572 /**
573 * FALSE == useVertexShaderFunction
574 * using std FVF code
577 /* Handle these vertexes */
578 if (isDiffuse) {
579 glColor4ub((diffuseColor >> 16) & 0xFF,
580 (diffuseColor >> 8) & 0xFF,
581 (diffuseColor >> 0) & 0xFF,
582 (diffuseColor >> 24) & 0xFF);
583 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
584 ((diffuseColor >> 16) & 0xFF) / 255.0f,
585 ((diffuseColor >> 8) & 0xFF) / 255.0f,
586 ((diffuseColor >> 0) & 0xFF) / 255.0f,
587 ((diffuseColor >> 24) & 0xFF) / 255.0f));
590 if (normal) {
591 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
592 glNormal3f(nx, ny, nz);
593 glVertex3f(x, y, z);
594 } else {
595 if (1.0f == rhw || rhw < 0.01f) {
596 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
597 glVertex3f(x, y, z);
598 } else {
599 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
600 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
605 if (!isIndexed) {
606 curVtx = curVtx + skip;
610 glEnd();
611 checkGLcall("glEnd and previous calls");
613 } else {
614 TRACE("Using fast vertex array code\n");
616 /* Faster version, harder to debug */
617 /* Shuffle to the beginning of the vertexes to render and index from there */
618 curVtx = vertexBufData + (StartVertexIndex * skip);
619 curPos = curVtx;
621 /* Set up the vertex pointers */
622 if (isRHW) {
623 glVertexPointer(4, GL_FLOAT, skip, curPos);
624 checkGLcall("glVertexPointer(4, ...)");
625 curPos += 4*sizeof(float);
626 } else {
627 glVertexPointer(3, GL_FLOAT, skip, curPos);
628 checkGLcall("glVertexPointer(3, ...)");
629 curPos += 3*sizeof(float);
631 glEnableClientState(GL_VERTEX_ARRAY);
632 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
634 if (numBlends>0) {
635 /* no such functionality in the fixed function GL pipeline */
636 /* FIXME: Wont get here as will drop to slow method */
637 FIXME("Cannot handle blending data here in openGl\n");
641 if (normal) {
642 glNormalPointer(GL_FLOAT, skip, curPos);
643 checkGLcall("glNormalPointer");
644 glEnableClientState(GL_NORMAL_ARRAY);
645 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
646 curPos += 3*sizeof(float);
647 } else {
648 glDisableClientState(GL_NORMAL_ARRAY);
649 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
650 glNormal3f(0, 0, 1);
651 checkGLcall("glNormal3f(0, 0, 1)");
654 if (isPtSize) {
655 /* no such functionality in the fixed function GL pipeline */
656 /* FIXME: Wont get here as will drop to slow method */
657 FIXME("Cannot change ptSize here in openGl\n");
658 curPos = curPos + sizeof(float);
661 if (isDiffuse) {
662 glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
663 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
664 glEnableClientState(GL_COLOR_ARRAY);
665 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
666 curPos += sizeof(DWORD);
668 else {
669 glDisableClientState(GL_COLOR_ARRAY);
670 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
671 glColor4f(1, 1, 1, 1);
672 checkGLcall("glColor4f(1, 1, 1, 1)");
675 /* Requires secondary color extensions to compile... */
676 #if 0
677 if (isSpecular) {
678 /* FIXME: check for GL_EXT_secondary_color */
679 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos);
680 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
681 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
682 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
683 curPos += sizeof(DWORD);
684 } else {
685 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
686 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
687 glSecondaryColor3fEXT(0, 0, 0);
688 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
690 #endif
692 /* ToDo: Texture coords */
693 for (textureNo = 0;textureNo<numTextures; textureNo++) {
695 /* Query tex coords */
696 glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
697 if (This->StateBlock.textures[textureNo] != NULL) {
698 enableTexture = TRUE;
699 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
700 case D3DRTYPE_TEXTURE:
701 glTexCoordPointer(2, GL_FLOAT, skip, curPos);
702 checkGLcall("glTexCoordPointer(2, ...)");
703 curPos += 2*sizeof(float);
704 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
705 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
706 break;
708 case D3DRTYPE_VOLUMETEXTURE:
709 glTexCoordPointer(3, GL_FLOAT, skip, curPos);
710 checkGLcall("glTexCoordPointer(3, ...)");
711 curPos += 3*sizeof(float);
712 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
713 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
714 break;
716 default:
717 FIXME("Unhandled texture type\n");
718 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
719 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
722 } else {
724 /* Note I have seen a program actually do this, so just hide it and continue */
725 TRACE("Very odd - texture requested in FVF but not bound!\n");
726 glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1);
727 checkGLcall("glMultiTexCoord4f(... , 0, 0, 0, 1)");
728 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
729 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
735 /* Finally do the drawing */
736 if (isIndexed) {
738 TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
739 if (idxBytes==2) {
740 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
741 glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT, idxData+(2 * StartIdx));
742 #else
743 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
744 GL_UNSIGNED_SHORT, idxData+(2 * StartIdx));
745 #endif
746 } else {
747 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
748 glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT, idxData+(4 * StartIdx));
749 #else
750 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
751 GL_UNSIGNED_INT, idxData+(2 * StartIdx));
752 #endif
754 checkGLcall("glDrawRangeElements");
756 } else {
758 /* Note first is now zero as we shuffled along earlier */
759 TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
760 glDrawArrays(primType, 0, NumVertexes);
761 checkGLcall("glDrawArrays");
766 /* If no normals, restore previous lighting state */
767 if (!normal) {
768 if (isLightingOn) glEnable(GL_LIGHTING);
769 else glDisable(GL_LIGHTING);
770 TRACE("Restored lighting to original state\n");
774 LEAVE_GL();
776 TRACE("glEnd\n");
780 Simple utility routines used for dx -> gl mapping of byte formats
782 SHORT bytesPerPixel(D3DFORMAT fmt) {
783 SHORT retVal;
785 switch (fmt) {
786 case D3DFMT_A4R4G4B4: retVal = 2; break;
787 case D3DFMT_A8R8G8B8: retVal = 4; break;
788 case D3DFMT_X8R8G8B8: retVal = 4; break;
789 case D3DFMT_R8G8B8: retVal = 3; break;
790 case D3DFMT_R5G6B5: retVal = 2; break;
791 case D3DFMT_A1R5G5B5: retVal = 2; break;
792 case D3DFMT_UNKNOWN:
793 /* Guess at the highest value of the above */
794 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt);
795 retVal = 4;
796 break;
797 default:
798 FIXME("Unhandled fmt %d\n", fmt);
799 retVal = 4;
801 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
802 return retVal;
805 GLint fmt2glintFmt(D3DFORMAT fmt) {
806 GLint retVal;
808 switch (fmt) {
809 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
810 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
811 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
812 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
813 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
814 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
815 default:
816 FIXME("Unhandled fmt %d\n", fmt);
817 retVal = 4;
819 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
820 return retVal;
822 GLenum fmt2glFmt(D3DFORMAT fmt) {
823 GLenum retVal;
825 switch (fmt) {
826 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
827 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
828 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
829 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
830 case D3DFMT_R5G6B5: retVal = GL_BGR; break;
831 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
832 default:
833 FIXME("Unhandled fmt %d\n", fmt);
834 retVal = 4;
836 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
837 return retVal;
839 DWORD fmt2glType(D3DFORMAT fmt) {
840 GLenum retVal;
842 switch (fmt) {
843 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
844 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
845 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
846 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
847 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
848 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
849 default:
850 FIXME("Unhandled fmt %d\n", fmt);
851 retVal = 4;
853 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
854 return retVal;
857 int SOURCEx_RGB_EXT(DWORD arg) {
858 switch(arg) {
859 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
860 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
861 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
862 case D3DTSS_ALPHAARG0:
863 case D3DTSS_ALPHAARG1:
864 case D3DTSS_ALPHAARG2:
865 default:
866 FIXME("Invalid arg %ld\n", arg);
867 return GL_SOURCE0_RGB_EXT;
870 int OPERANDx_RGB_EXT(DWORD arg) {
871 switch(arg) {
872 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
873 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
874 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
875 case D3DTSS_ALPHAARG0:
876 case D3DTSS_ALPHAARG1:
877 case D3DTSS_ALPHAARG2:
878 default:
879 FIXME("Invalid arg %ld\n", arg);
880 return GL_OPERAND0_RGB_EXT;
883 int SOURCEx_ALPHA_EXT(DWORD arg) {
884 switch(arg) {
885 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
886 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
887 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
888 case D3DTSS_COLORARG0:
889 case D3DTSS_COLORARG1:
890 case D3DTSS_COLORARG2:
891 default:
892 FIXME("Invalid arg %ld\n", arg);
893 return GL_SOURCE0_ALPHA_EXT;
896 int OPERANDx_ALPHA_EXT(DWORD arg) {
897 switch(arg) {
898 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
899 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
900 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
901 case D3DTSS_COLORARG0:
902 case D3DTSS_COLORARG1:
903 case D3DTSS_COLORARG2:
904 default:
905 FIXME("Invalid arg %ld\n", arg);
906 return GL_OPERAND0_ALPHA_EXT;
909 GLenum StencilOp(DWORD op) {
910 switch(op) {
911 case D3DSTENCILOP_KEEP : return GL_KEEP;
912 case D3DSTENCILOP_ZERO : return GL_ZERO;
913 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
914 case D3DSTENCILOP_INCRSAT : return GL_INCR;
915 case D3DSTENCILOP_DECRSAT : return GL_DECR;
916 case D3DSTENCILOP_INVERT : return GL_INVERT;
917 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op %ld\n", op);
918 return GL_INCR; /* Fixme - needs to support wrap */
919 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op %ld\n", op);
920 return GL_DECR; /* Fixme - needs to support wrap */
921 default:
922 FIXME("Invalid stencil op %ld\n", op);
923 return GL_ALWAYS;
927 /* Apply the current values to the specified texture stage */
928 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
929 ICOM_THIS(IDirect3DDevice8Impl,iface);
930 int i=0;
931 float col[4];
933 /* Make appropriate texture active */
934 if (This->isMultiTexture) {
935 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
936 checkGLcall("glActiveTextureARB");
937 } else if (Stage > 0) {
938 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
941 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
942 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
943 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock.texture_state[Stage][i]);
946 /* Note the D3DRS value applies to all textures, but GL has one
947 per texture, so apply it now ready to be used! */
948 col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
949 col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
950 col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
951 col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
952 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
953 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
955 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
958 /* IDirect3D IUnknown parts follow: */
959 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
961 ICOM_THIS(IDirect3DDevice8Impl,iface);
963 if (IsEqualGUID(riid, &IID_IUnknown)
964 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
965 IDirect3DDevice8Impl_AddRef(iface);
966 *ppobj = This;
967 return D3D_OK;
970 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
971 return E_NOINTERFACE;
974 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
975 ICOM_THIS(IDirect3DDevice8Impl,iface);
976 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
977 return ++(This->ref);
980 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
981 ICOM_THIS(IDirect3DDevice8Impl,iface);
982 ULONG ref = --This->ref;
983 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
984 if (ref == 0) {
985 HeapFree(GetProcessHeap(), 0, This);
987 return ref;
990 /* IDirect3DDevice Interface follow: */
991 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
992 ICOM_THIS(IDirect3DDevice8Impl,iface);
993 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
994 return D3D_OK;
997 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
998 ICOM_THIS(IDirect3DDevice8Impl,iface);
999 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
1001 * pretend we have 32MB of any type of memory queried.
1003 return (1024*1024*32);
1006 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
1007 ICOM_THIS(IDirect3DDevice8Impl,iface);
1008 FIXME("(%p) : stub\n", This); return D3D_OK;
1010 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
1011 ICOM_THIS(IDirect3DDevice8Impl,iface);
1012 TRACE("(%p) : returning %p\n", This, This->direct3d8);
1014 /* Inc ref count */
1015 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
1017 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
1018 return D3D_OK;
1020 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
1021 ICOM_THIS(IDirect3DDevice8Impl,iface);
1022 FIXME("(%p) : stub, calling idirect3d for now\n", This);
1023 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
1024 return D3D_OK;
1026 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
1028 HDC hdc;
1029 int bpp = 0;
1031 ICOM_THIS(IDirect3DDevice8Impl,iface);
1032 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
1033 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
1034 pMode->RefreshRate = 85; /*FIXME: How to identify? */
1036 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1037 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1038 DeleteDC(hdc);
1040 switch (bpp) {
1041 case 8: pMode->Format = D3DFMT_R8G8B8; break;
1042 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1043 case 24: pMode->Format = D3DFMT_R8G8B8; break;
1044 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1045 default:
1046 FIXME("Unrecognized display mode format\n");
1047 pMode->Format = D3DFMT_UNKNOWN;
1050 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
1051 return D3D_OK;
1053 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1054 ICOM_THIS(IDirect3DDevice8Impl,iface);
1055 TRACE("(%p) copying to %p\n", This, pParameters);
1056 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1057 return D3D_OK;
1059 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1060 ICOM_THIS(IDirect3DDevice8Impl,iface);
1061 FIXME("(%p) : stub\n", This); return D3D_OK;
1063 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1064 ICOM_THIS(IDirect3DDevice8Impl,iface);
1065 FIXME("(%p) : stub\n", This); return;
1067 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1068 ICOM_THIS(IDirect3DDevice8Impl,iface);
1069 FIXME("(%p) : stub\n", This); return D3D_OK;
1071 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1072 ICOM_THIS(IDirect3DDevice8Impl,iface);
1073 FIXME("(%p) : stub\n", This); return D3D_OK;
1075 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1076 ICOM_THIS(IDirect3DDevice8Impl,iface);
1077 FIXME("(%p) : stub\n", This); return D3D_OK;
1079 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1080 ICOM_THIS(IDirect3DDevice8Impl,iface);
1081 TRACE("(%p) : complete stub!\n", This);
1083 ENTER_GL();
1085 glXSwapBuffers(This->display, This->win);
1086 checkGLcall("glXSwapBuffers");
1088 LEAVE_GL();
1090 return D3D_OK;
1092 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
1093 ICOM_THIS(IDirect3DDevice8Impl,iface);
1094 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1095 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1097 /* Note inc ref on returned surface */
1098 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1100 return D3D_OK;
1102 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1103 ICOM_THIS(IDirect3DDevice8Impl,iface);
1104 FIXME("(%p) : stub\n", This); return D3D_OK;
1106 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1107 ICOM_THIS(IDirect3DDevice8Impl,iface);
1108 FIXME("(%p) : stub\n", This); return;
1110 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1111 ICOM_THIS(IDirect3DDevice8Impl,iface);
1112 FIXME("(%p) : stub\n", This); return;
1114 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1115 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1116 IDirect3DTexture8Impl *object;
1117 int i;
1118 UINT tmpW;
1119 UINT tmpH;
1121 ICOM_THIS(IDirect3DDevice8Impl,iface);
1123 /* Allocate the storage for the device */
1124 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
1125 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1126 object->lpVtbl = &Direct3DTexture8_Vtbl;
1127 object->Device = This;
1128 object->ResourceType = D3DRTYPE_TEXTURE;
1129 object->ref = 1;
1130 object->width = Width;
1131 object->height = Height;
1132 object->levels = Levels;
1133 object->usage = Usage;
1134 object->format = Format;
1135 object->device = This;
1137 /* Calculate levels for mip mapping */
1138 if (Levels == 0) {
1139 object->levels++;
1140 tmpW = Width;
1141 tmpH = Height;
1142 while (tmpW > 1 && tmpH > 1) {
1143 tmpW = max(1,tmpW / 2);
1144 tmpH = max(1, tmpH / 2);
1145 object->levels++;
1147 TRACE("Calculated levels = %d\n", object->levels);
1150 /* Generate all the surfaces */
1151 tmpW = Width;
1152 tmpH = Height;
1153 for (i=0; i<object->levels; i++)
1155 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1156 object->surfaces[i]->Container = object;
1157 object->surfaces[i]->myDesc.Usage = Usage;
1158 object->surfaces[i]->myDesc.Pool = Pool ;
1160 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1161 tmpW = max(1,tmpW / 2);
1162 tmpH = max(1, tmpH / 2);
1165 *ppTexture = (LPDIRECT3DTEXTURE8)object;
1166 return D3D_OK;
1168 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1170 IDirect3DVolumeTexture8Impl *object;
1171 int i;
1172 UINT tmpW;
1173 UINT tmpH;
1174 UINT tmpD;
1176 ICOM_THIS(IDirect3DDevice8Impl,iface);
1178 /* Allocate the storage for it */
1179 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);
1180 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1181 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1182 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1183 object->ref = 1;
1186 object->width = Width;
1187 object->height = Height;
1188 object->depth = Depth;
1189 object->levels = Levels;
1190 object->usage = Usage;
1191 object->format = Format;
1192 object->device = This;
1194 /* Calculate levels for mip mapping */
1195 if (Levels == 0) {
1196 object->levels++;
1197 tmpW = Width;
1198 tmpH = Height;
1199 tmpD = Depth;
1200 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1201 tmpW = max(1,tmpW / 2);
1202 tmpH = max(1, tmpH / 2);
1203 tmpD = max(1, tmpD / 2);
1204 object->levels++;
1206 TRACE("Calculated levels = %d\n", object->levels);
1209 /* Generate all the surfaces */
1210 tmpW = Width;
1211 tmpH = Height;
1212 tmpD = Depth;
1214 for (i=0; i<object->levels; i++)
1216 IDirect3DVolume8Impl *volume;
1218 /* Create the volume - No entry point for this seperately?? */
1219 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1220 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1222 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1223 volume->Device = This;
1224 volume->ResourceType = D3DRTYPE_VOLUME;
1225 volume->Container = object;
1226 volume->ref = 1;
1228 volume->myDesc.Width = Width;
1229 volume->myDesc.Height= Height;
1230 volume->myDesc.Depth = Depth;
1231 volume->myDesc.Format= Format;
1232 volume->myDesc.Type = D3DRTYPE_VOLUME;
1233 volume->myDesc.Pool = Pool;
1234 volume->myDesc.Usage = Usage;
1235 volume->bytesPerPixel = bytesPerPixel(Format);
1236 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1237 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1239 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
1240 volume, volume->allocatedMemory, volume->myDesc.Size);
1242 tmpW = max(1,tmpW / 2);
1243 tmpH = max(1, tmpH / 2);
1244 tmpD = max(1, tmpD / 2);
1247 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
1248 return D3D_OK;
1250 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
1252 IDirect3DCubeTexture8Impl *object;
1253 ICOM_THIS(IDirect3DDevice8Impl,iface);
1254 int i,j;
1255 UINT tmpW;
1257 /* Allocate the storage for it */
1258 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
1259 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1260 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1261 object->ref = 1;
1262 object->Device = This;
1263 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1265 object->edgeLength = EdgeLength;
1266 object->levels = Levels;
1267 object->usage = Usage;
1268 object->format = Format;
1269 object->device = This;
1271 /* Calculate levels for mip mapping */
1272 if (Levels == 0) {
1273 object->levels++;
1274 tmpW = EdgeLength;
1275 while (tmpW > 1) {
1276 tmpW = max(1,tmpW / 2);
1277 object->levels++;
1279 TRACE("Calculated levels = %d\n", object->levels);
1282 /* Generate all the surfaces */
1283 tmpW = EdgeLength;
1284 for (i=0; i<object->levels; i++)
1286 /* Create the 6 faces */
1287 for (j=0;j<6;j++) {
1288 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1289 object->surfaces[j][i]->Container = object;
1290 object->surfaces[j][i]->myDesc.Usage = Usage;
1291 object->surfaces[j][i]->myDesc.Pool = Pool ;
1293 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1294 tmpW = max(1,tmpW / 2);
1298 TRACE("(%p) : Iface@%p\n", This, object);
1299 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1300 return D3D_OK;
1302 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage,
1303 DWORD FVF,D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1304 IDirect3DVertexBuffer8Impl *object;
1306 ICOM_THIS(IDirect3DDevice8Impl,iface);
1308 /* Allocate the storage for the device */
1309 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1310 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1311 object->Device = This;
1312 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1313 object->ref = 1;
1314 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1315 object->currentDesc.Usage = Usage;
1316 object->currentDesc.Pool = Pool;
1317 object->currentDesc.FVF = FVF;
1318 object->currentDesc.Size = Size;
1320 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1322 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1324 return D3D_OK;
1326 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
1328 IDirect3DIndexBuffer8Impl *object;
1330 ICOM_THIS(IDirect3DDevice8Impl,iface);
1331 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
1333 /* Allocate the storage for the device */
1334 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1335 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1336 object->ref = 1;
1337 object->Device = This;
1338 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1340 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1341 object->currentDesc.Usage = Usage;
1342 object->currentDesc.Pool = Pool;
1343 object->currentDesc.Format = Format;
1344 object->currentDesc.Size = Length;
1346 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1348 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1350 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1352 return D3D_OK;
1354 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
1355 ICOM_THIS(IDirect3DDevice8Impl,iface);
1356 /* up ref count on surface, surface->container = This */
1357 FIXME("(%p) : stub\n", This); return D3D_OK;
1359 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
1360 ICOM_THIS(IDirect3DDevice8Impl,iface);
1361 /* surface->container = This */
1362 FIXME("(%p) : stub\n", This); return D3D_OK;
1364 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
1365 IDirect3DSurface8Impl *object;
1367 ICOM_THIS(IDirect3DDevice8Impl,iface);
1369 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1370 *ppSurface = (LPDIRECT3DSURFACE8) object;
1371 object->lpVtbl = &Direct3DSurface8_Vtbl;
1372 object->Device = This;
1373 object->ResourceType = D3DRTYPE_SURFACE;
1374 object->Container = This;
1376 object->ref = 1;
1377 object->myDesc.Width = Width;
1378 object->myDesc.Height= Height;
1379 object->myDesc.Format= Format;
1380 object->myDesc.Type = D3DRTYPE_SURFACE;
1381 /*object->myDesc.Usage */
1382 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
1383 object->bytesPerPixel = bytesPerPixel(Format);
1384 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1385 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1387 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);
1388 return D3D_OK;
1390 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1391 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1393 HRESULT rc = D3D_OK;
1395 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
1396 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1398 ICOM_THIS(IDirect3DDevice8Impl,iface);
1399 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1400 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1402 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1403 a sample and doesnt seem to break anything as far as I can tell */
1404 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1405 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1406 rc = D3DERR_INVALIDCALL;
1407 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1408 void *texture = NULL;
1410 TRACE("Converting dest to same format as source, since dest was unknown\n");
1411 dst->myDesc.Format = src->myDesc.Format;
1413 /* Convert container as well */
1414 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, NULL, &texture); /* FIXME: Which refid? */
1415 if (texture != NULL) {
1417 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1418 case D3DRTYPE_TEXTURE:
1419 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1420 break;
1421 case D3DRTYPE_VOLUMETEXTURE:
1422 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1423 break;
1424 case D3DRTYPE_CUBETEXTURE:
1425 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1426 break;
1427 default:
1428 FIXME("Unhandled texture type\n");
1434 /* Quick if complete copy ... */
1435 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1436 src->myDesc.Width == dst->myDesc.Width &&
1437 src->myDesc.Height == dst->myDesc.Height)) {
1438 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1439 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1441 } else {
1442 int i;
1443 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1444 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1445 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1447 void *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1448 void *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1450 /* Copy rect by rect */
1451 for (i=0; i<cRects; i++) {
1452 CONST RECT *r = &pSourceRectsArray[i];
1453 CONST POINT *p = &pDestPointsArray[i];
1454 void *from;
1455 void *to;
1456 int copyperline = (r->right - r->left) * bytesPerPixel;
1457 int j;
1459 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top,
1460 r->right, r->bottom, p->x, p->y);
1462 /* Find where to start */
1463 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1464 to = copyto + (p->y * pitchFrom) + (p->x * bytesPerPixel);
1466 /* Copy line by line */
1467 for (j=0; j<(r->bottom - r->top); j++) {
1468 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1472 return D3D_OK;
1474 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1475 ICOM_THIS(IDirect3DDevice8Impl,iface);
1476 FIXME("(%p) : stub\n", This); return D3D_OK;
1478 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1479 ICOM_THIS(IDirect3DDevice8Impl,iface);
1480 FIXME("(%p) : stub\n", This); return D3D_OK;
1482 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1483 ICOM_THIS(IDirect3DDevice8Impl,iface);
1484 FIXME("(%p) : stub\n", This);
1486 return D3D_OK;
1488 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1489 ICOM_THIS(IDirect3DDevice8Impl,iface);
1490 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1491 FIXME("(%p) : stub\n", This);
1494 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1495 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1498 return D3D_OK;
1500 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1502 ICOM_THIS(IDirect3DDevice8Impl,iface);
1504 /* Note inc ref on returned surface *
1505 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1507 FIXME("(%p) : stub\n", This);
1508 return D3D_OK;
1511 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1512 ICOM_THIS(IDirect3DDevice8Impl,iface);
1513 TRACE("(%p) : stub\n", This);
1514 return D3D_OK;
1516 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1517 ICOM_THIS(IDirect3DDevice8Impl,iface);
1518 TRACE("(%p)\n", This);
1520 ENTER_GL();
1522 glFlush();
1523 checkGLcall("glFlush");
1525 /* Useful for debugging sometimes!
1526 printf("Hit Enter ...\n");
1527 getchar(); */
1529 LEAVE_GL();
1530 return D3D_OK;
1532 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1533 ICOM_THIS(IDirect3DDevice8Impl,iface);
1535 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1536 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1537 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1538 GLbitfield glMask = 0;
1539 int i;
1540 CONST D3DRECT *curRect;
1542 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1543 Count, pRects, Flags, Z, Stencil);
1545 ENTER_GL();
1546 if (Count > 0 && pRects) {
1547 glEnable(GL_SCISSOR_TEST);
1548 checkGLcall("glEnable GL_SCISSOR_TEST");
1549 curRect = pRects;
1550 } else {
1551 curRect = NULL;
1554 for (i=0;i<Count || i==0; i++) {
1556 if (curRect) {
1557 /* Note gl uses lower left, width/height */
1558 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1559 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1560 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1561 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1562 checkGLcall("glScissor");
1565 /* Clear the whole screen */
1566 if (Flags & D3DCLEAR_STENCIL) {
1567 glClearStencil(Stencil);
1568 checkGLcall("glClearStencil");
1569 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1572 if (Flags & D3DCLEAR_ZBUFFER) {
1573 glClearDepth(Z);
1574 checkGLcall("glClearDepth");
1575 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1578 if (Flags & D3DCLEAR_TARGET) {
1579 TRACE("Clearing screen with glClear to color %lx\n", Color);
1580 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1581 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1582 checkGLcall("glClearColor");
1583 glMask = glMask | GL_COLOR_BUFFER_BIT;
1586 glClear(glMask);
1587 checkGLcall("glClear");
1589 if (curRect) curRect = curRect + sizeof(D3DRECT);
1592 if (Count > 0 && pRects) {
1593 glDisable(GL_SCISSOR_TEST);
1594 checkGLcall("glDisable");
1596 LEAVE_GL();
1598 return D3D_OK;
1600 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1601 ICOM_THIS(IDirect3DDevice8Impl,iface);
1602 int k;
1604 /* Most of this routine, comments included copied from ddraw tree initially: */
1605 TRACE("(%p) : State=%d\n", This, d3dts);
1607 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1608 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1609 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1611 /* Handle recording of state blocks */
1612 if (This->isRecordingState) {
1613 TRACE("Recording... not performing anything\n");
1614 return D3D_OK;
1618 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1620 where ViewMat = Camera space, WorldMat = world space.
1622 In OpenGL, camera and world space is combined into GL_MODELVIEW
1623 matrix. The Projection matrix stay projection matrix. */
1625 /* After reading through both OpenGL and Direct3D documentations, I
1626 thought that D3D matrices were written in 'line major mode' transposed
1627 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1628 works fine to transfer one matrix format to the other (it did not work
1629 when transposing)....
1631 So :
1632 1) are the documentations wrong
1633 2) does the matrix work even if they are not read correctly
1634 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1635 loading using glLoadMatrix ?
1637 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1638 to the other so that if I ever find out that I need to transpose them, I
1639 will able to do it quickly, only by changing the macro conv_mat. */
1641 switch (d3dts) {
1642 case D3DTS_WORLDMATRIX(0):
1643 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)]);
1644 break;
1646 case D3DTS_VIEW:
1647 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_VIEW]);
1648 break;
1650 case D3DTS_PROJECTION:
1651 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_PROJECTION]);
1652 break;
1654 default:
1655 FIXME("Unhandled transform state!!\n");
1656 break;
1660 * Move the GL operation to outside of switch to make it work
1661 * regardless of transform set order. Optimize later.
1663 ENTER_GL();
1664 glMatrixMode(GL_PROJECTION);
1665 checkGLcall("glMatrixMode");
1666 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
1667 checkGLcall("glLoadMatrixf");
1669 glMatrixMode(GL_MODELVIEW);
1670 checkGLcall("glMatrixMode");
1671 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1672 checkGLcall("glLoadMatrixf");
1674 /* If we are changing the View matrix, reset the light information to the new view */
1675 if (d3dts == D3DTS_VIEW) {
1676 for (k = 0; k < MAX_ACTIVE_LIGHTS; k++) {
1677 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1678 checkGLcall("glLightfv posn");
1679 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1680 checkGLcall("glLightfv dirn");
1684 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1685 checkGLcall("glMultMatrixf");
1687 LEAVE_GL();
1689 return D3D_OK;
1692 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1693 ICOM_THIS(IDirect3DDevice8Impl,iface);
1694 TRACE("(%p) : for State %d\n", This, State);
1695 memcpy(pMatrix, &This->StateBlock.transforms[State], sizeof(D3DMATRIX));
1696 return D3D_OK;
1699 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1700 ICOM_THIS(IDirect3DDevice8Impl,iface);
1701 FIXME("(%p) : stub\n", This); return D3D_OK;
1703 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1704 ICOM_THIS(IDirect3DDevice8Impl,iface);
1706 TRACE("(%p)\n", This);
1707 This->UpdateStateBlock->Changed.viewport = TRUE;
1708 This->UpdateStateBlock->Set.viewport = TRUE;
1709 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1711 /* Handle recording of state blocks */
1712 if (This->isRecordingState) {
1713 TRACE("Recording... not performing anything\n");
1714 return D3D_OK;
1717 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1718 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1720 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1721 checkGLcall("glDepthRange");
1722 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1723 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1724 checkGLcall("glViewport");
1727 return D3D_OK;
1730 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1731 ICOM_THIS(IDirect3DDevice8Impl,iface);
1732 TRACE("(%p)\n", This);
1733 memcpy(pViewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
1734 return D3D_OK;
1737 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1738 ICOM_THIS(IDirect3DDevice8Impl,iface);
1740 This->UpdateStateBlock->Changed.material = TRUE;
1741 This->UpdateStateBlock->Set.material = TRUE;
1742 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1744 /* Handle recording of state blocks */
1745 if (This->isRecordingState) {
1746 TRACE("Recording... not performing anything\n");
1747 return D3D_OK;
1750 ENTER_GL();
1751 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1752 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1753 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1754 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1755 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1757 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1758 checkGLcall("glMaterialfv");
1759 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1760 checkGLcall("glMaterialfv");
1762 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1763 checkGLcall("glMaterialfv");
1764 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1765 checkGLcall("glMaterialfv");
1766 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1767 checkGLcall("glMaterialf");
1769 LEAVE_GL();
1770 return D3D_OK;
1772 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1773 ICOM_THIS(IDirect3DDevice8Impl,iface);
1774 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1775 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1776 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1777 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1778 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1779 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1780 return D3D_OK;
1783 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1784 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1785 float rho;
1786 float quad_att;
1788 ICOM_THIS(IDirect3DDevice8Impl,iface);
1789 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1791 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,
1792 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1793 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1794 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1795 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1796 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1797 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1799 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1800 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1801 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1803 /* Handle recording of state blocks */
1804 if (This->isRecordingState) {
1805 TRACE("Recording... not performing anything\n");
1806 return D3D_OK;
1809 /* Diffuse: */
1810 colRGBA[0] = pLight->Diffuse.r;
1811 colRGBA[1] = pLight->Diffuse.g;
1812 colRGBA[2] = pLight->Diffuse.b;
1813 colRGBA[3] = pLight->Diffuse.a;
1814 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1815 checkGLcall("glLightfv");
1817 /* Specular */
1818 colRGBA[0] = pLight->Specular.r;
1819 colRGBA[1] = pLight->Specular.g;
1820 colRGBA[2] = pLight->Specular.b;
1821 colRGBA[3] = pLight->Specular.a;
1822 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1823 checkGLcall("glLightfv");
1825 /* Ambient */
1826 colRGBA[0] = pLight->Ambient.r;
1827 colRGBA[1] = pLight->Ambient.g;
1828 colRGBA[2] = pLight->Ambient.b;
1829 colRGBA[3] = pLight->Ambient.a;
1830 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1831 checkGLcall("glLightfv");
1833 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1834 glMatrixMode(GL_MODELVIEW);
1835 glPushMatrix();
1836 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1838 /* Attenuation - Are these right? guessing... */
1839 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
1840 checkGLcall("glLightf");
1841 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
1842 checkGLcall("glLightf");
1844 quad_att = 1.4/(pLight->Range*pLight->Range);
1845 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1846 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1847 checkGLcall("glLightf");
1849 switch (pLight->Type) {
1850 case D3DLIGHT_POINT:
1851 /* Position */
1852 This->lightPosn[Index][0] = pLight->Position.x;
1853 This->lightPosn[Index][1] = pLight->Position.y;
1854 This->lightPosn[Index][2] = pLight->Position.z;
1855 This->lightPosn[Index][3] = 1.0;
1856 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1857 checkGLcall("glLightfv");
1859 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1860 checkGLcall("glLightf");
1862 /* FIXME: Range */
1863 break;
1865 case D3DLIGHT_SPOT:
1866 /* Position */
1867 This->lightPosn[Index][0] = pLight->Position.x;
1868 This->lightPosn[Index][1] = pLight->Position.y;
1869 This->lightPosn[Index][2] = pLight->Position.z;
1870 This->lightPosn[Index][3] = 1.0;
1871 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1872 checkGLcall("glLightfv");
1874 /* Direction */
1875 This->lightDirn[Index][0] = pLight->Direction.x;
1876 This->lightDirn[Index][1] = pLight->Direction.y;
1877 This->lightDirn[Index][2] = pLight->Direction.z;
1878 This->lightDirn[Index][3] = 1.0;
1879 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1880 checkGLcall("glLightfv");
1883 * opengl-ish and d3d-ish spot lights use too different models for the
1884 * light "intensity" as a function of the angle towards the main light direction,
1885 * so we only can approximate very roughly.
1886 * however spot lights are rather rarely used in games (if ever used at all).
1887 * furthermore if still used, probably nobody pays attention to such details.
1889 if (pLight->Falloff == 0) {
1890 rho = 6.28f;
1891 } else {
1892 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1894 if (rho < 0.0001) rho = 0.0001f;
1895 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
1896 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
1898 /* FIXME: Range */
1899 break;
1900 case D3DLIGHT_DIRECTIONAL:
1901 /* Direction */
1902 This->lightPosn[Index][0] = -pLight->Direction.x;
1903 This->lightPosn[Index][1] = -pLight->Direction.y;
1904 This->lightPosn[Index][2] = -pLight->Direction.z;
1905 This->lightPosn[Index][3] = 0.0;
1906 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
1907 checkGLcall("glLightfv");
1909 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
1910 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
1913 break;
1914 default:
1915 FIXME("Unrecognized light type %d\n", pLight->Type);
1918 /* Restore the modelview matrix */
1919 glPopMatrix();
1921 return D3D_OK;
1923 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1924 ICOM_THIS(IDirect3DDevice8Impl,iface);
1925 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1926 memcpy(pLight, &This->StateBlock.lights[Index], sizeof(D3DLIGHT8));
1927 return D3D_OK;
1929 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1930 ICOM_THIS(IDirect3DDevice8Impl,iface);
1931 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
1933 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
1934 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
1935 This->UpdateStateBlock->lightEnable[Index] = Enable;
1937 /* Handle recording of state blocks */
1938 if (This->isRecordingState) {
1939 TRACE("Recording... not performing anything\n");
1940 return D3D_OK;
1943 if (Enable) {
1944 glEnable(GL_LIGHT0+Index);
1945 checkGLcall("glEnable GL_LIGHT0+Index");
1946 } else {
1947 glDisable(GL_LIGHT0+Index);
1948 checkGLcall("glDisable GL_LIGHT0+Index");
1950 return D3D_OK;
1952 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1953 ICOM_THIS(IDirect3DDevice8Impl,iface);
1954 TRACE("(%p) : for idx(%ld)\n", This, Index);
1955 *pEnable = This->StateBlock.lightEnable[Index];
1956 return D3D_OK;
1958 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1959 ICOM_THIS(IDirect3DDevice8Impl,iface);
1960 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
1962 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
1963 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
1964 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
1965 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
1966 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
1967 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
1969 /* Handle recording of state blocks */
1970 if (This->isRecordingState) {
1971 TRACE("Recording... not performing anything\n");
1972 return D3D_OK;
1975 /* Apply it */
1977 /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
1978 glMatrixMode(GL_MODELVIEW);
1979 glPushMatrix();
1980 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLD].u.m[0][0]);
1982 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
1983 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
1984 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
1986 glPopMatrix();
1987 checkGLcall("glClipPlane");
1989 return D3D_OK;
1991 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1992 ICOM_THIS(IDirect3DDevice8Impl,iface);
1993 TRACE("(%p) : for idx %ld\n", This, Index);
1994 pPlane[0] = This->StateBlock.clipplane[Index][0];
1995 pPlane[1] = This->StateBlock.clipplane[Index][0];
1996 pPlane[2] = This->StateBlock.clipplane[Index][0];
1997 pPlane[3] = This->StateBlock.clipplane[Index][0];
1998 return D3D_OK;
2000 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
2001 ICOM_THIS(IDirect3DDevice8Impl,iface);
2002 DWORD OldValue = This->StateBlock.renderstate[State];
2004 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
2005 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2006 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2007 This->UpdateStateBlock->renderstate[State] = Value;
2009 /* Handle recording of state blocks */
2010 if (This->isRecordingState) {
2011 TRACE("Recording... not performing anything\n");
2012 return D3D_OK;
2015 switch (State) {
2016 case D3DRS_FILLMODE :
2017 switch ((D3DFILLMODE) Value) {
2018 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2019 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2020 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2021 default:
2022 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2024 checkGLcall("glPolygonMode (fillmode)");
2025 break;
2027 case D3DRS_LIGHTING :
2028 if (Value) {
2029 glEnable(GL_LIGHTING);
2030 checkGLcall("glEnable GL_LIGHTING");
2031 } else {
2032 glDisable(GL_LIGHTING);
2033 checkGLcall("glDisable GL_LIGHTING");
2035 break;
2037 case D3DRS_ZENABLE :
2038 switch ((D3DZBUFFERTYPE) Value) {
2039 case D3DZB_FALSE:
2040 glDisable(GL_DEPTH_TEST);
2041 checkGLcall("glDisable GL_DEPTH_TEST");
2042 break;
2043 case D3DZB_TRUE:
2044 glEnable(GL_DEPTH_TEST);
2045 checkGLcall("glEnable GL_DEPTH_TEST");
2046 break;
2048 case D3DZB_USEW:
2049 default:
2050 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2052 break;
2054 case D3DRS_CULLMODE :
2056 /* If we are culling "back faces with clockwise vertices" then
2057 set front faces to be counter clockwise and enable culling
2058 of back faces */
2059 switch ((D3DCULL) Value) {
2060 case D3DCULL_NONE:
2061 glDisable(GL_CULL_FACE);
2062 checkGLcall("glDisable GL_CULL_FACE");
2063 break;
2064 case D3DCULL_CW:
2065 glEnable(GL_CULL_FACE);
2066 checkGLcall("glEnable GL_CULL_FACE");
2067 glFrontFace(GL_CCW);
2068 checkGLcall("glFrontFace GL_CCW");
2069 glCullFace(GL_BACK);
2070 break;
2071 case D3DCULL_CCW:
2072 glEnable(GL_CULL_FACE);
2073 checkGLcall("glEnable GL_CULL_FACE");
2074 glFrontFace(GL_CW);
2075 checkGLcall("glFrontFace GL_CW");
2076 glCullFace(GL_BACK);
2077 break;
2078 default:
2079 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2081 break;
2083 case D3DRS_SHADEMODE :
2084 switch ((D3DSHADEMODE) Value) {
2085 case D3DSHADE_FLAT:
2086 glShadeModel(GL_FLAT);
2087 checkGLcall("glShadeModel");
2088 break;
2089 case D3DSHADE_GOURAUD:
2090 glShadeModel(GL_SMOOTH);
2091 checkGLcall("glShadeModel");
2092 break;
2093 case D3DSHADE_PHONG:
2094 FIXME("D3DSHADE_PHONG isnt supported?\n");
2095 return D3DERR_INVALIDCALL;
2096 default:
2097 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
2099 break;
2101 case D3DRS_DITHERENABLE :
2102 if (Value) {
2103 glEnable(GL_DITHER);
2104 checkGLcall("glEnable GL_DITHER");
2105 } else {
2106 glDisable(GL_DITHER);
2107 checkGLcall("glDisable GL_DITHER");
2109 break;
2111 case D3DRS_ZWRITEENABLE :
2112 if (Value) {
2113 glDepthMask(1);
2114 checkGLcall("glDepthMask");
2115 } else {
2116 glDepthMask(0);
2117 checkGLcall("glDepthMask");
2119 break;
2121 case D3DRS_ZFUNC :
2123 int glParm = GL_LESS;
2125 switch ((D3DCMPFUNC) Value) {
2126 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2127 case D3DCMP_LESS: glParm=GL_LESS; break;
2128 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2129 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2130 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2131 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2132 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2133 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2134 default:
2135 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2137 glDepthFunc(glParm);
2138 checkGLcall("glDepthFunc");
2140 break;
2142 case D3DRS_AMBIENT :
2145 float col[4];
2146 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2147 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2148 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2149 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2150 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
2151 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2152 checkGLcall("glLightModel for MODEL_AMBIENT");
2155 break;
2157 case D3DRS_ALPHABLENDENABLE :
2158 if (Value) {
2159 glEnable(GL_BLEND);
2160 checkGLcall("glEnable GL_BLEND");
2161 } else {
2162 glDisable(GL_BLEND);
2163 checkGLcall("glDisable GL_BLEND");
2165 break;
2167 case D3DRS_SRCBLEND :
2168 case D3DRS_DESTBLEND :
2170 int newVal = GL_ZERO;
2171 switch (Value) {
2172 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2173 case D3DBLEND_ONE : newVal = GL_ONE; break;
2174 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2175 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2176 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2177 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2178 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2179 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2180 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2181 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2182 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2184 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2185 This->srcBlend = newVal;
2186 This->dstBlend = newVal;
2187 break;
2189 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2190 This->srcBlend = newVal;
2191 This->dstBlend = newVal;
2192 break;
2193 default:
2194 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
2197 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
2198 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
2199 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
2200 glBlendFunc(This->srcBlend, This->dstBlend);
2202 checkGLcall("glBlendFunc");
2204 break;
2206 case D3DRS_ALPHATESTENABLE :
2207 if (Value) {
2208 glEnable(GL_ALPHA_TEST);
2209 checkGLcall("glEnable GL_ALPHA_TEST");
2210 } else {
2211 glDisable(GL_ALPHA_TEST);
2212 checkGLcall("glDisable GL_ALPHA_TEST");
2214 break;
2216 case D3DRS_ALPHAFUNC :
2218 int glParm = GL_LESS;
2219 float ref = 1.0;
2221 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
2222 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
2224 switch ((D3DCMPFUNC) Value) {
2225 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2226 case D3DCMP_LESS: glParm=GL_LESS; break;
2227 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2228 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2229 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2230 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2231 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2232 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2233 default:
2234 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2236 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2237 glAlphaFunc(glParm, ref);
2238 checkGLcall("glAlphaFunc");
2240 break;
2242 case D3DRS_ALPHAREF :
2244 int glParm = GL_LESS;
2245 float ref = 1.0;
2247 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
2248 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
2250 ref = ((float) Value) / 255.0;
2251 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2252 glAlphaFunc(glParm, ref);
2253 checkGLcall("glAlphaFunc");
2255 break;
2257 case D3DRS_CLIPPLANEENABLE :
2258 case D3DRS_CLIPPING :
2260 /* Ensure we only do the changed clip planes */
2261 DWORD enable = 0xFFFFFFFF;
2262 DWORD disable = 0x00000000;
2264 /* If enabling / disabling all */
2265 if (State == D3DRS_CLIPPING) {
2266 if (Value) {
2267 enable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
2268 disable = 0x00;
2269 } else {
2270 disable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
2271 enable = 0x00;
2273 } else {
2274 enable = Value & ~OldValue;
2275 disable = ~Value & OldValue;
2278 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
2279 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
2280 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
2281 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
2282 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
2283 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
2285 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
2286 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
2287 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
2288 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
2289 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
2290 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
2292 break;
2294 case D3DRS_BLENDOP :
2296 int glParm = GL_FUNC_ADD;
2298 switch ((D3DBLENDOP) Value) {
2299 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
2300 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
2301 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
2302 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
2303 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
2304 default:
2305 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
2307 TRACE("glBlendEquation(%x)\n", glParm);
2308 glBlendEquation(glParm);
2309 checkGLcall("glBlendEquation");
2311 break;
2313 case D3DRS_TEXTUREFACTOR :
2315 int i;
2317 /* Note the texture color applies to all textures whereas
2318 GL_TEXTURE_ENV_COLOR applies to active only */
2319 float col[4];
2320 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2321 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2322 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2323 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2325 /* Set the default alpha blend color */
2326 glBlendColor(col[0], col[1], col[2], col[3]);
2327 checkGLcall("glBlendColor");
2329 /* And now the default texture color as well */
2330 for (i = 0; i < This->TextureUnits; i++) {
2332 /* Note the D3DRS value applies to all textures, but GL has one
2333 per texture, so apply it now ready to be used! */
2334 if (This->isMultiTexture) {
2335 glActiveTextureARB(GL_TEXTURE0_ARB + i);
2336 checkGLcall("Activate texture.. to update const color");
2337 } else if (i>0) {
2338 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2341 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
2342 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2345 break;
2347 case D3DRS_SPECULARENABLE :
2349 if (Value) {
2350 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
2351 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
2352 } else {
2353 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
2354 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
2357 break;
2359 case D3DRS_STENCILENABLE :
2360 if (Value) {
2361 glEnable(GL_STENCIL_TEST);
2362 checkGLcall("glEnable GL_STENCIL_TEST");
2363 } else {
2364 glDisable(GL_STENCIL_TEST);
2365 checkGLcall("glDisable GL_STENCIL_TEST");
2367 break;
2369 case D3DRS_STENCILFUNC :
2371 int glParm = GL_ALWAYS;
2372 int ref = 0;
2373 GLuint mask = 0xFFFFFFFF;
2375 glGetIntegerv(GL_STENCIL_REF, &ref);
2376 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2377 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2378 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2380 switch ((D3DCMPFUNC) Value) {
2381 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2382 case D3DCMP_LESS: glParm=GL_LESS; break;
2383 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2384 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2385 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2386 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2387 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2388 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2389 default:
2390 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2392 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2393 glStencilFunc(glParm, ref, mask);
2394 checkGLcall("glStencilFunc");
2396 break;
2398 case D3DRS_STENCILREF :
2400 int glParm = GL_ALWAYS;
2401 int ref = 0;
2402 GLuint mask = 0xFFFFFFFF;
2404 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2405 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2406 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2407 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2409 ref = Value;
2410 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2411 glStencilFunc(glParm, ref, mask);
2412 checkGLcall("glStencilFunc");
2414 break;
2416 case D3DRS_STENCILMASK :
2418 int glParm = GL_ALWAYS;
2419 int ref = 0.0;
2420 GLuint mask = Value;
2422 glGetIntegerv(GL_STENCIL_REF, &ref);
2423 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2424 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2425 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2427 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2428 glStencilFunc(glParm, ref, mask);
2429 checkGLcall("glStencilFunc");
2431 break;
2433 case D3DRS_STENCILFAIL :
2435 GLenum fail ;
2436 GLenum zpass ;
2437 GLenum zfail ;
2439 fail = StencilOp(Value);
2440 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2441 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2442 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2443 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2445 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2446 glStencilOp(fail, zfail, zpass);
2447 checkGLcall("glStencilOp(fail, zfail, zpass);");
2449 break;
2450 case D3DRS_STENCILZFAIL :
2452 GLenum fail ;
2453 GLenum zpass ;
2454 GLenum zfail ;
2456 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2457 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2458 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2459 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2460 zfail = StencilOp(Value);
2462 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2463 glStencilOp(fail, zfail, zpass);
2464 checkGLcall("glStencilOp(fail, zfail, zpass);");
2466 break;
2467 case D3DRS_STENCILPASS :
2469 GLenum fail ;
2470 GLenum zpass ;
2471 GLenum zfail ;
2473 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2474 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2475 zpass = StencilOp(Value);
2476 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2477 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2479 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2480 glStencilOp(fail, zfail, zpass);
2481 checkGLcall("glStencilOp(fail, zfail, zpass);");
2483 break;
2485 case D3DRS_STENCILWRITEMASK :
2487 glStencilMask(Value);
2488 TRACE("glStencilMask(%lu)\n", Value);
2489 checkGLcall("glStencilMask");
2491 break;
2493 case D3DRS_FOGENABLE :
2495 if (Value && This->StateBlock.renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
2496 glEnable(GL_FOG);
2497 checkGLcall("glEnable GL_FOG\n");
2498 } else {
2499 glDisable(GL_FOG);
2500 checkGLcall("glDisable GL_FOG\n");
2503 break;
2505 case D3DRS_FOGCOLOR :
2507 float col[4];
2508 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2509 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2510 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2511 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2513 /* Set the default alpha blend color */
2514 glFogfv(GL_FOG_COLOR, &col[0]);
2515 checkGLcall("glFog GL_FOG_COLOR");
2517 break;
2519 case D3DRS_FOGSTART :
2521 float *f = (float *)&Value;
2522 glFogfv(GL_FOG_START, f);
2523 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2524 TRACE("Fog Start == %f\n", *f);
2526 break;
2528 case D3DRS_FOGEND :
2530 float *f = (float *)&Value;
2531 glFogfv(GL_FOG_END, f);
2532 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2533 TRACE("Fog End == %f\n", *f);
2535 break;
2537 case D3DRS_FOGDENSITY :
2539 glFogf(GL_FOG_DENSITY, (float) Value);
2540 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2542 break;
2544 /* Unhandled yet...! */
2545 case D3DRS_LINEPATTERN :
2546 case D3DRS_LASTPIXEL :
2547 case D3DRS_ZVISIBLE :
2548 case D3DRS_FOGTABLEMODE :
2549 case D3DRS_EDGEANTIALIAS :
2550 case D3DRS_ZBIAS :
2551 case D3DRS_RANGEFOGENABLE :
2552 case D3DRS_WRAP0 :
2553 case D3DRS_WRAP1 :
2554 case D3DRS_WRAP2 :
2555 case D3DRS_WRAP3 :
2556 case D3DRS_WRAP4 :
2557 case D3DRS_WRAP5 :
2558 case D3DRS_WRAP6 :
2559 case D3DRS_WRAP7 :
2560 case D3DRS_FOGVERTEXMODE :
2561 case D3DRS_COLORVERTEX :
2562 case D3DRS_LOCALVIEWER :
2563 case D3DRS_NORMALIZENORMALS :
2564 case D3DRS_DIFFUSEMATERIALSOURCE :
2565 case D3DRS_SPECULARMATERIALSOURCE :
2566 case D3DRS_AMBIENTMATERIALSOURCE :
2567 case D3DRS_EMISSIVEMATERIALSOURCE :
2568 case D3DRS_VERTEXBLEND :
2569 case D3DRS_SOFTWAREVERTEXPROCESSING :
2570 case D3DRS_POINTSIZE :
2571 case D3DRS_POINTSIZE_MIN :
2572 case D3DRS_POINTSPRITEENABLE :
2573 case D3DRS_POINTSCALEENABLE :
2574 case D3DRS_POINTSCALE_A :
2575 case D3DRS_POINTSCALE_B :
2576 case D3DRS_POINTSCALE_C :
2577 case D3DRS_MULTISAMPLEANTIALIAS :
2578 case D3DRS_MULTISAMPLEMASK :
2579 case D3DRS_PATCHEDGESTYLE :
2580 case D3DRS_PATCHSEGMENTS :
2581 case D3DRS_DEBUGMONITORTOKEN :
2582 case D3DRS_POINTSIZE_MAX :
2583 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2584 case D3DRS_COLORWRITEENABLE :
2585 case D3DRS_TWEENFACTOR :
2586 case D3DRS_POSITIONORDER :
2587 case D3DRS_NORMALORDER :
2588 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2589 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2590 break;
2591 default:
2592 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2595 return D3D_OK;
2597 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2598 ICOM_THIS(IDirect3DDevice8Impl,iface);
2599 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2600 *pValue = This->StateBlock.renderstate[State];
2601 return D3D_OK;
2603 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2604 ICOM_THIS(IDirect3DDevice8Impl,iface);
2606 void *memory;
2608 TRACE("(%p)\n", This);
2609 if (This->isRecordingState) {
2610 TRACE("(%p) already recording! returning error\n", This);
2611 return D3DERR_INVALIDCALL;
2614 /* Allocate Storage */
2615 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2616 This->isRecordingState = TRUE;
2617 This->UpdateStateBlock = memory;
2619 return D3D_OK;
2621 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2623 ICOM_THIS(IDirect3DDevice8Impl,iface);
2624 TRACE("(%p)\n", This);
2626 if (!This->isRecordingState) {
2627 TRACE("(%p) not recording! returning error\n", This);
2628 return D3DERR_INVALIDCALL;
2631 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2632 *pToken = (DWORD) This->UpdateStateBlock;
2633 This->isRecordingState = FALSE;
2634 This->UpdateStateBlock = &This->StateBlock;
2636 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2637 return D3D_OK;
2640 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2642 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2643 int i,j;
2645 ICOM_THIS(IDirect3DDevice8Impl,iface);
2646 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2648 /* FIXME: Only apply applicable states not all states */
2650 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2652 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2654 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2655 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2656 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2657 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2660 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2661 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2663 /* TODO: Vertex Shader Constants */
2666 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2668 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2669 IDirect3DDevice8Impl_SetPixelShader(iface, pSB->PixelShader);
2671 /* TODO: Pixel Shader Constants */
2674 /* Others + Render & Texture */
2675 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2676 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2677 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2678 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2681 if (pSB->Set.Indices && pSB->Changed.Indices)
2682 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2684 if (pSB->Set.material && pSB->Changed.material)
2685 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2687 if (pSB->Set.viewport && pSB->Changed.viewport)
2688 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2690 for (i=0; i<MAX_STREAMS; i++) {
2691 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2692 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2695 for (i=0; i<MAX_CLIPPLANES; i++) {
2696 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2697 float clip[4];
2699 clip[0] = pSB->clipplane[i][0];
2700 clip[1] = pSB->clipplane[i][1];
2701 clip[2] = pSB->clipplane[i][2];
2702 clip[3] = pSB->clipplane[i][3];
2703 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2707 /* Render */
2708 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2710 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2711 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2715 /* Texture */
2716 for (j = 0; j < This->TextureUnits; j++) {
2717 for (i = 0; i < HIGHEST_TEXTURE_STATE; i++) {
2718 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i]) {
2719 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2722 if (pSB->Set.textures[j] && pSB->Changed.textures[j]) {
2723 IDirect3DDevice8Impl_SetTexture(iface, j, pSB->textures[j]);
2728 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2730 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2731 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2732 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2736 for (j=0; j<This->TextureUnits; i++) {
2737 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2739 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2740 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2741 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2745 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2747 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2748 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2749 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2753 for (j=0; j<This->TextureUnits; i++) {
2754 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2756 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2757 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2758 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2763 } else {
2764 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2766 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2767 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2769 return D3D_OK;
2771 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2773 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2775 ICOM_THIS(IDirect3DDevice8Impl,iface);
2777 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2779 /* If not recorded, then update can just recapture */
2780 if (updateBlock->blockType != D3DSBT_RECORDED) {
2781 DWORD tmpToken;
2782 STATEBLOCK *tmpBlock;
2783 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2784 tmpBlock = (STATEBLOCK *)tmpToken;
2785 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2786 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2788 /* FIXME: This will record states of new lights! May need to have and save set_lights
2789 across this action */
2791 } else {
2792 int i,j;
2794 /* Recorded => Only update 'changed' values */
2795 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2796 updateBlock->VertexShader = This->StateBlock.VertexShader;
2797 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2800 /* TODO: Vertex Shader Constants */
2802 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2803 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2804 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2805 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2808 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2809 &updateBlock->lights[i],
2810 sizeof(D3DLIGHT8)) != 0) {
2811 TRACE("Updating lights for light %d\n", i);
2812 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2816 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2817 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2818 updateBlock->lights[i] = This->StateBlock.lights[i];
2819 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2822 /* TODO: Pixel Shader Constants */
2824 /* Others + Render & Texture */
2825 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2826 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2827 &updateBlock->transforms[i],
2828 sizeof(D3DMATRIX)) != 0) {
2829 TRACE("Updating transform %d\n", i);
2830 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2834 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2835 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2836 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2837 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2838 updateBlock->pIndexData = This->StateBlock.pIndexData;
2839 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2842 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2843 &updateBlock->material,
2844 sizeof(D3DMATERIAL8)) != 0) {
2845 TRACE("Updating material\n");
2846 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2849 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2850 &updateBlock->viewport,
2851 sizeof(D3DVIEWPORT8)) != 0) {
2852 TRACE("Updating viewport\n");
2853 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2856 for (i=0; i<MAX_STREAMS; i++) {
2857 if (updateBlock->Set.stream_source[i] &&
2858 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2859 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2860 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2861 This->StateBlock.stream_stride[i]);
2862 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2863 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2867 for (i=0; i<MAX_CLIPPLANES; i++) {
2868 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2869 &updateBlock->clipplane[i],
2870 sizeof(updateBlock->clipplane)) != 0) {
2872 TRACE("Updating clipplane %d\n", i);
2873 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2874 sizeof(updateBlock->clipplane));
2878 /* Render */
2879 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2881 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
2882 This->StateBlock.renderstate[i])) {
2883 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2884 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2888 /* Texture */
2889 for (j=0; j<This->TextureUnits; j++) {
2890 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2892 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
2893 This->StateBlock.texture_state[j][i])) {
2894 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
2895 updateBlock->texture_state[j][i]);
2896 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
2899 if (updateBlock->Set.textures[j] && (updateBlock->textures[j] != This->StateBlock.textures[j])) {
2900 TRACE("Updating texture %d to %p (was %p)\n", j, This->StateBlock.textures[j], updateBlock->textures[j]);
2901 updateBlock->textures[j] = This->StateBlock.textures[j];
2908 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2910 return D3D_OK;
2912 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2913 ICOM_THIS(IDirect3DDevice8Impl,iface);
2914 TRACE("(%p) : freeing StateBlock %lx\n", This, Token);
2915 HeapFree(GetProcessHeap(), 0, (void *)Token);
2916 return D3D_OK;
2919 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
2920 void *memory;
2921 STATEBLOCK *s;
2922 int i,j;
2924 ICOM_THIS(IDirect3DDevice8Impl,iface);
2925 TRACE("(%p) : for type %d\n", This, Type);
2927 /* Allocate Storage */
2928 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2929 if (memory) {
2930 memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2931 } else {
2932 *pToken = 0xFFFFFFFF;
2933 return E_OUTOFMEMORY;
2935 *pToken = (DWORD) memory;
2936 s = memory;
2937 s->blockType = Type;
2939 TRACE("Updating changed flags appropriate for type %d\n", Type);
2941 if (Type == D3DSBT_ALL) {
2942 TRACE("ALL => Pretend everything has changed\n");
2943 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2945 } else if (Type == D3DSBT_PIXELSTATE) {
2947 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2949 /* TODO: Pixel Shader Constants */
2950 s->Changed.pixelShader = TRUE;
2951 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2952 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2954 for (j=0; j<This->TextureUnits; i++) {
2955 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2956 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2960 } else if (Type == D3DSBT_VERTEXSTATE) {
2962 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2964 /* TODO: Vertex Shader Constants */
2965 s->Changed.vertexShader = TRUE;
2967 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2968 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2970 for (j=0; j<This->TextureUnits; i++) {
2971 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2972 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2976 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2977 s->Changed.lightEnable[i] = TRUE;
2978 s->Changed.lights[i] = TRUE;
2981 } else {
2982 FIXME("Unrecognized state block type %d\n", Type);
2984 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2985 return D3D_OK;
2988 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2989 ICOM_THIS(IDirect3DDevice8Impl,iface);
2990 FIXME("(%p) : stub\n", This); return D3D_OK;
2992 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2993 ICOM_THIS(IDirect3DDevice8Impl,iface);
2994 FIXME("(%p) : stub\n", This); return D3D_OK;
2996 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2997 ICOM_THIS(IDirect3DDevice8Impl,iface);
2998 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2999 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
3000 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
3001 return D3D_OK;
3003 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
3005 IDirect3DBaseTexture8 *oldTxt;
3007 ICOM_THIS(IDirect3DDevice8Impl,iface);
3008 D3DRESOURCETYPE textureType;
3010 oldTxt = This->StateBlock.textures[Stage];
3011 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
3013 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
3014 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
3015 This->UpdateStateBlock->textures[Stage] = pTexture;
3017 /* Handle recording of state blocks */
3018 if (This->isRecordingState) {
3019 TRACE("Recording... not performing anything\n");
3020 return D3D_OK;
3023 /* Make appropriate texture active */
3024 if (This->isMultiTexture) {
3025 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3026 checkGLcall("glActiveTextureARB");
3027 } else if (Stage>0) {
3028 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3031 /* Decrement the count of the previous texture */
3032 /* FIXME PERF: If old == new and not dirty then skip all this */
3033 if (oldTxt != NULL) {
3034 IDirect3DBaseTexture8Impl_Release(oldTxt);
3037 if (pTexture) {
3038 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
3040 /* Now setup the texture appropraitly */
3041 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
3043 if (textureType == D3DRTYPE_TEXTURE) {
3044 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
3045 int i;
3047 /* Standard 2D texture */
3048 TRACE("Standard 2d texture\n");
3049 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
3051 for (i=0; i<pTexture2->levels; i++)
3054 if (i==0 && pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3055 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3056 checkGLcall("glBindTexture");
3057 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3058 } else {
3059 if (i==0) {
3061 if (pTexture2->surfaces[i]->textureName == 0) {
3062 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
3063 checkGLcall("glGenTextures");
3064 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3067 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3068 checkGLcall("glBindTexture");
3070 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", pTexture2->levels-1);
3071 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3072 checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels)");
3075 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3076 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
3077 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3078 pTexture2->surfaces[i]->allocatedMemory);
3079 glTexImage2D(GL_TEXTURE_2D, i,
3080 fmt2glintFmt(pTexture2->format),
3081 pTexture2->surfaces[i]->myDesc.Width,
3082 pTexture2->surfaces[i]->myDesc.Height,
3084 fmt2glFmt(pTexture2->format),
3085 fmt2glType(pTexture2->format),
3086 pTexture2->surfaces[i]->allocatedMemory
3088 checkGLcall("glTexImage2D");
3090 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3091 pTexture2->Dirty = FALSE;
3096 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3097 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3098 int i;
3100 /* Standard 3D (volume) texture */
3101 TRACE("Standard 3d texture\n");
3102 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
3104 for (i=0; i<pTexture2->levels; i++)
3107 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3108 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3109 checkGLcall("glBindTexture");
3110 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3111 } else {
3112 if (i==0) {
3114 if (pTexture2->volumes[i]->textureName == 0) {
3115 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3116 checkGLcall("glGenTextures");
3117 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3120 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3121 checkGLcall("glBindTexture");
3123 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3124 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3127 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3128 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3129 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3130 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3131 pTexture2->volumes[i]->allocatedMemory);
3132 glTexImage3D(GL_TEXTURE_3D, i,
3133 fmt2glintFmt(pTexture2->format),
3134 pTexture2->volumes[i]->myDesc.Width,
3135 pTexture2->volumes[i]->myDesc.Height,
3136 pTexture2->volumes[i]->myDesc.Depth,
3138 fmt2glFmt(pTexture2->format),
3139 fmt2glType(pTexture2->format),
3140 pTexture2->volumes[i]->allocatedMemory
3142 checkGLcall("glTexImage3D");
3144 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3145 pTexture2->Dirty = FALSE;
3149 } else {
3150 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
3152 } else {
3153 TRACE("Setting to no texture (ie default texture)\n");
3154 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
3155 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3156 checkGLcall("glBindTexture");
3157 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3160 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3161 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3162 setupTextureStates (iface, Stage);
3164 return D3D_OK;
3167 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3168 ICOM_THIS(IDirect3DDevice8Impl,iface);
3169 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
3170 *pValue = This->StateBlock.texture_state[Stage][Type];
3171 return D3D_OK;
3174 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
3175 ICOM_THIS(IDirect3DDevice8Impl,iface);
3177 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3179 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
3181 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3182 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3183 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3185 /* Handle recording of state blocks */
3186 if (This->isRecordingState) {
3187 TRACE("Recording... not performing anything\n");
3188 return D3D_OK;
3191 /* Make appropriate texture active */
3192 TRACE("Activating appropriate texture state %ld\n", Stage);
3193 if (This->isMultiTexture) {
3194 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3195 checkGLcall("glActiveTextureARB");
3196 } else if (Stage>0) {
3197 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3200 switch (Type) {
3202 case D3DTSS_MINFILTER :
3203 case D3DTSS_MIPFILTER :
3205 DWORD ValueMIN = This->StateBlock.texture_state[Stage][D3DTSS_MINFILTER];
3206 DWORD ValueMIP = This->StateBlock.texture_state[Stage][D3DTSS_MIPFILTER];
3207 GLint realVal = GL_LINEAR;
3209 if (ValueMIN == D3DTEXF_POINT) {
3210 /* GL_NEAREST_* */
3211 if (ValueMIP == D3DTEXF_POINT) {
3212 realVal = GL_NEAREST_MIPMAP_NEAREST;
3213 } else if (ValueMIP == D3DTEXF_LINEAR) {
3214 realVal = GL_NEAREST_MIPMAP_LINEAR;
3215 } else if (ValueMIP == D3DTEXF_NONE) {
3216 realVal = GL_NEAREST;
3217 } else {
3218 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3219 realVal = GL_NEAREST_MIPMAP_LINEAR;
3221 } else if (ValueMIN == D3DTEXF_LINEAR) {
3222 /* GL_LINEAR_* */
3223 if (ValueMIP == D3DTEXF_POINT) {
3224 realVal = GL_LINEAR_MIPMAP_NEAREST;
3225 } else if (ValueMIP == D3DTEXF_LINEAR) {
3226 realVal = GL_LINEAR_MIPMAP_LINEAR;
3227 } else if (ValueMIP == D3DTEXF_NONE) {
3228 realVal = GL_LINEAR;
3229 } else {
3230 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3231 realVal = GL_LINEAR_MIPMAP_LINEAR;
3233 } else if (ValueMIN == D3DTEXF_NONE) {
3234 /* Doesnt really make sense - Windows just seems to disable
3235 mipmapping when this occurs */
3236 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3237 realVal = GL_LINEAR;
3239 } else {
3240 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3241 realVal = GL_LINEAR_MIPMAP_LINEAR;
3244 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3245 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3246 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3248 break;
3251 case D3DTSS_MAGFILTER :
3252 if (Value == D3DTEXF_POINT) {
3253 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3254 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3255 } else if (Value == D3DTEXF_LINEAR) {
3256 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3257 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3258 } else {
3259 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3261 break;
3263 case D3DTSS_COLORARG0 :
3264 case D3DTSS_ALPHAARG0 :
3265 /* FIXME: Mesa seems to struggle setting these at the moment */
3266 break;
3268 case D3DTSS_COLORARG1 :
3269 case D3DTSS_COLORARG2 :
3270 case D3DTSS_ALPHAARG1 :
3271 case D3DTSS_ALPHAARG2 :
3273 BOOL isAlphaReplicate = FALSE;
3274 BOOL isComplement = FALSE;
3275 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3276 int operand= GL_SRC_COLOR;
3277 int source = GL_TEXTURE;
3279 /* Catch alpha replicate */
3280 if (Value & D3DTA_ALPHAREPLICATE) {
3281 Value = Value & ~D3DTA_ALPHAREPLICATE;
3282 isAlphaReplicate = TRUE;
3285 /* Catch Complement */
3286 if (Value & D3DTA_COMPLEMENT) {
3287 Value = Value & ~D3DTA_COMPLEMENT;
3288 isComplement = TRUE;
3291 /* Calculate the operand */
3292 if (isAlphaReplicate && !isComplement) {
3293 operand = GL_SRC_ALPHA;
3294 } else if (isAlphaReplicate && isComplement) {
3295 operand = GL_ONE_MINUS_SRC_ALPHA;
3296 } else if (isComplement) {
3297 if (isAlphaArg) {
3298 operand = GL_ONE_MINUS_SRC_COLOR;
3299 } else {
3300 operand = GL_ONE_MINUS_SRC_ALPHA;
3302 } else {
3303 if (isAlphaArg) {
3304 operand = GL_SRC_ALPHA;
3305 } else {
3306 operand = GL_SRC_COLOR;
3310 /* Calculate the source */
3311 switch (Value) {
3312 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
3313 break;
3314 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
3315 break;
3316 case D3DTA_TEXTURE: source = GL_TEXTURE;
3317 break;
3318 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
3319 break;
3321 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
3322 isnt supported until base GL supports it
3323 There is no concept of temp registers as far as I can tell */
3325 default:
3326 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
3329 if (isAlphaArg) {
3330 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3331 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3332 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3333 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3334 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3335 } else {
3336 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3337 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3338 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3339 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3340 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3343 break;
3345 case D3DTSS_ALPHAOP :
3346 case D3DTSS_COLOROP :
3349 int Scale = 1;
3350 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3352 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3353 /* TODO: Disable by making this and all later levels disabled */
3354 glDisable(GL_TEXTURE_1D);
3355 checkGLcall("Disable GL_TEXTURE_1D");
3356 glDisable(GL_TEXTURE_2D);
3357 checkGLcall("Disable GL_TEXTURE_2D");
3358 glDisable(GL_TEXTURE_3D);
3359 checkGLcall("Disable GL_TEXTURE_3D");
3360 } else {
3362 /* Enable only the appropriate texture dimension */
3363 if (Type==D3DTSS_COLOROP) {
3364 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
3365 glEnable(GL_TEXTURE_1D);
3366 checkGLcall("Enable GL_TEXTURE_1D");
3367 } else {
3368 glDisable(GL_TEXTURE_1D);
3369 checkGLcall("Disable GL_TEXTURE_1D");
3371 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
3372 glEnable(GL_TEXTURE_2D);
3373 checkGLcall("Enable GL_TEXTURE_2D");
3374 } else {
3375 glDisable(GL_TEXTURE_2D);
3376 checkGLcall("Disable GL_TEXTURE_2D");
3378 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
3379 glEnable(GL_TEXTURE_3D);
3380 checkGLcall("Enable GL_TEXTURE_3D");
3381 } else {
3382 glDisable(GL_TEXTURE_3D);
3383 checkGLcall("Disable GL_TEXTURE_3D");
3387 /* Now set up the operand correctly */
3388 switch (Value) {
3389 case D3DTOP_DISABLE :
3390 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3391 and it works, so ignore this op */
3392 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3393 break;
3395 case D3DTOP_SELECTARG1 :
3396 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3397 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3398 break;
3400 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3401 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3402 case D3DTOP_MODULATE :
3404 /* Correct scale */
3405 if (Type == D3DTSS_ALPHAOP) {
3406 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3407 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3408 } else {
3409 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3410 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3412 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3413 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3414 break;
3416 case D3DTOP_ADD :
3417 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3418 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3419 break;
3421 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3422 case D3DTOP_ADDSIGNED :
3423 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3424 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3425 break;
3427 case D3DTOP_DOTPRODUCT3 :
3428 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3429 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3430 break;*/
3432 case D3DTOP_SUBTRACT :
3433 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3434 case D3DTOP_SELECTARG2 :
3435 /* GL_REPLACE, swap args 0 and 1? */
3436 case D3DTOP_ADDSMOOTH :
3437 case D3DTOP_BLENDDIFFUSEALPHA :
3438 case D3DTOP_BLENDTEXTUREALPHA :
3439 case D3DTOP_BLENDFACTORALPHA :
3440 case D3DTOP_BLENDTEXTUREALPHAPM :
3441 case D3DTOP_BLENDCURRENTALPHA :
3442 case D3DTOP_PREMODULATE :
3443 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3444 case D3DTOP_MODULATECOLOR_ADDALPHA :
3445 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3446 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3447 case D3DTOP_BUMPENVMAP :
3448 case D3DTOP_BUMPENVMAPLUMINANCE :
3449 case D3DTOP_MULTIPLYADD :
3450 case D3DTOP_LERP :
3451 default:
3452 FIXME("Unhandled texture operation %ld\n", Value);
3455 break;
3458 /* Unhandled */
3459 case D3DTSS_BUMPENVMAT00 :
3460 case D3DTSS_BUMPENVMAT01 :
3461 case D3DTSS_BUMPENVMAT10 :
3462 case D3DTSS_BUMPENVMAT11 :
3463 case D3DTSS_TEXCOORDINDEX :
3464 case D3DTSS_ADDRESSU :
3465 case D3DTSS_ADDRESSV :
3466 case D3DTSS_BORDERCOLOR :
3467 case D3DTSS_MIPMAPLODBIAS :
3468 case D3DTSS_MAXMIPLEVEL :
3469 case D3DTSS_MAXANISOTROPY :
3470 case D3DTSS_BUMPENVLSCALE :
3471 case D3DTSS_BUMPENVLOFFSET :
3472 case D3DTSS_TEXTURETRANSFORMFLAGS :
3473 case D3DTSS_ADDRESSW :
3474 case D3DTSS_RESULTARG :
3475 default:
3476 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3477 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3479 return D3D_OK;
3481 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3482 ICOM_THIS(IDirect3DDevice8Impl,iface);
3483 FIXME("(%p) : stub\n", This); return D3D_OK;
3485 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3486 ICOM_THIS(IDirect3DDevice8Impl,iface);
3487 FIXME("(%p) : stub\n", This); return D3D_OK;
3489 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3490 ICOM_THIS(IDirect3DDevice8Impl,iface);
3491 FIXME("(%p) : stub\n", This); return D3D_OK;
3493 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3494 ICOM_THIS(IDirect3DDevice8Impl,iface);
3495 FIXME("(%p) : stub\n", This); return D3D_OK;
3497 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3498 ICOM_THIS(IDirect3DDevice8Impl,iface);
3499 FIXME("(%p) : stub\n", This); return D3D_OK;
3501 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3502 ICOM_THIS(IDirect3DDevice8Impl,iface);
3503 FIXME("(%p) : stub\n", This); return D3D_OK;
3505 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3507 IDirect3DVertexBuffer8 *pVB;
3509 ICOM_THIS(IDirect3DDevice8Impl,iface);
3510 pVB = This->StateBlock.stream_source[0];
3512 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3514 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3515 This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
3517 return D3D_OK;
3519 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3520 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3521 UINT idxStride = 2;
3522 IDirect3DIndexBuffer8 *pIB;
3523 IDirect3DVertexBuffer8 *pVB;
3524 D3DINDEXBUFFER_DESC IdxBufDsc;
3526 ICOM_THIS(IDirect3DDevice8Impl,iface);
3527 pIB = This->StateBlock.pIndexData;
3528 pVB = This->StateBlock.stream_source[0];
3530 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3531 minIndex, NumVertices, startIndex, primCount);
3533 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3534 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3535 idxStride = 2;
3536 } else {
3537 idxStride = 4;
3540 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3541 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3542 minIndex);
3544 return D3D_OK;
3546 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3547 ICOM_THIS(IDirect3DDevice8Impl,iface);
3549 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3551 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3553 This->StateBlock.stream_source[0] = NULL;
3554 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3555 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3556 0, 0, 0, NULL, 0);
3557 This->StateBlock.stream_stride[0] = 0;
3559 /*stream zero settings set to null at end */
3560 return D3D_OK;
3562 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3563 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3564 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3565 UINT VertexStreamZeroStride) {
3566 int idxStride;
3567 ICOM_THIS(IDirect3DDevice8Impl,iface);
3568 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3569 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3571 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3572 if (IndexDataFormat == D3DFMT_INDEX16) {
3573 idxStride = 2;
3574 } else {
3575 idxStride = 4;
3578 This->StateBlock.stream_source[0] = NULL;
3579 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3580 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3581 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3583 /*stream zero settings set to null at end */
3584 This->StateBlock.stream_stride[0] = 0;
3585 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3587 return D3D_OK;
3589 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3590 ICOM_THIS(IDirect3DDevice8Impl,iface);
3591 FIXME("(%p) : stub\n", This); return D3D_OK;
3593 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3594 ICOM_THIS(IDirect3DDevice8Impl,iface);
3595 VERTEXSHADER8* object;
3596 UINT i;
3598 FIXME("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3599 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3600 return D3DERR_INVALIDCALL;
3602 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(VERTEXSHADER8*); ++i) ;
3603 if (i >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) {
3604 return D3DERR_OUTOFVIDEOMEMORY;
3606 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERTEXSHADER8));
3607 if (NULL == object) {
3608 return D3DERR_OUTOFVIDEOMEMORY;
3611 object->usage = Usage;
3612 object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADERDATA8));
3614 VertexShaders[i] = object;
3615 *pHandle = VS_HIGHESTFIXEDFXF + i;
3617 object->decl = (DWORD*) pDeclaration;
3618 object->function = (DWORD*) pFunction;
3620 vshader_decl_parse(object);
3621 vshader_program_parse(object);
3623 /* copy the function ... because it will certainly be released by application */
3624 if (NULL != pFunction) {
3625 object->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->functionLength);
3626 memcpy(object->function, pFunction, object->functionLength);
3628 /* copy the declaration too */
3629 object->decl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declLength);
3630 memcpy(object->decl, pDeclaration, object->declLength);
3631 return D3D_OK;
3633 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3634 ICOM_THIS(IDirect3DDevice8Impl,iface);
3636 This->UpdateStateBlock->VertexShader = Handle;
3637 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3638 This->UpdateStateBlock->Set.vertexShader = TRUE;
3640 /* Handle recording of state blocks */
3641 if (This->isRecordingState) {
3642 TRACE("Recording... not performing anything\n");
3643 return D3D_OK;
3645 if (Handle <= VS_HIGHESTFIXEDFXF) {
3646 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3647 return D3D_OK;
3648 } else {
3649 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3650 return D3D_OK;
3653 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3654 ICOM_THIS(IDirect3DDevice8Impl,iface);
3655 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock.VertexShader);
3656 *pHandle = This->StateBlock.VertexShader;
3657 return D3D_OK;
3660 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3661 ICOM_THIS(IDirect3DDevice8Impl,iface);
3662 VERTEXSHADER8* object;
3664 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3665 return D3DERR_INVALIDCALL;
3667 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3668 if (NULL == object) {
3669 return D3DERR_INVALIDCALL;
3671 TRACE("(%p) : freing VertexShader %p\n", This, object);
3672 /* TODO: check validity of object */
3673 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3674 HeapFree(GetProcessHeap(), 0, (void *)object->decl);
3675 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3676 HeapFree(GetProcessHeap(), 0, (void *)object);
3677 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3678 return D3D_OK;
3681 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3682 ICOM_THIS(IDirect3DDevice8Impl,iface);
3683 VERTEXSHADER8* object;
3684 DWORD Handle = This->UpdateStateBlock->VertexShader;
3686 /* FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); */
3687 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3688 return D3DERR_INVALIDCALL;
3690 object = VERTEX_SHADER(Handle);
3691 if (NULL == object || NULL == pConstantData) {
3692 return D3DERR_INVALIDCALL;
3694 if (NULL == object->data) { /* temporary while datas not supported */
3695 FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
3696 return D3DERR_INVALIDCALL;
3698 memcpy(object->data->C + Register, pConstantData, ConstantCount * sizeof(D3DSHADERVECTOR));
3700 return D3D_OK;
3702 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3703 ICOM_THIS(IDirect3DDevice8Impl,iface);
3704 VERTEXSHADER8* object;
3705 DWORD Handle = This->UpdateStateBlock->VertexShader;
3707 FIXME("(%p) : VertexShader_GetConstant not fully supported yet\n", This);
3709 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3710 return D3DERR_INVALIDCALL;
3712 object = VERTEX_SHADER(Handle);
3713 if (NULL == object || NULL == pConstantData) {
3714 return D3DERR_INVALIDCALL;
3716 if (NULL == object->data) { /* temporary while datas not supported */
3717 return D3DERR_INVALIDCALL;
3719 memcpy(pConstantData, object->data->C + Register, ConstantCount * sizeof(D3DSHADERVECTOR));
3721 return D3D_OK;
3723 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3724 ICOM_THIS(IDirect3DDevice8Impl,iface);
3725 VERTEXSHADER8* object;
3727 object = VERTEX_SHADER(Handle);
3728 if (NULL == object) {
3729 return D3DERR_INVALIDCALL;
3731 if (NULL == pData) {
3732 *pSizeOfData = object->declLength;
3733 return D3D_OK;
3735 if (*pSizeOfData < object->declLength) {
3736 *pSizeOfData = object->declLength;
3737 return D3DERR_MOREDATA;
3739 TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
3740 memcpy(pData, object->decl, object->declLength);
3741 return D3D_OK;
3743 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3744 ICOM_THIS(IDirect3DDevice8Impl,iface);
3745 VERTEXSHADER8* object;
3747 object = VERTEX_SHADER(Handle);
3748 if (NULL == object) {
3749 return D3DERR_INVALIDCALL;
3751 if (NULL == pData) {
3752 *pSizeOfData = object->functionLength;
3753 return D3D_OK;
3755 if (*pSizeOfData < object->functionLength) {
3756 *pSizeOfData = object->functionLength;
3757 return D3DERR_MOREDATA;
3759 if (NULL == object->function) { /* no function defined */
3760 TRACE("(%p) : GetVertexShaderFunction no User Function defined using NULL to %p\n", This, pData);
3761 ((DWORD *) pData) = NULL;
3762 } else {
3763 TRACE("(%p) : GetVertexShaderFunction copying to %p\n", This, pData);
3764 memcpy(pData, object->function, object->functionLength);
3766 return D3D_OK;
3769 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3770 ICOM_THIS(IDirect3DDevice8Impl,iface);
3771 IDirect3DIndexBuffer8 *oldIdxs;
3773 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3774 oldIdxs = This->StateBlock.pIndexData;
3776 This->UpdateStateBlock->Changed.Indices = TRUE;
3777 This->UpdateStateBlock->Set.Indices = TRUE;
3778 This->UpdateStateBlock->pIndexData = pIndexData;
3779 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3781 /* Handle recording of state blocks */
3782 if (This->isRecordingState) {
3783 TRACE("Recording... not performing anything\n");
3784 return D3D_OK;
3787 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3788 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3789 return D3D_OK;
3791 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3792 ICOM_THIS(IDirect3DDevice8Impl,iface);
3793 FIXME("(%p) : stub\n", This);
3795 *ppIndexData = This->StateBlock.pIndexData;
3796 /* up ref count on ppindexdata */
3797 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3798 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3800 return D3D_OK;
3802 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3803 ICOM_THIS(IDirect3DDevice8Impl,iface);
3804 PIXELSHADER8* object;
3805 UINT i;
3807 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3808 if (NULL == pFunction || NULL == pHandle) {
3809 return D3DERR_INVALIDCALL;
3811 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(PIXELSHADER8*); ++i) ;
3812 if (i >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) {
3813 return D3DERR_OUTOFVIDEOMEMORY;
3815 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PIXELSHADER8));
3816 if (NULL == object) {
3817 return D3DERR_OUTOFVIDEOMEMORY;
3820 object->data = NULL; /* TODO */
3822 PixelShaders[i] = object;
3823 *pHandle = VS_HIGHESTFIXEDFXF + i;
3825 object->function = pFunction;
3826 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3827 object->functionLength = i + 1;
3829 return D3D_OK;
3831 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3832 ICOM_THIS(IDirect3DDevice8Impl,iface);
3834 This->UpdateStateBlock->PixelShader = Handle;
3835 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3836 This->UpdateStateBlock->Set.pixelShader = TRUE;
3838 /* Handle recording of state blocks */
3839 if (This->isRecordingState) {
3840 TRACE("Recording... not performing anything\n");
3841 return D3D_OK;
3844 /* FIXME: Quieten when not being used */
3845 if (Handle != 0) {
3846 FIXME("(%p) : stub %ld\n", This, Handle);
3847 } else {
3848 TRACE("(%p) : stub %ld\n", This, Handle);
3851 return D3D_OK;
3853 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3854 ICOM_THIS(IDirect3DDevice8Impl,iface);
3855 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock.PixelShader);
3856 *pHandle = This->StateBlock.PixelShader;
3857 return D3D_OK;
3860 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3861 ICOM_THIS(IDirect3DDevice8Impl,iface);
3862 PIXELSHADER8* object;
3864 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3865 return D3DERR_INVALIDCALL;
3867 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3868 TRACE("(%p) : freeing PixelShader %p\n", This, object);
3869 /* TODO: check validity of object before free */
3870 HeapFree(GetProcessHeap(), 0, (void *)object);
3871 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3872 return D3D_OK;
3874 #define PIXEL_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
3876 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
3877 ICOM_THIS(IDirect3DDevice8Impl,iface);
3878 FIXME("(%p) : stub\n", This);
3879 return D3D_OK;
3881 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
3882 ICOM_THIS(IDirect3DDevice8Impl,iface);
3883 FIXME("(%p) : stub\n", This);
3884 return D3D_OK;
3886 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3887 ICOM_THIS(IDirect3DDevice8Impl,iface);
3888 PIXELSHADER8* object;
3890 object = PIXEL_SHADER(Handle);
3891 if (NULL == object) {
3892 return D3DERR_INVALIDCALL;
3894 if (NULL == pData) {
3895 *pSizeOfData = object->functionLength;
3896 return D3D_OK;
3898 if (*pSizeOfData < object->functionLength) {
3899 *pSizeOfData = object->functionLength;
3900 return D3DERR_MOREDATA;
3902 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
3903 memcpy(pData, object->function, object->functionLength);
3904 return D3D_OK;
3906 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3907 ICOM_THIS(IDirect3DDevice8Impl,iface);
3908 FIXME("(%p) : stub\n", This); return D3D_OK;
3910 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3911 ICOM_THIS(IDirect3DDevice8Impl,iface);
3912 FIXME("(%p) : stub\n", This); return D3D_OK;
3914 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3915 ICOM_THIS(IDirect3DDevice8Impl,iface);
3916 FIXME("(%p) : stub\n", This); return D3D_OK;
3919 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3920 IDirect3DVertexBuffer8 *oldSrc;
3921 ICOM_THIS(IDirect3DDevice8Impl,iface);
3923 oldSrc = This->StateBlock.stream_source[StreamNumber];
3924 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3926 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3927 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3928 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3929 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3931 /* Handle recording of state blocks */
3932 if (This->isRecordingState) {
3933 TRACE("Recording... not performing anything\n");
3934 return D3D_OK;
3937 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3938 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3939 return D3D_OK;
3941 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3942 ICOM_THIS(IDirect3DDevice8Impl,iface);
3943 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3944 *pStream = This->StateBlock.stream_source[StreamNumber];
3945 *pStride = This->StateBlock.stream_stride[StreamNumber];
3946 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3947 return D3D_OK;
3951 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3953 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3954 IDirect3DDevice8Impl_QueryInterface,
3955 IDirect3DDevice8Impl_AddRef,
3956 IDirect3DDevice8Impl_Release,
3957 IDirect3DDevice8Impl_TestCooperativeLevel,
3958 IDirect3DDevice8Impl_GetAvailableTextureMem,
3959 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3960 IDirect3DDevice8Impl_GetDirect3D,
3961 IDirect3DDevice8Impl_GetDeviceCaps,
3962 IDirect3DDevice8Impl_GetDisplayMode,
3963 IDirect3DDevice8Impl_GetCreationParameters,
3964 IDirect3DDevice8Impl_SetCursorProperties,
3965 IDirect3DDevice8Impl_SetCursorPosition,
3966 IDirect3DDevice8Impl_ShowCursor,
3967 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3968 IDirect3DDevice8Impl_Reset,
3969 IDirect3DDevice8Impl_Present,
3970 IDirect3DDevice8Impl_GetBackBuffer,
3971 IDirect3DDevice8Impl_GetRasterStatus,
3972 IDirect3DDevice8Impl_SetGammaRamp,
3973 IDirect3DDevice8Impl_GetGammaRamp,
3974 IDirect3DDevice8Impl_CreateTexture,
3975 IDirect3DDevice8Impl_CreateVolumeTexture,
3976 IDirect3DDevice8Impl_CreateCubeTexture,
3977 IDirect3DDevice8Impl_CreateVertexBuffer,
3978 IDirect3DDevice8Impl_CreateIndexBuffer,
3979 IDirect3DDevice8Impl_CreateRenderTarget,
3980 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3981 IDirect3DDevice8Impl_CreateImageSurface,
3982 IDirect3DDevice8Impl_CopyRects,
3983 IDirect3DDevice8Impl_UpdateTexture,
3984 IDirect3DDevice8Impl_GetFrontBuffer,
3985 IDirect3DDevice8Impl_SetRenderTarget,
3986 IDirect3DDevice8Impl_GetRenderTarget,
3987 IDirect3DDevice8Impl_GetDepthStencilSurface,
3988 IDirect3DDevice8Impl_BeginScene,
3989 IDirect3DDevice8Impl_EndScene,
3990 IDirect3DDevice8Impl_Clear,
3991 IDirect3DDevice8Impl_SetTransform,
3992 IDirect3DDevice8Impl_GetTransform,
3993 IDirect3DDevice8Impl_MultiplyTransform,
3994 IDirect3DDevice8Impl_SetViewport,
3995 IDirect3DDevice8Impl_GetViewport,
3996 IDirect3DDevice8Impl_SetMaterial,
3997 IDirect3DDevice8Impl_GetMaterial,
3998 IDirect3DDevice8Impl_SetLight,
3999 IDirect3DDevice8Impl_GetLight,
4000 IDirect3DDevice8Impl_LightEnable,
4001 IDirect3DDevice8Impl_GetLightEnable,
4002 IDirect3DDevice8Impl_SetClipPlane,
4003 IDirect3DDevice8Impl_GetClipPlane,
4004 IDirect3DDevice8Impl_SetRenderState,
4005 IDirect3DDevice8Impl_GetRenderState,
4006 IDirect3DDevice8Impl_BeginStateBlock,
4007 IDirect3DDevice8Impl_EndStateBlock,
4008 IDirect3DDevice8Impl_ApplyStateBlock,
4009 IDirect3DDevice8Impl_CaptureStateBlock,
4010 IDirect3DDevice8Impl_DeleteStateBlock,
4011 IDirect3DDevice8Impl_CreateStateBlock,
4012 IDirect3DDevice8Impl_SetClipStatus,
4013 IDirect3DDevice8Impl_GetClipStatus,
4014 IDirect3DDevice8Impl_GetTexture,
4015 IDirect3DDevice8Impl_SetTexture,
4016 IDirect3DDevice8Impl_GetTextureStageState,
4017 IDirect3DDevice8Impl_SetTextureStageState,
4018 IDirect3DDevice8Impl_ValidateDevice,
4019 IDirect3DDevice8Impl_GetInfo,
4020 IDirect3DDevice8Impl_SetPaletteEntries,
4021 IDirect3DDevice8Impl_GetPaletteEntries,
4022 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4023 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4024 IDirect3DDevice8Impl_DrawPrimitive,
4025 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4026 IDirect3DDevice8Impl_DrawPrimitiveUP,
4027 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4028 IDirect3DDevice8Impl_ProcessVertices,
4029 IDirect3DDevice8Impl_CreateVertexShader,
4030 IDirect3DDevice8Impl_SetVertexShader,
4031 IDirect3DDevice8Impl_GetVertexShader,
4032 IDirect3DDevice8Impl_DeleteVertexShader,
4033 IDirect3DDevice8Impl_SetVertexShaderConstant,
4034 IDirect3DDevice8Impl_GetVertexShaderConstant,
4035 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4036 IDirect3DDevice8Impl_GetVertexShaderFunction,
4037 IDirect3DDevice8Impl_SetStreamSource,
4038 IDirect3DDevice8Impl_GetStreamSource,
4039 IDirect3DDevice8Impl_SetIndices,
4040 IDirect3DDevice8Impl_GetIndices,
4041 IDirect3DDevice8Impl_CreatePixelShader,
4042 IDirect3DDevice8Impl_SetPixelShader,
4043 IDirect3DDevice8Impl_GetPixelShader,
4044 IDirect3DDevice8Impl_DeletePixelShader,
4045 IDirect3DDevice8Impl_SetPixelShaderConstant,
4046 IDirect3DDevice8Impl_GetPixelShaderConstant,
4047 IDirect3DDevice8Impl_GetPixelShaderFunction,
4048 IDirect3DDevice8Impl_DrawRectPatch,
4049 IDirect3DDevice8Impl_DrawTriPatch,
4050 IDirect3DDevice8Impl_DeletePatch
4053 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
4054 D3DLINEPATTERN lp;
4055 int i;
4057 ICOM_THIS(IDirect3DDevice8Impl,iface);
4059 /* Note this may have a large overhead but it should only be executed
4060 once, in order to initialize the complete state of the device and
4061 all opengl equivalents */
4062 TRACE("-----------------------> Setting up device defaults...\n");
4063 This->StateBlock.blockType = D3DSBT_ALL;
4065 /* FIXME: Set some of the defaults for lights, transforms etc */
4066 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
4067 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
4068 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
4070 /* Render states: */
4071 if (This->PresentParms.EnableAutoDepthStencil) {
4072 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
4073 } else {
4074 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
4076 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
4077 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
4078 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
4079 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
4080 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
4081 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
4082 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
4083 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
4084 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
4085 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
4086 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
4087 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
4088 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
4089 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
4090 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
4091 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
4092 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
4093 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
4094 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
4095 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
4096 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
4097 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
4098 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
4099 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
4100 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
4101 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
4102 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
4103 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
4104 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
4105 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
4106 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
4107 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
4108 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
4109 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
4110 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
4111 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
4112 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
4113 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
4114 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
4115 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
4116 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
4117 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
4118 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
4119 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
4120 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
4121 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
4122 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
4123 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
4124 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
4125 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
4126 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
4127 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
4128 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
4129 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
4130 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
4131 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
4132 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
4133 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
4134 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
4135 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
4136 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
4137 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
4138 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
4139 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
4140 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
4141 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
4142 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
4143 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
4144 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
4145 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
4146 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
4147 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
4148 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4149 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
4150 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
4152 /* Texture Stage States - Put directly into state block, we will call function below */
4153 for (i=0; i<This->TextureUnits;i++) {
4154 memcpy(&This->StateBlock.transforms[D3DTS_TEXTURE0+i], &idmatrix, sizeof(idmatrix));
4155 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
4156 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
4157 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
4158 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
4159 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
4160 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
4161 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
4162 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
4163 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
4164 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
4165 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
4166 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
4167 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
4168 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
4169 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
4170 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
4171 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
4172 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
4173 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
4174 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
4175 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
4176 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
4177 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
4178 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
4179 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
4180 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
4181 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
4184 /* Under DirectX you can have texture stage operations even if no texture is
4185 bound, whereas opengl will only do texture operations when a valid texture is
4186 bound. We emulate this by creating dummy textures and binding them to each
4187 texture stage, but disable all stages by default. Hence if a stage is enabled
4188 then the default texture will kick in until replaced by a SetTexture call */
4190 for (i=0; i<This->TextureUnits; i++) {
4191 GLubyte white = 255;
4193 /* Note this avoids calling settexture, so pretend it has been called */
4194 This->StateBlock.Set.textures[i] = TRUE;
4195 This->StateBlock.Changed.textures[i] = TRUE;
4196 This->StateBlock.textures[i] = NULL;
4198 /* Make appropriate texture active */
4199 if (This->isMultiTexture) {
4200 glActiveTextureARB(GL_TEXTURE0_ARB + i);
4201 checkGLcall("glActiveTextureARB");
4202 } else if (i>0) {
4203 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
4206 /* Generate an opengl texture name */
4207 glGenTextures(1, &This->dummyTextureName[i]);
4208 checkGLcall("glGenTextures");
4209 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
4211 /* Generate a dummy 1d texture */
4212 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
4213 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
4214 checkGLcall("glBindTexture");
4216 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
4217 checkGLcall("glTexImage1D");
4219 /* Reapply all the texture state information to this texture */
4220 setupTextureStates(iface, i);
4223 TRACE("-----------------------> Device defaults now set up...\n");
4228 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
4229 D3DRS_ALPHABLENDENABLE ,
4230 D3DRS_ALPHAFUNC ,
4231 D3DRS_ALPHAREF ,
4232 D3DRS_ALPHATESTENABLE ,
4233 D3DRS_BLENDOP ,
4234 D3DRS_COLORWRITEENABLE ,
4235 D3DRS_DESTBLEND ,
4236 D3DRS_DITHERENABLE ,
4237 D3DRS_EDGEANTIALIAS ,
4238 D3DRS_FILLMODE ,
4239 D3DRS_FOGDENSITY ,
4240 D3DRS_FOGEND ,
4241 D3DRS_FOGSTART ,
4242 D3DRS_LASTPIXEL ,
4243 D3DRS_LINEPATTERN ,
4244 D3DRS_SHADEMODE ,
4245 D3DRS_SRCBLEND ,
4246 D3DRS_STENCILENABLE ,
4247 D3DRS_STENCILFAIL ,
4248 D3DRS_STENCILFUNC ,
4249 D3DRS_STENCILMASK ,
4250 D3DRS_STENCILPASS ,
4251 D3DRS_STENCILREF ,
4252 D3DRS_STENCILWRITEMASK ,
4253 D3DRS_STENCILZFAIL ,
4254 D3DRS_TEXTUREFACTOR ,
4255 D3DRS_WRAP0 ,
4256 D3DRS_WRAP1 ,
4257 D3DRS_WRAP2 ,
4258 D3DRS_WRAP3 ,
4259 D3DRS_WRAP4 ,
4260 D3DRS_WRAP5 ,
4261 D3DRS_WRAP6 ,
4262 D3DRS_WRAP7 ,
4263 D3DRS_ZBIAS ,
4264 D3DRS_ZENABLE ,
4265 D3DRS_ZFUNC ,
4266 D3DRS_ZWRITEENABLE
4269 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
4270 D3DTSS_ADDRESSU ,
4271 D3DTSS_ADDRESSV ,
4272 D3DTSS_ADDRESSW ,
4273 D3DTSS_ALPHAARG0 ,
4274 D3DTSS_ALPHAARG1 ,
4275 D3DTSS_ALPHAARG2 ,
4276 D3DTSS_ALPHAOP ,
4277 D3DTSS_BORDERCOLOR ,
4278 D3DTSS_BUMPENVLOFFSET ,
4279 D3DTSS_BUMPENVLSCALE ,
4280 D3DTSS_BUMPENVMAT00 ,
4281 D3DTSS_BUMPENVMAT01 ,
4282 D3DTSS_BUMPENVMAT10 ,
4283 D3DTSS_BUMPENVMAT11 ,
4284 D3DTSS_COLORARG0 ,
4285 D3DTSS_COLORARG1 ,
4286 D3DTSS_COLORARG2 ,
4287 D3DTSS_COLOROP ,
4288 D3DTSS_MAGFILTER ,
4289 D3DTSS_MAXANISOTROPY ,
4290 D3DTSS_MAXMIPLEVEL ,
4291 D3DTSS_MINFILTER ,
4292 D3DTSS_MIPFILTER ,
4293 D3DTSS_MIPMAPLODBIAS ,
4294 D3DTSS_RESULTARG ,
4295 D3DTSS_TEXCOORDINDEX ,
4296 D3DTSS_TEXTURETRANSFORMFLAGS
4299 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
4300 D3DRS_AMBIENT ,
4301 D3DRS_AMBIENTMATERIALSOURCE ,
4302 D3DRS_CLIPPING ,
4303 D3DRS_CLIPPLANEENABLE ,
4304 D3DRS_COLORVERTEX ,
4305 D3DRS_DIFFUSEMATERIALSOURCE ,
4306 D3DRS_EMISSIVEMATERIALSOURCE ,
4307 D3DRS_FOGDENSITY ,
4308 D3DRS_FOGEND ,
4309 D3DRS_FOGSTART ,
4310 D3DRS_FOGTABLEMODE ,
4311 D3DRS_FOGVERTEXMODE ,
4312 D3DRS_INDEXEDVERTEXBLENDENABLE ,
4313 D3DRS_LIGHTING ,
4314 D3DRS_LOCALVIEWER ,
4315 D3DRS_MULTISAMPLEANTIALIAS ,
4316 D3DRS_MULTISAMPLEMASK ,
4317 D3DRS_NORMALIZENORMALS ,
4318 D3DRS_PATCHEDGESTYLE ,
4319 D3DRS_PATCHSEGMENTS ,
4320 D3DRS_POINTSCALE_A ,
4321 D3DRS_POINTSCALE_B ,
4322 D3DRS_POINTSCALE_C ,
4323 D3DRS_POINTSCALEENABLE ,
4324 D3DRS_POINTSIZE ,
4325 D3DRS_POINTSIZE_MAX ,
4326 D3DRS_POINTSIZE_MIN ,
4327 D3DRS_POINTSPRITEENABLE ,
4328 D3DRS_RANGEFOGENABLE ,
4329 D3DRS_SOFTWAREVERTEXPROCESSING ,
4330 D3DRS_SPECULARMATERIALSOURCE ,
4331 D3DRS_TWEENFACTOR ,
4332 D3DRS_VERTEXBLEND
4335 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
4336 D3DTSS_TEXCOORDINDEX ,
4337 D3DTSS_TEXTURETRANSFORMFLAGS