Beginning of more COM compliant behavior:
[wine/wine-kai.git] / dlls / d3d8 / device.c
blobb6bd0d6f902cdac531337c0711e2a39ac00de5cc
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 "config.h"
23 #include <math.h>
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "wingdi.h"
31 #include "wine/debug.h"
33 #include "d3d8_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
37 /* Some #defines for additional diagnostics */
39 /* Per-vertex trace: */
40 #if 0
41 #define VTRACE(A) TRACE A
42 #else
43 #define VTRACE(A)
44 #endif
47 static VERTEXSHADER8* VertexShaders[64];
48 static PIXELSHADER8* PixelShaders[64];
50 /* CreateVertexShader can return > 0xFFFF */
51 #define VS_HIGHESTFIXEDFXF 0xF0000000
53 /* Used for CreateStateBlock */
54 #define NUM_SAVEDPIXELSTATES_R 38
55 #define NUM_SAVEDPIXELSTATES_T 27
56 #define NUM_SAVEDVERTEXSTATES_R 33
57 #define NUM_SAVEDVERTEXSTATES_T 2
60 * Utility functions or macros
62 #define conv_mat(mat,gl_mat) \
63 do { \
64 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
65 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
66 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
67 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
68 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
69 } while (0)
71 #define VERTEX_SHADER(Handle) \
72 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
74 #define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
77 * Globals
79 extern DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R];
80 extern DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T];
81 extern DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R];
82 extern DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T];
84 static const float idmatrix[16] = {
85 1.0, 0.0, 0.0, 0.0,
86 0.0, 1.0, 0.0, 0.0,
87 0.0, 0.0, 1.0, 0.0,
88 0.0, 0.0, 0.0, 1.0
92 /* Routine common to the draw primitive and draw indexed primitive routines */
93 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
94 int PrimitiveType,
95 long NumPrimitives,
96 BOOL isIndexed,
98 /* For Both:*/
99 D3DFORMAT fvf,
100 const void *vertexBufData,
102 /* for Indexed: */
103 long StartVertexIndex,
104 long StartIdx,
105 short idxBytes,
106 const void *idxData,
107 int minIndex) {
109 int NumVertexes = NumPrimitives;
110 VERTEXSHADER8* vertex_shader = NULL;
111 BOOL useVertexShaderFunction = FALSE;
113 ICOM_THIS(IDirect3DDevice8Impl,iface);
115 /* Dont understand how to handle multiple streams, but if a fixed
116 FVF is passed in rather than a handle, it must use stream 0 */
118 if (This->StateBlock.VertexShader > VS_HIGHESTFIXEDFXF) {
119 vertex_shader = VERTEX_SHADER(This->StateBlock.VertexShader);
120 if (NULL == vertex_shader) {
121 ERR("trying to use unitialised vertex shader: %lu\n", This->StateBlock.VertexShader);
122 return ;
124 if (NULL == vertex_shader->function) {
125 TRACE("vertex shader declared without program, using FVF pure mode\n");
126 } else {
127 useVertexShaderFunction = TRUE;
129 fvf = (D3DFORMAT) vertex_shader->fvf;
130 TRACE("vertex shader declared FVF: %lx\n", vertex_shader->fvf);
131 memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8));
135 int skip = This->StateBlock.stream_stride[0];
136 GLenum primType = GL_POINTS;
137 BOOL normal;
138 BOOL isRHW;
139 BOOL isPtSize;
140 BOOL isDiffuse;
141 BOOL isSpecular;
142 int numBlends;
143 BOOL isLastUByte4;
144 int numTextures;
145 int textureNo;
146 const void *curVtx = NULL;
147 const short *pIdxBufS = NULL;
148 const long *pIdxBufL = NULL;
149 const void *curPos;
150 BOOL isLightingOn = FALSE;
151 BOOL enableTexture = FALSE;
152 int vx_index;
154 float x=0.0, y=0.0, z=0.0; /* x,y,z coordinates */
155 float nx=0.0, ny=0.0, nz=0.0; /* normal x,y,z coordinates */
156 float rhw=0.0; /* rhw */
157 float ptSize=0.0; /* Point size */
158 DWORD diffuseColor=0; /* Diffusre Color */
159 DWORD specularColor=0; /* Specular Color */
161 ENTER_GL();
163 if (isIndexed) {
164 if (idxBytes == 2) pIdxBufS = (short *) idxData;
165 else pIdxBufL = (long *) idxData;
168 /* Check vertex formats expected ? */
169 normal = fvf & D3DFVF_NORMAL;
170 isRHW = fvf & D3DFVF_XYZRHW;
171 numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2; /* WARNING can be < 0 because -2 */
172 isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
173 isPtSize = fvf & D3DFVF_PSIZE;
174 isDiffuse = fvf & D3DFVF_DIFFUSE;
175 isSpecular = fvf & D3DFVF_SPECULAR;
176 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
178 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d)\n",
179 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends);
181 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
182 set by the appropriate render state */
183 if (!normal) {
184 isLightingOn = glIsEnabled(GL_LIGHTING);
185 glDisable(GL_LIGHTING);
186 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
189 if (isRHW) {
190 double height, width, minZ, maxZ;
192 * Already transformed vertex do not need transform
193 * matrices. Reset all matrices to identity.
194 * Leave the default matrix in world mode.
196 glMatrixMode(GL_PROJECTION);
197 checkGLcall("glMatrixMode");
198 glLoadIdentity();
199 checkGLcall("glLoadIdentity");
200 glMatrixMode(GL_MODELVIEW);
201 checkGLcall("glMatrixMode");
202 glLoadIdentity();
203 checkGLcall("glLoadIdentity");
204 height = This->StateBlock.viewport.Height;
205 width = This->StateBlock.viewport.Width;
206 minZ = This->StateBlock.viewport.MinZ;
207 maxZ = This->StateBlock.viewport.MaxZ;
208 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
209 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
210 checkGLcall("glOrtho");
211 } else {
212 glMatrixMode(GL_PROJECTION);
213 checkGLcall("glMatrixMode");
214 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
215 checkGLcall("glLoadMatrixf");
216 glMatrixMode(GL_MODELVIEW);
217 checkGLcall("glMatrixMode");
218 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
219 checkGLcall("glLoadMatrixf");
220 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
221 checkGLcall("glMultMatrixf");
224 /* Set OpenGL to the appropriate Primitive Type */
225 switch (PrimitiveType) {
226 case D3DPT_POINTLIST:
227 TRACE("POINTS\n");
228 primType = GL_POINTS;
229 NumVertexes = NumPrimitives;
230 break;
232 case D3DPT_LINELIST:
233 TRACE("LINES\n");
234 primType = GL_LINES;
235 NumVertexes = NumPrimitives * 2;
236 break;
238 case D3DPT_LINESTRIP:
239 TRACE("LINE_STRIP\n");
240 primType = GL_LINE_STRIP;
241 NumVertexes = NumPrimitives + 1;
242 break;
244 case D3DPT_TRIANGLELIST:
245 TRACE("TRIANGLES\n");
246 primType = GL_TRIANGLES;
247 NumVertexes = NumPrimitives * 3;
248 break;
250 case D3DPT_TRIANGLESTRIP:
251 TRACE("TRIANGLE_STRIP\n");
252 primType = GL_TRIANGLE_STRIP;
253 NumVertexes = NumPrimitives + 2;
254 break;
256 case D3DPT_TRIANGLEFAN:
257 TRACE("TRIANGLE_FAN\n");
258 primType = GL_TRIANGLE_FAN;
259 NumVertexes = NumPrimitives + 2;
260 break;
262 default:
263 FIXME("Unhandled primitive\n");
264 break;
267 /* Fixme, Ideally, only use this per-vertex code for software HAL
268 but until opengl supports all the functions returned to setup
269 vertex arrays, we need to drop down to the slow mechanism for
270 certain functions */
272 if (isPtSize || isDiffuse || useVertexShaderFunction==TRUE || (numBlends > 0)) {
273 TRACE("Using slow per-vertex code\n");
275 /* Enable this one to be able to debug what is going on, but it is slower
276 than the pointer/array version */
277 VTRACE(("glBegin(%x)\n", primType));
278 glBegin(primType);
280 /* Draw the primitives */
281 curVtx = vertexBufData + (StartVertexIndex * skip);
283 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
285 if (!isIndexed) {
286 curPos = curVtx;
287 } else {
288 if (idxBytes == 2) {
289 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
290 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
291 } else {
292 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
293 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
297 /* Work through the vertex buffer */
298 x = *(float *)curPos;
299 curPos = curPos + sizeof(float);
300 y = *(float *)curPos;
301 curPos = curPos + sizeof(float);
302 z = *(float *)curPos;
303 curPos = curPos + sizeof(float);
304 VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
306 /* RHW follows, only if transformed */
307 if (isRHW) {
308 rhw = *(float *)curPos;
309 curPos = curPos + sizeof(float);
310 VTRACE(("rhw=%f\n", rhw));
313 /* Blending data */
314 if (numBlends > 0) {
315 UINT i;
316 D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
317 DWORD skippedBlendLastUByte4 = 0;
319 for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
320 ((float*)&skippedBlend)[i] = *(float *)curPos;
321 curPos = curPos + sizeof(float);
324 if (isLastUByte4) {
325 skippedBlendLastUByte4 = *(DWORD*)curPos;
326 curPos = curPos + sizeof(DWORD);
330 /* Vertex Normal Data (untransformed only) */
331 if (normal) {
332 nx = *(float *)curPos;
333 curPos = curPos + sizeof(float);
334 ny = *(float *)curPos;
335 curPos = curPos + sizeof(float);
336 nz = *(float *)curPos;
337 curPos = curPos + sizeof(float);
338 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
341 if (isPtSize) {
342 ptSize = *(float *)curPos;
343 VTRACE(("ptSize=%f\n", ptSize));
344 curPos = curPos + sizeof(float);
347 if (isDiffuse) {
348 diffuseColor = *(DWORD *)curPos;
349 VTRACE(("diffuseColor=%lx\n", diffuseColor));
350 curPos = curPos + sizeof(DWORD);
353 if (isSpecular) {
354 specularColor = *(DWORD *)curPos;
355 VTRACE(("specularColor=%lx\n", specularColor));
356 curPos = curPos + sizeof(DWORD);
359 /* ToDo: Texture coords */
360 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
361 float s, t, r, q;
363 if (!(This->isMultiTexture) && textureNo > 0) {
364 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
365 continue ;
367 if (textureNo > This->TextureUnits) {
368 FIXME("Program using more concurrent textures than this opengl implementation support\n");
369 break ;
372 /* Query tex coords */
373 if (This->StateBlock.textures[textureNo] != NULL) {
374 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
375 case D3DRTYPE_TEXTURE:
376 s = *(float *)curPos;
377 curPos = curPos + sizeof(float);
378 t = *(float *)curPos;
379 curPos = curPos + sizeof(float);
380 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s,t));
382 if (TRUE == useVertexShaderFunction) {
383 /* Nothing to do */
384 } else {
385 if (This->isMultiTexture) {
386 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
387 } else {
388 glTexCoord2f(s, t);
391 break;
393 case D3DRTYPE_VOLUMETEXTURE:
394 s = *(float *)curPos;
395 curPos = curPos + sizeof(float);
396 t = *(float *)curPos;
397 curPos = curPos + sizeof(float);
398 r = *(float *)curPos;
399 curPos = curPos + sizeof(float);
400 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r));
402 if (TRUE == useVertexShaderFunction) {
403 /* Nothing to do */
404 } else {
405 if (This->isMultiTexture) {
406 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
407 } else {
408 glTexCoord3f(s, t, r);
411 break;
413 default:
414 r = 0.0f; q = 0.0f; /* Avoid compiler warnings, need these vars later for other textures */
415 FIXME("Unhandled texture type\n");
417 } else {
418 /* Note I have seen a program actually do this, so just hide it and continue */
419 VTRACE(("Very odd - texture requested in FVF but not bound!\n"));
424 /** if vertex shader program specified ... using it */
425 if (TRUE == useVertexShaderFunction) {
428 * this code must become the really
429 * vs input params init
431 * because its possible to use input registers for anything
432 * and some samples use registers for other things than they are
433 * declared
436 /**
437 * no really valid declaration, user defined input register use
438 * so fill input registers as described in vertex shader declaration
440 vshader_fill_input(vertex_shader, This, vertexBufData, StartVertexIndex,
441 (!isIndexed) ? (vx_index * skip) :
442 (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) :
443 ((pIdxBufL[StartIdx + vx_index]) * skip));
445 memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
446 vshader_program_execute_SW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
448 TRACE_VECTOR(vertex_shader->output.oPos);
449 TRACE_VECTOR(vertex_shader->output.oD[0]);
450 TRACE_VECTOR(vertex_shader->output.oD[1]);
451 TRACE_VECTOR(vertex_shader->output.oT[0]);
452 TRACE_VECTOR(vertex_shader->output.oT[1]);
454 x = vertex_shader->output.oPos.x;
455 y = vertex_shader->output.oPos.y;
456 z = vertex_shader->output.oPos.z;
458 if (1.0f != vertex_shader->output.oPos.w || isRHW) {
459 rhw = vertex_shader->output.oPos.w;
461 /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
462 glColor4fv((float*) &vertex_shader->output.oD[0]);
464 /* Requires secondary color extensions to compile... */
465 if (checkGLSupport(EXT_SECONDARY_COLOR)) {
466 /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/
467 GLExtCall(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]);
468 /*checkGLcall("glSecondaryColor3fvEXT");*/
471 /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
472 for (textureNo = 0; textureNo < 4; ++textureNo) {
473 float s, t, r, q;
475 if (!(This->isMultiTexture) && textureNo > 0) {
476 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
477 continue ;
479 /* Query tex coords */
480 if (This->StateBlock.textures[textureNo] != NULL) {
481 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
482 case D3DRTYPE_TEXTURE:
483 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
484 s = vertex_shader->output.oT[textureNo].x;
485 t = vertex_shader->output.oT[textureNo].y;
486 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t));
487 if (This->isMultiTexture) {
488 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
489 /*checkGLcall("glMultiTexCoord2fARB");*/
490 } else {
491 glTexCoord2f(s, t);
492 /*checkGLcall("gTexCoord2f");*/
494 break;
496 case D3DRTYPE_VOLUMETEXTURE:
497 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
498 s = vertex_shader->output.oT[textureNo].x;
499 t = vertex_shader->output.oT[textureNo].y;
500 r = vertex_shader->output.oT[textureNo].z;
501 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r));
502 if (This->isMultiTexture) {
503 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
504 /*checkGLcall("glMultiTexCoord2fARB");*/
505 } else {
506 glTexCoord3f(s, t, r);
507 /*checkGLcall("gTexCoord3f");*/
509 break;
511 default:
512 /* Avoid compiler warnings, need these vars later for other textures */
513 r = 0.0f; q = 0.0f;
514 FIXME("Unhandled texture type\n");
519 if (1.0f == rhw || rhw < 0.01f) {
520 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
521 glVertex3f(x, y, z);
522 /*checkGLcall("glVertex3f");*/
523 } else {
524 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
525 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
526 /*checkGLcall("glVertex4f");*/
528 } else {
529 /**
530 * FALSE == useVertexShaderFunction
531 * using std FVF code
534 /* Handle these vertexes */
535 if (isDiffuse) {
536 glColor4ub((diffuseColor >> 16) & 0xFF,
537 (diffuseColor >> 8) & 0xFF,
538 (diffuseColor >> 0) & 0xFF,
539 (diffuseColor >> 24) & 0xFF);
540 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
541 ((diffuseColor >> 16) & 0xFF) / 255.0f,
542 ((diffuseColor >> 8) & 0xFF) / 255.0f,
543 ((diffuseColor >> 0) & 0xFF) / 255.0f,
544 ((diffuseColor >> 24) & 0xFF) / 255.0f));
547 if (normal) {
548 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
549 glNormal3f(nx, ny, nz);
550 glVertex3f(x, y, z);
551 } else {
552 if (1.0f == rhw || rhw < 0.01f) {
553 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
554 glVertex3f(x, y, z);
555 } else {
556 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
557 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
562 if (!isIndexed) {
563 curVtx = curVtx + skip;
567 glEnd();
568 checkGLcall("glEnd and previous calls");
570 } else {
571 TRACE("Using fast vertex array code\n");
573 /* Faster version, harder to debug */
574 /* Shuffle to the beginning of the vertexes to render and index from there */
575 curVtx = vertexBufData + (StartVertexIndex * skip);
576 curPos = curVtx;
578 /* Set up the vertex pointers */
579 if (isRHW) {
580 glVertexPointer(4, GL_FLOAT, skip, curPos);
581 checkGLcall("glVertexPointer(4, ...)");
582 curPos += 4*sizeof(float);
583 } else {
584 glVertexPointer(3, GL_FLOAT, skip, curPos);
585 checkGLcall("glVertexPointer(3, ...)");
586 curPos += 3*sizeof(float);
588 glEnableClientState(GL_VERTEX_ARRAY);
589 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
591 if (numBlends>0) {
592 /* no such functionality in the fixed function GL pipeline */
593 /* FIXME: Wont get here as will drop to slow method */
594 FIXME("Cannot handle blending data here in openGl\n");
598 if (normal) {
599 glNormalPointer(GL_FLOAT, skip, curPos);
600 checkGLcall("glNormalPointer");
601 glEnableClientState(GL_NORMAL_ARRAY);
602 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
603 curPos += 3*sizeof(float);
604 } else {
605 glDisableClientState(GL_NORMAL_ARRAY);
606 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
607 glNormal3f(0, 0, 1);
608 checkGLcall("glNormal3f(0, 0, 1)");
611 if (isPtSize) {
612 /* no such functionality in the fixed function GL pipeline */
613 /* FIXME: Wont get here as will drop to slow method */
614 FIXME("Cannot change ptSize here in openGl\n");
615 curPos = curPos + sizeof(float);
618 if (isDiffuse) {
619 glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
620 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
621 glEnableClientState(GL_COLOR_ARRAY);
622 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
623 curPos += sizeof(DWORD);
625 else {
626 glDisableClientState(GL_COLOR_ARRAY);
627 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
628 glColor4f(1, 1, 1, 1);
629 checkGLcall("glColor4f(1, 1, 1, 1)");
632 /* Requires secondary color extensions to compile... */
633 #if 0
634 if (isSpecular) {
635 /* FIXME: check for GL_EXT_secondary_color */
636 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos);
637 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
638 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
639 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
640 curPos += sizeof(DWORD);
641 } else {
642 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
643 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
644 glSecondaryColor3fEXT(0, 0, 0);
645 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
647 #endif
649 /* ToDo: Texture coords */
650 for (textureNo = 0;textureNo<numTextures; textureNo++) {
652 /* Query tex coords */
653 glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
654 if (This->StateBlock.textures[textureNo] != NULL) {
655 enableTexture = TRUE;
656 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
657 case D3DRTYPE_TEXTURE:
658 glTexCoordPointer(2, GL_FLOAT, skip, curPos);
659 checkGLcall("glTexCoordPointer(2, ...)");
660 curPos += 2*sizeof(float);
661 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
662 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
663 break;
665 case D3DRTYPE_VOLUMETEXTURE:
666 glTexCoordPointer(3, GL_FLOAT, skip, curPos);
667 checkGLcall("glTexCoordPointer(3, ...)");
668 curPos += 3*sizeof(float);
669 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
670 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
671 break;
673 default:
674 FIXME("Unhandled texture type\n");
675 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
676 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
679 } else {
681 /* Note I have seen a program actually do this, so just hide it and continue */
682 TRACE("Very odd - texture requested in FVF but not bound!\n");
683 glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1);
684 checkGLcall("glMultiTexCoord4f(... , 0, 0, 0, 1)");
685 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
686 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
692 /* Finally do the drawing */
693 if (isIndexed) {
695 TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
696 if (idxBytes==2) {
697 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
698 glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT, idxData+(2 * StartIdx));
699 #else
700 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
701 GL_UNSIGNED_SHORT, idxData+(2 * StartIdx));
702 #endif
703 } else {
704 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
705 glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT, idxData+(4 * StartIdx));
706 #else
707 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
708 GL_UNSIGNED_INT, idxData+(2 * StartIdx));
709 #endif
711 checkGLcall("glDrawRangeElements");
713 } else {
715 /* Note first is now zero as we shuffled along earlier */
716 TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
717 glDrawArrays(primType, 0, NumVertexes);
718 checkGLcall("glDrawArrays");
723 /* If no normals, restore previous lighting state */
724 if (!normal) {
725 if (isLightingOn) glEnable(GL_LIGHTING);
726 else glDisable(GL_LIGHTING);
727 TRACE("Restored lighting to original state\n");
731 LEAVE_GL();
733 TRACE("glEnd\n");
737 Simple utility routines used for dx -> gl mapping of byte formats
739 SHORT bytesPerPixel(D3DFORMAT fmt) {
740 SHORT retVal;
742 switch (fmt) {
743 case D3DFMT_A4R4G4B4: retVal = 2; break;
744 case D3DFMT_A8R8G8B8: retVal = 4; break;
745 case D3DFMT_X8R8G8B8: retVal = 4; break;
746 case D3DFMT_R8G8B8: retVal = 3; break;
747 case D3DFMT_R5G6B5: retVal = 2; break;
748 case D3DFMT_A1R5G5B5: retVal = 2; break;
749 case D3DFMT_UNKNOWN:
750 /* Guess at the highest value of the above */
751 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt);
752 retVal = 4;
753 break;
754 default:
755 FIXME("Unhandled fmt %d\n", fmt);
756 retVal = 4;
758 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
759 return retVal;
762 GLint fmt2glintFmt(D3DFORMAT fmt) {
763 GLint retVal;
765 switch (fmt) {
766 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
767 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
768 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
769 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
770 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
771 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
772 default:
773 FIXME("Unhandled fmt %d\n", fmt);
774 retVal = 4;
776 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
777 return retVal;
779 GLenum fmt2glFmt(D3DFORMAT fmt) {
780 GLenum retVal;
782 switch (fmt) {
783 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
784 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
785 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
786 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
787 case D3DFMT_R5G6B5: retVal = GL_BGR; break;
788 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
789 default:
790 FIXME("Unhandled fmt %d\n", fmt);
791 retVal = 4;
793 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
794 return retVal;
796 DWORD fmt2glType(D3DFORMAT fmt) {
797 GLenum retVal;
799 switch (fmt) {
800 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
801 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
802 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
803 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
804 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
805 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
806 default:
807 FIXME("Unhandled fmt %d\n", fmt);
808 retVal = 4;
810 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
811 return retVal;
814 int SOURCEx_RGB_EXT(DWORD arg) {
815 switch(arg) {
816 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
817 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
818 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
819 case D3DTSS_ALPHAARG0:
820 case D3DTSS_ALPHAARG1:
821 case D3DTSS_ALPHAARG2:
822 default:
823 FIXME("Invalid arg %ld\n", arg);
824 return GL_SOURCE0_RGB_EXT;
827 int OPERANDx_RGB_EXT(DWORD arg) {
828 switch(arg) {
829 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
830 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
831 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
832 case D3DTSS_ALPHAARG0:
833 case D3DTSS_ALPHAARG1:
834 case D3DTSS_ALPHAARG2:
835 default:
836 FIXME("Invalid arg %ld\n", arg);
837 return GL_OPERAND0_RGB_EXT;
840 int SOURCEx_ALPHA_EXT(DWORD arg) {
841 switch(arg) {
842 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
843 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
844 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
845 case D3DTSS_COLORARG0:
846 case D3DTSS_COLORARG1:
847 case D3DTSS_COLORARG2:
848 default:
849 FIXME("Invalid arg %ld\n", arg);
850 return GL_SOURCE0_ALPHA_EXT;
853 int OPERANDx_ALPHA_EXT(DWORD arg) {
854 switch(arg) {
855 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
856 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
857 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
858 case D3DTSS_COLORARG0:
859 case D3DTSS_COLORARG1:
860 case D3DTSS_COLORARG2:
861 default:
862 FIXME("Invalid arg %ld\n", arg);
863 return GL_OPERAND0_ALPHA_EXT;
866 GLenum StencilOp(DWORD op) {
867 switch(op) {
868 case D3DSTENCILOP_KEEP : return GL_KEEP;
869 case D3DSTENCILOP_ZERO : return GL_ZERO;
870 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
871 case D3DSTENCILOP_INCRSAT : return GL_INCR;
872 case D3DSTENCILOP_DECRSAT : return GL_DECR;
873 case D3DSTENCILOP_INVERT : return GL_INVERT;
874 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op %ld\n", op);
875 return GL_INCR; /* Fixme - needs to support wrap */
876 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op %ld\n", op);
877 return GL_DECR; /* Fixme - needs to support wrap */
878 default:
879 FIXME("Invalid stencil op %ld\n", op);
880 return GL_ALWAYS;
884 /* Apply the current values to the specified texture stage */
885 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
886 ICOM_THIS(IDirect3DDevice8Impl,iface);
887 int i=0;
888 float col[4];
890 /* Make appropriate texture active */
891 if (This->isMultiTexture) {
892 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
893 checkGLcall("glActiveTextureARB");
894 } else if (Stage > 0) {
895 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
898 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
899 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
900 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock.texture_state[Stage][i]);
903 /* Note the D3DRS value applies to all textures, but GL has one
904 per texture, so apply it now ready to be used! */
905 col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
906 col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
907 col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
908 col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
909 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
910 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
912 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
915 /* IDirect3D IUnknown parts follow: */
916 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
918 ICOM_THIS(IDirect3DDevice8Impl,iface);
920 if (IsEqualGUID(riid, &IID_IUnknown)
921 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
922 IDirect3DDevice8Impl_AddRef(iface);
923 *ppobj = This;
924 return D3D_OK;
927 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
928 return E_NOINTERFACE;
931 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
932 ICOM_THIS(IDirect3DDevice8Impl,iface);
933 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
934 return ++(This->ref);
937 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
938 ICOM_THIS(IDirect3DDevice8Impl,iface);
939 ULONG ref = --This->ref;
940 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
941 if (ref == 0) {
942 HeapFree(GetProcessHeap(), 0, This);
944 return ref;
947 /* IDirect3DDevice Interface follow: */
948 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
949 ICOM_THIS(IDirect3DDevice8Impl,iface);
950 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
951 return D3D_OK;
954 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
955 ICOM_THIS(IDirect3DDevice8Impl,iface);
956 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
958 * pretend we have 32MB of any type of memory queried.
960 return (1024*1024*32);
963 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
964 ICOM_THIS(IDirect3DDevice8Impl,iface);
965 FIXME("(%p) : stub\n", This); return D3D_OK;
967 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
968 ICOM_THIS(IDirect3DDevice8Impl,iface);
969 TRACE("(%p) : returning %p\n", This, This->direct3d8);
971 /* Inc ref count */
972 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
974 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
975 return D3D_OK;
977 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
978 ICOM_THIS(IDirect3DDevice8Impl,iface);
979 FIXME("(%p) : stub, calling idirect3d for now\n", This);
980 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
981 return D3D_OK;
983 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
985 HDC hdc;
986 int bpp = 0;
988 ICOM_THIS(IDirect3DDevice8Impl,iface);
989 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
990 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
991 pMode->RefreshRate = 85; /*FIXME: How to identify? */
993 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
994 bpp = GetDeviceCaps(hdc, BITSPIXEL);
995 DeleteDC(hdc);
997 switch (bpp) {
998 case 8: pMode->Format = D3DFMT_R8G8B8; break;
999 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1000 case 24: pMode->Format = D3DFMT_R8G8B8; break;
1001 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1002 default:
1003 FIXME("Unrecognized display mode format\n");
1004 pMode->Format = D3DFMT_UNKNOWN;
1007 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
1008 return D3D_OK;
1010 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1011 ICOM_THIS(IDirect3DDevice8Impl,iface);
1012 TRACE("(%p) copying to %p\n", This, pParameters);
1013 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1014 return D3D_OK;
1016 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1017 ICOM_THIS(IDirect3DDevice8Impl,iface);
1018 FIXME("(%p) : stub\n", This); return D3D_OK;
1020 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1021 ICOM_THIS(IDirect3DDevice8Impl,iface);
1022 FIXME("(%p) : stub\n", This); return;
1024 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1025 ICOM_THIS(IDirect3DDevice8Impl,iface);
1026 FIXME("(%p) : stub\n", This); return D3D_OK;
1028 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1029 ICOM_THIS(IDirect3DDevice8Impl,iface);
1030 FIXME("(%p) : stub\n", This); return D3D_OK;
1032 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1033 ICOM_THIS(IDirect3DDevice8Impl,iface);
1034 FIXME("(%p) : stub\n", This); return D3D_OK;
1036 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1037 ICOM_THIS(IDirect3DDevice8Impl,iface);
1038 TRACE("(%p) : complete stub!\n", This);
1040 ENTER_GL();
1042 glXSwapBuffers(This->display, This->win);
1043 checkGLcall("glXSwapBuffers");
1045 LEAVE_GL();
1047 return D3D_OK;
1049 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
1050 ICOM_THIS(IDirect3DDevice8Impl,iface);
1051 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1052 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1054 /* Note inc ref on returned surface */
1055 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1057 return D3D_OK;
1059 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1060 ICOM_THIS(IDirect3DDevice8Impl,iface);
1061 FIXME("(%p) : stub\n", This); return D3D_OK;
1063 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1064 ICOM_THIS(IDirect3DDevice8Impl,iface);
1065 FIXME("(%p) : stub\n", This); return;
1067 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1068 ICOM_THIS(IDirect3DDevice8Impl,iface);
1069 FIXME("(%p) : stub\n", This); return;
1071 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1072 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1073 IDirect3DTexture8Impl *object;
1074 int i;
1075 UINT tmpW;
1076 UINT tmpH;
1078 ICOM_THIS(IDirect3DDevice8Impl,iface);
1080 /* Allocate the storage for the device */
1081 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
1082 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1083 object->lpVtbl = &Direct3DTexture8_Vtbl;
1084 object->Device = This; /* FIXME: AddRef(This) */
1085 object->ResourceType = D3DRTYPE_TEXTURE;
1086 object->ref = 1;
1087 object->width = Width;
1088 object->height = Height;
1089 object->levels = Levels;
1090 object->usage = Usage;
1091 object->format = Format;
1092 object->device = This;
1094 /* Calculate levels for mip mapping */
1095 if (Levels == 0) {
1096 object->levels++;
1097 tmpW = Width;
1098 tmpH = Height;
1099 while (tmpW > 1 && tmpH > 1) {
1100 tmpW = max(1,tmpW / 2);
1101 tmpH = max(1, tmpH / 2);
1102 object->levels++;
1104 TRACE("Calculated levels = %d\n", object->levels);
1107 /* Generate all the surfaces */
1108 tmpW = Width;
1109 tmpH = Height;
1110 for (i=0; i<object->levels; i++)
1112 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1113 object->surfaces[i]->Container = (IUnknown*) object; /* FIXME: AddRef(object) */
1114 object->surfaces[i]->myDesc.Usage = Usage;
1115 object->surfaces[i]->myDesc.Pool = Pool ;
1117 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1118 tmpW = max(1, tmpW / 2);
1119 tmpH = max(1, tmpH / 2);
1122 *ppTexture = (LPDIRECT3DTEXTURE8)object;
1123 return D3D_OK;
1125 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1127 IDirect3DVolumeTexture8Impl *object;
1128 int i;
1129 UINT tmpW;
1130 UINT tmpH;
1131 UINT tmpD;
1133 ICOM_THIS(IDirect3DDevice8Impl,iface);
1135 /* Allocate the storage for it */
1136 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);
1137 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1138 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1139 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1140 object->ref = 1;
1143 object->width = Width;
1144 object->height = Height;
1145 object->depth = Depth;
1146 object->levels = Levels;
1147 object->usage = Usage;
1148 object->format = Format;
1149 object->device = This;
1151 /* Calculate levels for mip mapping */
1152 if (Levels == 0) {
1153 object->levels++;
1154 tmpW = Width;
1155 tmpH = Height;
1156 tmpD = Depth;
1157 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1158 tmpW = max(1,tmpW / 2);
1159 tmpH = max(1, tmpH / 2);
1160 tmpD = max(1, tmpD / 2);
1161 object->levels++;
1163 TRACE("Calculated levels = %d\n", object->levels);
1166 /* Generate all the surfaces */
1167 tmpW = Width;
1168 tmpH = Height;
1169 tmpD = Depth;
1171 for (i=0; i<object->levels; i++)
1173 IDirect3DVolume8Impl *volume;
1175 /* Create the volume - No entry point for this seperately?? */
1176 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1177 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1179 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1180 volume->Device = This; /* FIXME: AddRef(This) */
1181 volume->ResourceType = D3DRTYPE_VOLUME;
1182 volume->Container = object;
1183 volume->ref = 1;
1185 volume->myDesc.Width = Width;
1186 volume->myDesc.Height= Height;
1187 volume->myDesc.Depth = Depth;
1188 volume->myDesc.Format= Format;
1189 volume->myDesc.Type = D3DRTYPE_VOLUME;
1190 volume->myDesc.Pool = Pool;
1191 volume->myDesc.Usage = Usage;
1192 volume->bytesPerPixel = bytesPerPixel(Format);
1193 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1194 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1196 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
1197 volume, volume->allocatedMemory, volume->myDesc.Size);
1199 tmpW = max(1,tmpW / 2);
1200 tmpH = max(1, tmpH / 2);
1201 tmpD = max(1, tmpD / 2);
1204 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
1205 return D3D_OK;
1207 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
1209 IDirect3DCubeTexture8Impl *object;
1210 ICOM_THIS(IDirect3DDevice8Impl,iface);
1211 int i,j;
1212 UINT tmpW;
1214 /* Allocate the storage for it */
1215 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
1216 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1217 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1218 object->ref = 1;
1219 object->Device = This; /* FIXME: AddRef(This) */
1220 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1222 object->edgeLength = EdgeLength;
1223 object->levels = Levels;
1224 object->usage = Usage;
1225 object->format = Format;
1226 object->device = This;
1228 /* Calculate levels for mip mapping */
1229 if (Levels == 0) {
1230 object->levels++;
1231 tmpW = EdgeLength;
1232 while (tmpW > 1) {
1233 tmpW = max(1,tmpW / 2);
1234 object->levels++;
1236 TRACE("Calculated levels = %d\n", object->levels);
1239 /* Generate all the surfaces */
1240 tmpW = EdgeLength;
1241 for (i=0; i<object->levels; i++)
1243 /* Create the 6 faces */
1244 for (j=0;j<6;j++) {
1245 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1246 object->surfaces[j][i]->Container = (IUnknown*) object;
1247 object->surfaces[j][i]->myDesc.Usage = Usage;
1248 object->surfaces[j][i]->myDesc.Pool = Pool ;
1250 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1251 tmpW = max(1,tmpW / 2);
1255 TRACE("(%p) : Iface@%p\n", This, object);
1256 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1257 return D3D_OK;
1259 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage,
1260 DWORD FVF,D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1261 IDirect3DVertexBuffer8Impl *object;
1263 ICOM_THIS(IDirect3DDevice8Impl,iface);
1265 /* Allocate the storage for the device */
1266 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1267 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1268 object->Device = This;
1269 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1270 object->ref = 1;
1271 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1272 object->currentDesc.Usage = Usage;
1273 object->currentDesc.Pool = Pool;
1274 object->currentDesc.FVF = FVF;
1275 object->currentDesc.Size = Size;
1277 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1279 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1281 return D3D_OK;
1283 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
1285 IDirect3DIndexBuffer8Impl *object;
1287 ICOM_THIS(IDirect3DDevice8Impl,iface);
1288 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
1290 /* Allocate the storage for the device */
1291 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1292 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1293 object->ref = 1;
1294 object->Device = This;
1295 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1297 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1298 object->currentDesc.Usage = Usage;
1299 object->currentDesc.Pool = Pool;
1300 object->currentDesc.Format = Format;
1301 object->currentDesc.Size = Length;
1303 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1305 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1307 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1309 return D3D_OK;
1311 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
1312 ICOM_THIS(IDirect3DDevice8Impl,iface);
1313 /* up ref count on surface, surface->container = This */
1314 FIXME("(%p) : stub\n", This); return D3D_OK;
1316 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
1317 ICOM_THIS(IDirect3DDevice8Impl,iface);
1318 /* surface->container = This */
1319 FIXME("(%p) : stub\n", This); return D3D_OK;
1321 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
1322 IDirect3DSurface8Impl *object;
1324 ICOM_THIS(IDirect3DDevice8Impl,iface);
1326 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1327 *ppSurface = (LPDIRECT3DSURFACE8) object;
1328 object->lpVtbl = &Direct3DSurface8_Vtbl;
1329 object->Device = This;
1330 object->ResourceType = D3DRTYPE_SURFACE;
1331 object->Container = (IUnknown*) This;
1333 object->ref = 1;
1334 object->myDesc.Width = Width;
1335 object->myDesc.Height= Height;
1336 object->myDesc.Format= Format;
1337 object->myDesc.Type = D3DRTYPE_SURFACE;
1338 /*object->myDesc.Usage */
1339 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
1340 object->bytesPerPixel = bytesPerPixel(Format);
1341 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1342 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1344 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);
1345 return D3D_OK;
1347 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1348 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1350 HRESULT rc = D3D_OK;
1351 IDirect3DBaseTexture8* texture = NULL;
1354 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
1355 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1357 ICOM_THIS(IDirect3DDevice8Impl,iface);
1358 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1359 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1361 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1362 a sample and doesnt seem to break anything as far as I can tell */
1363 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1364 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1365 rc = D3DERR_INVALIDCALL;
1367 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1368 TRACE("Converting dest to same format as source, since dest was unknown\n");
1369 dst->myDesc.Format = src->myDesc.Format;
1371 /* Convert container as well */
1372 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1373 if (texture != NULL) {
1375 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1376 case D3DRTYPE_TEXTURE:
1377 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1378 break;
1379 case D3DRTYPE_VOLUMETEXTURE:
1380 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1381 break;
1382 case D3DRTYPE_CUBETEXTURE:
1383 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1384 break;
1385 default:
1386 FIXME("Unhandled texture type\n");
1389 /** Releasing texture after GetContainer */
1390 IDirect3DBaseTexture8_Release(texture);
1394 /* Quick if complete copy ... */
1395 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1396 src->myDesc.Width == dst->myDesc.Width &&
1397 src->myDesc.Height == dst->myDesc.Height)) {
1398 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1399 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1401 } else {
1402 int i;
1403 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1404 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1405 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1407 void *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1408 void *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1410 /* Copy rect by rect */
1411 for (i=0; i<cRects; i++) {
1412 CONST RECT *r = &pSourceRectsArray[i];
1413 CONST POINT *p = &pDestPointsArray[i];
1414 void *from;
1415 void *to;
1416 int copyperline = (r->right - r->left) * bytesPerPixel;
1417 int j;
1419 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top,
1420 r->right, r->bottom, p->x, p->y);
1422 /* Find where to start */
1423 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1424 to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel);
1426 /* Copy line by line */
1427 for (j=0; j<(r->bottom - r->top); j++) {
1428 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1433 /* Set dirty */
1434 if (rc == D3D_OK) {
1435 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1436 if (texture != NULL) {
1438 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1439 case D3DRTYPE_TEXTURE:
1441 IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)texture;
1442 pTexture->Dirty = TRUE;
1444 break;
1445 case D3DRTYPE_VOLUMETEXTURE:
1447 IDirect3DVolumeTexture8Impl *pTexture = (IDirect3DVolumeTexture8Impl *)texture;
1448 pTexture->Dirty = TRUE;
1450 break;
1451 case D3DRTYPE_CUBETEXTURE:
1453 IDirect3DCubeTexture8Impl *pTexture = (IDirect3DCubeTexture8Impl *)texture;
1454 pTexture->Dirty = TRUE;
1456 break;
1457 default:
1458 FIXME("Unhandled texture type\n");
1461 /** Releasing texture after GetContainer */
1462 IDirect3DBaseTexture8_Release(texture);
1466 return D3D_OK;
1468 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1469 ICOM_THIS(IDirect3DDevice8Impl,iface);
1470 FIXME("(%p) : stub\n", This); return D3D_OK;
1472 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1473 ICOM_THIS(IDirect3DDevice8Impl,iface);
1474 FIXME("(%p) : stub\n", This); return D3D_OK;
1476 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1477 ICOM_THIS(IDirect3DDevice8Impl,iface);
1478 FIXME("(%p) : stub\n", This);
1480 return D3D_OK;
1482 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1483 ICOM_THIS(IDirect3DDevice8Impl,iface);
1484 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1485 FIXME("(%p) : stub\n", This);
1488 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1489 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1492 return D3D_OK;
1494 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1496 ICOM_THIS(IDirect3DDevice8Impl,iface);
1498 /* Note inc ref on returned surface *
1499 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1501 FIXME("(%p) : stub\n", This);
1502 return D3D_OK;
1505 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1506 ICOM_THIS(IDirect3DDevice8Impl,iface);
1507 TRACE("(%p) : stub\n", This);
1508 return D3D_OK;
1510 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1511 ICOM_THIS(IDirect3DDevice8Impl,iface);
1512 TRACE("(%p)\n", This);
1514 ENTER_GL();
1516 glFlush();
1517 checkGLcall("glFlush");
1519 /* Useful for debugging sometimes!
1520 printf("Hit Enter ...\n");
1521 getchar(); */
1523 LEAVE_GL();
1524 return D3D_OK;
1526 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1527 ICOM_THIS(IDirect3DDevice8Impl,iface);
1529 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1530 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1531 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1532 GLbitfield glMask = 0;
1533 int i;
1534 CONST D3DRECT *curRect;
1536 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1537 Count, pRects, Flags, Z, Stencil);
1539 ENTER_GL();
1540 if (Count > 0 && pRects) {
1541 glEnable(GL_SCISSOR_TEST);
1542 checkGLcall("glEnable GL_SCISSOR_TEST");
1543 curRect = pRects;
1544 } else {
1545 curRect = NULL;
1548 for (i=0;i<Count || i==0; i++) {
1550 if (curRect) {
1551 /* Note gl uses lower left, width/height */
1552 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1553 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1554 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1555 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1556 checkGLcall("glScissor");
1559 /* Clear the whole screen */
1560 if (Flags & D3DCLEAR_STENCIL) {
1561 glClearStencil(Stencil);
1562 checkGLcall("glClearStencil");
1563 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1566 if (Flags & D3DCLEAR_ZBUFFER) {
1567 glClearDepth(Z);
1568 checkGLcall("glClearDepth");
1569 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1572 if (Flags & D3DCLEAR_TARGET) {
1573 TRACE("Clearing screen with glClear to color %lx\n", Color);
1574 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1575 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1576 checkGLcall("glClearColor");
1577 glMask = glMask | GL_COLOR_BUFFER_BIT;
1580 glClear(glMask);
1581 checkGLcall("glClear");
1583 if (curRect) curRect = curRect + sizeof(D3DRECT);
1586 if (Count > 0 && pRects) {
1587 glDisable(GL_SCISSOR_TEST);
1588 checkGLcall("glDisable");
1590 LEAVE_GL();
1592 return D3D_OK;
1594 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1595 ICOM_THIS(IDirect3DDevice8Impl,iface);
1596 int k;
1598 /* Most of this routine, comments included copied from ddraw tree initially: */
1599 TRACE("(%p) : State=%d\n", This, d3dts);
1601 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1602 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1603 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1605 /* Handle recording of state blocks */
1606 if (This->isRecordingState) {
1607 TRACE("Recording... not performing anything\n");
1608 return D3D_OK;
1612 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1614 where ViewMat = Camera space, WorldMat = world space.
1616 In OpenGL, camera and world space is combined into GL_MODELVIEW
1617 matrix. The Projection matrix stay projection matrix. */
1619 /* After reading through both OpenGL and Direct3D documentations, I
1620 thought that D3D matrices were written in 'line major mode' transposed
1621 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1622 works fine to transfer one matrix format to the other (it did not work
1623 when transposing)....
1625 So :
1626 1) are the documentations wrong
1627 2) does the matrix work even if they are not read correctly
1628 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1629 loading using glLoadMatrix ?
1631 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1632 to the other so that if I ever find out that I need to transpose them, I
1633 will able to do it quickly, only by changing the macro conv_mat. */
1635 switch (d3dts) {
1636 case D3DTS_WORLDMATRIX(0):
1637 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)]);
1638 break;
1640 case D3DTS_VIEW:
1641 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_VIEW]);
1642 break;
1644 case D3DTS_PROJECTION:
1645 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_PROJECTION]);
1646 break;
1648 default:
1649 FIXME("Unhandled transform state!!\n");
1650 break;
1654 * Move the GL operation to outside of switch to make it work
1655 * regardless of transform set order. Optimize later.
1657 ENTER_GL();
1658 glMatrixMode(GL_PROJECTION);
1659 checkGLcall("glMatrixMode");
1660 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
1661 checkGLcall("glLoadMatrixf");
1663 glMatrixMode(GL_MODELVIEW);
1664 checkGLcall("glMatrixMode");
1665 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1666 checkGLcall("glLoadMatrixf");
1668 /* If we are changing the View matrix, reset the light information to the new view */
1669 if (d3dts == D3DTS_VIEW) {
1670 for (k = 0; k < MAX_ACTIVE_LIGHTS; k++) {
1671 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1672 checkGLcall("glLightfv posn");
1673 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1674 checkGLcall("glLightfv dirn");
1678 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1679 checkGLcall("glMultMatrixf");
1681 LEAVE_GL();
1683 return D3D_OK;
1686 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1687 ICOM_THIS(IDirect3DDevice8Impl,iface);
1688 TRACE("(%p) : for State %d\n", This, State);
1689 memcpy(pMatrix, &This->StateBlock.transforms[State], sizeof(D3DMATRIX));
1690 return D3D_OK;
1693 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1694 ICOM_THIS(IDirect3DDevice8Impl,iface);
1695 FIXME("(%p) : stub\n", This); return D3D_OK;
1697 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1698 ICOM_THIS(IDirect3DDevice8Impl,iface);
1700 TRACE("(%p)\n", This);
1701 This->UpdateStateBlock->Changed.viewport = TRUE;
1702 This->UpdateStateBlock->Set.viewport = TRUE;
1703 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1705 /* Handle recording of state blocks */
1706 if (This->isRecordingState) {
1707 TRACE("Recording... not performing anything\n");
1708 return D3D_OK;
1711 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1712 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1714 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1715 checkGLcall("glDepthRange");
1716 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1717 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1718 checkGLcall("glViewport");
1721 return D3D_OK;
1724 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1725 ICOM_THIS(IDirect3DDevice8Impl,iface);
1726 TRACE("(%p)\n", This);
1727 memcpy(pViewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
1728 return D3D_OK;
1731 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1732 ICOM_THIS(IDirect3DDevice8Impl,iface);
1734 This->UpdateStateBlock->Changed.material = TRUE;
1735 This->UpdateStateBlock->Set.material = TRUE;
1736 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1738 /* Handle recording of state blocks */
1739 if (This->isRecordingState) {
1740 TRACE("Recording... not performing anything\n");
1741 return D3D_OK;
1744 ENTER_GL();
1745 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1746 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1747 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1748 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1749 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1751 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1752 checkGLcall("glMaterialfv");
1753 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1754 checkGLcall("glMaterialfv");
1756 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1757 checkGLcall("glMaterialfv");
1758 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1759 checkGLcall("glMaterialfv");
1760 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1761 checkGLcall("glMaterialf");
1763 LEAVE_GL();
1764 return D3D_OK;
1766 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1767 ICOM_THIS(IDirect3DDevice8Impl,iface);
1768 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1769 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1770 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1771 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1772 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1773 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1774 return D3D_OK;
1777 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1778 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1779 float rho;
1780 float quad_att;
1782 ICOM_THIS(IDirect3DDevice8Impl,iface);
1783 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1785 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,
1786 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1787 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1788 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1789 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1790 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1791 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1793 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1794 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1795 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1797 /* Handle recording of state blocks */
1798 if (This->isRecordingState) {
1799 TRACE("Recording... not performing anything\n");
1800 return D3D_OK;
1803 /* Diffuse: */
1804 colRGBA[0] = pLight->Diffuse.r;
1805 colRGBA[1] = pLight->Diffuse.g;
1806 colRGBA[2] = pLight->Diffuse.b;
1807 colRGBA[3] = pLight->Diffuse.a;
1808 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1809 checkGLcall("glLightfv");
1811 /* Specular */
1812 colRGBA[0] = pLight->Specular.r;
1813 colRGBA[1] = pLight->Specular.g;
1814 colRGBA[2] = pLight->Specular.b;
1815 colRGBA[3] = pLight->Specular.a;
1816 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1817 checkGLcall("glLightfv");
1819 /* Ambient */
1820 colRGBA[0] = pLight->Ambient.r;
1821 colRGBA[1] = pLight->Ambient.g;
1822 colRGBA[2] = pLight->Ambient.b;
1823 colRGBA[3] = pLight->Ambient.a;
1824 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1825 checkGLcall("glLightfv");
1827 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1828 glMatrixMode(GL_MODELVIEW);
1829 glPushMatrix();
1830 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1832 /* Attenuation - Are these right? guessing... */
1833 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
1834 checkGLcall("glLightf");
1835 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
1836 checkGLcall("glLightf");
1838 quad_att = 1.4/(pLight->Range*pLight->Range);
1839 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1840 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1841 checkGLcall("glLightf");
1843 switch (pLight->Type) {
1844 case D3DLIGHT_POINT:
1845 /* Position */
1846 This->lightPosn[Index][0] = pLight->Position.x;
1847 This->lightPosn[Index][1] = pLight->Position.y;
1848 This->lightPosn[Index][2] = pLight->Position.z;
1849 This->lightPosn[Index][3] = 1.0;
1850 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1851 checkGLcall("glLightfv");
1853 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1854 checkGLcall("glLightf");
1856 /* FIXME: Range */
1857 break;
1859 case D3DLIGHT_SPOT:
1860 /* Position */
1861 This->lightPosn[Index][0] = pLight->Position.x;
1862 This->lightPosn[Index][1] = pLight->Position.y;
1863 This->lightPosn[Index][2] = pLight->Position.z;
1864 This->lightPosn[Index][3] = 1.0;
1865 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1866 checkGLcall("glLightfv");
1868 /* Direction */
1869 This->lightDirn[Index][0] = pLight->Direction.x;
1870 This->lightDirn[Index][1] = pLight->Direction.y;
1871 This->lightDirn[Index][2] = pLight->Direction.z;
1872 This->lightDirn[Index][3] = 1.0;
1873 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1874 checkGLcall("glLightfv");
1877 * opengl-ish and d3d-ish spot lights use too different models for the
1878 * light "intensity" as a function of the angle towards the main light direction,
1879 * so we only can approximate very roughly.
1880 * however spot lights are rather rarely used in games (if ever used at all).
1881 * furthermore if still used, probably nobody pays attention to such details.
1883 if (pLight->Falloff == 0) {
1884 rho = 6.28f;
1885 } else {
1886 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1888 if (rho < 0.0001) rho = 0.0001f;
1889 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
1890 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
1892 /* FIXME: Range */
1893 break;
1894 case D3DLIGHT_DIRECTIONAL:
1895 /* Direction */
1896 This->lightPosn[Index][0] = -pLight->Direction.x;
1897 This->lightPosn[Index][1] = -pLight->Direction.y;
1898 This->lightPosn[Index][2] = -pLight->Direction.z;
1899 This->lightPosn[Index][3] = 0.0;
1900 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
1901 checkGLcall("glLightfv");
1903 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
1904 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
1907 break;
1908 default:
1909 FIXME("Unrecognized light type %d\n", pLight->Type);
1912 /* Restore the modelview matrix */
1913 glPopMatrix();
1915 return D3D_OK;
1917 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1918 ICOM_THIS(IDirect3DDevice8Impl,iface);
1919 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1920 memcpy(pLight, &This->StateBlock.lights[Index], sizeof(D3DLIGHT8));
1921 return D3D_OK;
1923 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1924 ICOM_THIS(IDirect3DDevice8Impl,iface);
1925 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
1927 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
1928 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
1929 This->UpdateStateBlock->lightEnable[Index] = Enable;
1931 /* Handle recording of state blocks */
1932 if (This->isRecordingState) {
1933 TRACE("Recording... not performing anything\n");
1934 return D3D_OK;
1937 if (Enable) {
1938 glEnable(GL_LIGHT0+Index);
1939 checkGLcall("glEnable GL_LIGHT0+Index");
1940 } else {
1941 glDisable(GL_LIGHT0+Index);
1942 checkGLcall("glDisable GL_LIGHT0+Index");
1944 return D3D_OK;
1946 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1947 ICOM_THIS(IDirect3DDevice8Impl,iface);
1948 TRACE("(%p) : for idx(%ld)\n", This, Index);
1949 *pEnable = This->StateBlock.lightEnable[Index];
1950 return D3D_OK;
1952 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1953 ICOM_THIS(IDirect3DDevice8Impl,iface);
1954 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
1956 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
1957 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
1958 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
1959 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
1960 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
1961 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
1963 /* Handle recording of state blocks */
1964 if (This->isRecordingState) {
1965 TRACE("Recording... not performing anything\n");
1966 return D3D_OK;
1969 /* Apply it */
1971 /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
1972 glMatrixMode(GL_MODELVIEW);
1973 glPushMatrix();
1974 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLD].u.m[0][0]);
1976 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
1977 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
1978 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
1980 glPopMatrix();
1981 checkGLcall("glClipPlane");
1983 return D3D_OK;
1985 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1986 ICOM_THIS(IDirect3DDevice8Impl,iface);
1987 TRACE("(%p) : for idx %ld\n", This, Index);
1988 pPlane[0] = This->StateBlock.clipplane[Index][0];
1989 pPlane[1] = This->StateBlock.clipplane[Index][0];
1990 pPlane[2] = This->StateBlock.clipplane[Index][0];
1991 pPlane[3] = This->StateBlock.clipplane[Index][0];
1992 return D3D_OK;
1994 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
1995 ICOM_THIS(IDirect3DDevice8Impl,iface);
1996 DWORD OldValue = This->StateBlock.renderstate[State];
1998 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
1999 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2000 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2001 This->UpdateStateBlock->renderstate[State] = Value;
2003 /* Handle recording of state blocks */
2004 if (This->isRecordingState) {
2005 TRACE("Recording... not performing anything\n");
2006 return D3D_OK;
2009 switch (State) {
2010 case D3DRS_FILLMODE :
2011 switch ((D3DFILLMODE) Value) {
2012 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2013 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2014 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2015 default:
2016 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2018 checkGLcall("glPolygonMode (fillmode)");
2019 break;
2021 case D3DRS_LIGHTING :
2022 if (Value) {
2023 glEnable(GL_LIGHTING);
2024 checkGLcall("glEnable GL_LIGHTING");
2025 } else {
2026 glDisable(GL_LIGHTING);
2027 checkGLcall("glDisable GL_LIGHTING");
2029 break;
2031 case D3DRS_ZENABLE :
2032 switch ((D3DZBUFFERTYPE) Value) {
2033 case D3DZB_FALSE:
2034 glDisable(GL_DEPTH_TEST);
2035 checkGLcall("glDisable GL_DEPTH_TEST");
2036 break;
2037 case D3DZB_TRUE:
2038 glEnable(GL_DEPTH_TEST);
2039 checkGLcall("glEnable GL_DEPTH_TEST");
2040 break;
2042 case D3DZB_USEW:
2043 default:
2044 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2046 break;
2048 case D3DRS_CULLMODE :
2050 /* If we are culling "back faces with clockwise vertices" then
2051 set front faces to be counter clockwise and enable culling
2052 of back faces */
2053 switch ((D3DCULL) Value) {
2054 case D3DCULL_NONE:
2055 glDisable(GL_CULL_FACE);
2056 checkGLcall("glDisable GL_CULL_FACE");
2057 break;
2058 case D3DCULL_CW:
2059 glEnable(GL_CULL_FACE);
2060 checkGLcall("glEnable GL_CULL_FACE");
2061 glFrontFace(GL_CCW);
2062 checkGLcall("glFrontFace GL_CCW");
2063 glCullFace(GL_BACK);
2064 break;
2065 case D3DCULL_CCW:
2066 glEnable(GL_CULL_FACE);
2067 checkGLcall("glEnable GL_CULL_FACE");
2068 glFrontFace(GL_CW);
2069 checkGLcall("glFrontFace GL_CW");
2070 glCullFace(GL_BACK);
2071 break;
2072 default:
2073 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2075 break;
2077 case D3DRS_SHADEMODE :
2078 switch ((D3DSHADEMODE) Value) {
2079 case D3DSHADE_FLAT:
2080 glShadeModel(GL_FLAT);
2081 checkGLcall("glShadeModel");
2082 break;
2083 case D3DSHADE_GOURAUD:
2084 glShadeModel(GL_SMOOTH);
2085 checkGLcall("glShadeModel");
2086 break;
2087 case D3DSHADE_PHONG:
2088 FIXME("D3DSHADE_PHONG isnt supported?\n");
2089 return D3DERR_INVALIDCALL;
2090 default:
2091 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
2093 break;
2095 case D3DRS_DITHERENABLE :
2096 if (Value) {
2097 glEnable(GL_DITHER);
2098 checkGLcall("glEnable GL_DITHER");
2099 } else {
2100 glDisable(GL_DITHER);
2101 checkGLcall("glDisable GL_DITHER");
2103 break;
2105 case D3DRS_ZWRITEENABLE :
2106 if (Value) {
2107 glDepthMask(1);
2108 checkGLcall("glDepthMask");
2109 } else {
2110 glDepthMask(0);
2111 checkGLcall("glDepthMask");
2113 break;
2115 case D3DRS_ZFUNC :
2117 int glParm = GL_LESS;
2119 switch ((D3DCMPFUNC) Value) {
2120 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2121 case D3DCMP_LESS: glParm=GL_LESS; break;
2122 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2123 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2124 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2125 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2126 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2127 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2128 default:
2129 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2131 glDepthFunc(glParm);
2132 checkGLcall("glDepthFunc");
2134 break;
2136 case D3DRS_AMBIENT :
2139 float col[4];
2140 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2141 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2142 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2143 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2144 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
2145 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2146 checkGLcall("glLightModel for MODEL_AMBIENT");
2149 break;
2151 case D3DRS_ALPHABLENDENABLE :
2152 if (Value) {
2153 glEnable(GL_BLEND);
2154 checkGLcall("glEnable GL_BLEND");
2155 } else {
2156 glDisable(GL_BLEND);
2157 checkGLcall("glDisable GL_BLEND");
2159 break;
2161 case D3DRS_SRCBLEND :
2162 case D3DRS_DESTBLEND :
2164 int newVal = GL_ZERO;
2165 switch (Value) {
2166 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2167 case D3DBLEND_ONE : newVal = GL_ONE; break;
2168 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2169 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2170 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2171 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2172 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2173 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2174 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2175 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2176 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2178 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2179 This->srcBlend = newVal;
2180 This->dstBlend = newVal;
2181 break;
2183 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2184 This->srcBlend = newVal;
2185 This->dstBlend = newVal;
2186 break;
2187 default:
2188 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
2191 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
2192 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
2193 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
2194 glBlendFunc(This->srcBlend, This->dstBlend);
2196 checkGLcall("glBlendFunc");
2198 break;
2200 case D3DRS_ALPHATESTENABLE :
2201 if (Value) {
2202 glEnable(GL_ALPHA_TEST);
2203 checkGLcall("glEnable GL_ALPHA_TEST");
2204 } else {
2205 glDisable(GL_ALPHA_TEST);
2206 checkGLcall("glDisable GL_ALPHA_TEST");
2208 break;
2210 case D3DRS_ALPHAFUNC :
2212 int glParm = GL_LESS;
2213 float ref = 1.0;
2215 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
2216 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
2218 switch ((D3DCMPFUNC) Value) {
2219 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2220 case D3DCMP_LESS: glParm=GL_LESS; break;
2221 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2222 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2223 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2224 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2225 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2226 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2227 default:
2228 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2230 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2231 glAlphaFunc(glParm, ref);
2232 checkGLcall("glAlphaFunc");
2234 break;
2236 case D3DRS_ALPHAREF :
2238 int glParm = GL_LESS;
2239 float ref = 1.0;
2241 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
2242 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
2244 ref = ((float) Value) / 255.0;
2245 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2246 glAlphaFunc(glParm, ref);
2247 checkGLcall("glAlphaFunc");
2249 break;
2251 case D3DRS_CLIPPLANEENABLE :
2252 case D3DRS_CLIPPING :
2254 /* Ensure we only do the changed clip planes */
2255 DWORD enable = 0xFFFFFFFF;
2256 DWORD disable = 0x00000000;
2258 /* If enabling / disabling all */
2259 if (State == D3DRS_CLIPPING) {
2260 if (Value) {
2261 enable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
2262 disable = 0x00;
2263 } else {
2264 disable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
2265 enable = 0x00;
2267 } else {
2268 enable = Value & ~OldValue;
2269 disable = ~Value & OldValue;
2272 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
2273 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
2274 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
2275 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
2276 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
2277 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
2279 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
2280 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
2281 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
2282 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
2283 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
2284 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
2286 break;
2288 case D3DRS_BLENDOP :
2290 int glParm = GL_FUNC_ADD;
2292 switch ((D3DBLENDOP) Value) {
2293 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
2294 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
2295 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
2296 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
2297 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
2298 default:
2299 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
2301 TRACE("glBlendEquation(%x)\n", glParm);
2302 glBlendEquation(glParm);
2303 checkGLcall("glBlendEquation");
2305 break;
2307 case D3DRS_TEXTUREFACTOR :
2309 int i;
2311 /* Note the texture color applies to all textures whereas
2312 GL_TEXTURE_ENV_COLOR applies to active only */
2313 float col[4];
2314 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2315 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2316 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2317 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2319 /* Set the default alpha blend color */
2320 glBlendColor(col[0], col[1], col[2], col[3]);
2321 checkGLcall("glBlendColor");
2323 /* And now the default texture color as well */
2324 for (i = 0; i < This->TextureUnits; i++) {
2326 /* Note the D3DRS value applies to all textures, but GL has one
2327 per texture, so apply it now ready to be used! */
2328 if (This->isMultiTexture) {
2329 glActiveTextureARB(GL_TEXTURE0_ARB + i);
2330 checkGLcall("Activate texture.. to update const color");
2331 } else if (i>0) {
2332 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2335 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
2336 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2339 break;
2341 case D3DRS_SPECULARENABLE :
2343 if (Value) {
2344 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
2345 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
2346 } else {
2347 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
2348 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
2351 break;
2353 case D3DRS_STENCILENABLE :
2354 if (Value) {
2355 glEnable(GL_STENCIL_TEST);
2356 checkGLcall("glEnable GL_STENCIL_TEST");
2357 } else {
2358 glDisable(GL_STENCIL_TEST);
2359 checkGLcall("glDisable GL_STENCIL_TEST");
2361 break;
2363 case D3DRS_STENCILFUNC :
2365 int glParm = GL_ALWAYS;
2366 int ref = 0;
2367 GLuint mask = 0xFFFFFFFF;
2369 glGetIntegerv(GL_STENCIL_REF, &ref);
2370 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2371 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2372 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2374 switch ((D3DCMPFUNC) Value) {
2375 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2376 case D3DCMP_LESS: glParm=GL_LESS; break;
2377 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2378 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2379 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2380 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2381 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2382 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2383 default:
2384 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2386 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2387 glStencilFunc(glParm, ref, mask);
2388 checkGLcall("glStencilFunc");
2390 break;
2392 case D3DRS_STENCILREF :
2394 int glParm = GL_ALWAYS;
2395 int ref = 0;
2396 GLuint mask = 0xFFFFFFFF;
2398 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2399 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2400 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2401 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2403 ref = Value;
2404 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2405 glStencilFunc(glParm, ref, mask);
2406 checkGLcall("glStencilFunc");
2408 break;
2410 case D3DRS_STENCILMASK :
2412 int glParm = GL_ALWAYS;
2413 int ref = 0.0;
2414 GLuint mask = Value;
2416 glGetIntegerv(GL_STENCIL_REF, &ref);
2417 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2418 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2419 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2421 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2422 glStencilFunc(glParm, ref, mask);
2423 checkGLcall("glStencilFunc");
2425 break;
2427 case D3DRS_STENCILFAIL :
2429 GLenum fail ;
2430 GLenum zpass ;
2431 GLenum zfail ;
2433 fail = StencilOp(Value);
2434 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2435 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2436 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2437 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2439 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2440 glStencilOp(fail, zfail, zpass);
2441 checkGLcall("glStencilOp(fail, zfail, zpass);");
2443 break;
2444 case D3DRS_STENCILZFAIL :
2446 GLenum fail ;
2447 GLenum zpass ;
2448 GLenum zfail ;
2450 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2451 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2452 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2453 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2454 zfail = StencilOp(Value);
2456 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2457 glStencilOp(fail, zfail, zpass);
2458 checkGLcall("glStencilOp(fail, zfail, zpass);");
2460 break;
2461 case D3DRS_STENCILPASS :
2463 GLenum fail ;
2464 GLenum zpass ;
2465 GLenum zfail ;
2467 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2468 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2469 zpass = StencilOp(Value);
2470 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2471 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2473 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2474 glStencilOp(fail, zfail, zpass);
2475 checkGLcall("glStencilOp(fail, zfail, zpass);");
2477 break;
2479 case D3DRS_STENCILWRITEMASK :
2481 glStencilMask(Value);
2482 TRACE("glStencilMask(%lu)\n", Value);
2483 checkGLcall("glStencilMask");
2485 break;
2487 case D3DRS_FOGENABLE :
2489 if (Value && This->StateBlock.renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
2490 glEnable(GL_FOG);
2491 checkGLcall("glEnable GL_FOG\n");
2492 } else {
2493 glDisable(GL_FOG);
2494 checkGLcall("glDisable GL_FOG\n");
2497 break;
2499 case D3DRS_FOGCOLOR :
2501 float col[4];
2502 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2503 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2504 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2505 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2507 /* Set the default alpha blend color */
2508 glFogfv(GL_FOG_COLOR, &col[0]);
2509 checkGLcall("glFog GL_FOG_COLOR");
2511 break;
2513 case D3DRS_FOGSTART :
2515 float *f = (float *)&Value;
2516 glFogfv(GL_FOG_START, f);
2517 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2518 TRACE("Fog Start == %f\n", *f);
2520 break;
2522 case D3DRS_FOGEND :
2524 float *f = (float *)&Value;
2525 glFogfv(GL_FOG_END, f);
2526 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2527 TRACE("Fog End == %f\n", *f);
2529 break;
2531 case D3DRS_FOGDENSITY :
2533 glFogf(GL_FOG_DENSITY, (float) Value);
2534 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2536 break;
2538 /* Unhandled yet...! */
2539 case D3DRS_LINEPATTERN :
2540 case D3DRS_LASTPIXEL :
2541 case D3DRS_ZVISIBLE :
2542 case D3DRS_FOGTABLEMODE :
2543 case D3DRS_EDGEANTIALIAS :
2544 case D3DRS_ZBIAS :
2545 case D3DRS_RANGEFOGENABLE :
2546 case D3DRS_WRAP0 :
2547 case D3DRS_WRAP1 :
2548 case D3DRS_WRAP2 :
2549 case D3DRS_WRAP3 :
2550 case D3DRS_WRAP4 :
2551 case D3DRS_WRAP5 :
2552 case D3DRS_WRAP6 :
2553 case D3DRS_WRAP7 :
2554 case D3DRS_FOGVERTEXMODE :
2555 case D3DRS_COLORVERTEX :
2556 case D3DRS_LOCALVIEWER :
2557 case D3DRS_NORMALIZENORMALS :
2558 case D3DRS_DIFFUSEMATERIALSOURCE :
2559 case D3DRS_SPECULARMATERIALSOURCE :
2560 case D3DRS_AMBIENTMATERIALSOURCE :
2561 case D3DRS_EMISSIVEMATERIALSOURCE :
2562 case D3DRS_VERTEXBLEND :
2563 case D3DRS_SOFTWAREVERTEXPROCESSING :
2564 case D3DRS_POINTSIZE :
2565 case D3DRS_POINTSIZE_MIN :
2566 case D3DRS_POINTSPRITEENABLE :
2567 case D3DRS_POINTSCALEENABLE :
2568 case D3DRS_POINTSCALE_A :
2569 case D3DRS_POINTSCALE_B :
2570 case D3DRS_POINTSCALE_C :
2571 case D3DRS_MULTISAMPLEANTIALIAS :
2572 case D3DRS_MULTISAMPLEMASK :
2573 case D3DRS_PATCHEDGESTYLE :
2574 case D3DRS_PATCHSEGMENTS :
2575 case D3DRS_DEBUGMONITORTOKEN :
2576 case D3DRS_POINTSIZE_MAX :
2577 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2578 case D3DRS_COLORWRITEENABLE :
2579 case D3DRS_TWEENFACTOR :
2580 case D3DRS_POSITIONORDER :
2581 case D3DRS_NORMALORDER :
2582 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2583 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2584 break;
2585 default:
2586 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2589 return D3D_OK;
2591 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2592 ICOM_THIS(IDirect3DDevice8Impl,iface);
2593 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2594 *pValue = This->StateBlock.renderstate[State];
2595 return D3D_OK;
2597 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2598 ICOM_THIS(IDirect3DDevice8Impl,iface);
2600 void *memory;
2602 TRACE("(%p)\n", This);
2603 if (This->isRecordingState) {
2604 TRACE("(%p) already recording! returning error\n", This);
2605 return D3DERR_INVALIDCALL;
2608 /* Allocate Storage */
2609 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2610 This->isRecordingState = TRUE;
2611 This->UpdateStateBlock = memory;
2613 return D3D_OK;
2615 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2617 ICOM_THIS(IDirect3DDevice8Impl,iface);
2618 TRACE("(%p)\n", This);
2620 if (!This->isRecordingState) {
2621 TRACE("(%p) not recording! returning error\n", This);
2622 return D3DERR_INVALIDCALL;
2625 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2626 *pToken = (DWORD) This->UpdateStateBlock;
2627 This->isRecordingState = FALSE;
2628 This->UpdateStateBlock = &This->StateBlock;
2630 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2631 return D3D_OK;
2634 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2636 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2637 int i,j;
2639 ICOM_THIS(IDirect3DDevice8Impl,iface);
2640 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2642 /* FIXME: Only apply applicable states not all states */
2644 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2646 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2648 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2649 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2650 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2651 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2654 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2655 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2657 /* TODO: Vertex Shader Constants */
2660 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2662 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2663 IDirect3DDevice8Impl_SetPixelShader(iface, pSB->PixelShader);
2665 /* TODO: Pixel Shader Constants */
2668 /* Others + Render & Texture */
2669 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2670 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2671 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2672 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2675 if (pSB->Set.Indices && pSB->Changed.Indices)
2676 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2678 if (pSB->Set.material && pSB->Changed.material)
2679 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2681 if (pSB->Set.viewport && pSB->Changed.viewport)
2682 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2684 for (i=0; i<MAX_STREAMS; i++) {
2685 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2686 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2689 for (i=0; i<MAX_CLIPPLANES; i++) {
2690 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2691 float clip[4];
2693 clip[0] = pSB->clipplane[i][0];
2694 clip[1] = pSB->clipplane[i][1];
2695 clip[2] = pSB->clipplane[i][2];
2696 clip[3] = pSB->clipplane[i][3];
2697 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2701 /* Render */
2702 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2704 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2705 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2709 /* Texture */
2710 for (j = 0; j < This->TextureUnits; j++) {
2711 for (i = 0; i < HIGHEST_TEXTURE_STATE; i++) {
2712 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i]) {
2713 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2716 if (pSB->Set.textures[j] && pSB->Changed.textures[j]) {
2717 IDirect3DDevice8Impl_SetTexture(iface, j, pSB->textures[j]);
2722 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2724 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2725 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2726 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2730 for (j=0; j<This->TextureUnits; i++) {
2731 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2733 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2734 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2735 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2739 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2741 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2742 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2743 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2747 for (j=0; j<This->TextureUnits; i++) {
2748 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2750 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2751 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2752 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2757 } else {
2758 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2760 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2761 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2763 return D3D_OK;
2765 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2767 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2769 ICOM_THIS(IDirect3DDevice8Impl,iface);
2771 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2773 /* If not recorded, then update can just recapture */
2774 if (updateBlock->blockType != D3DSBT_RECORDED) {
2775 DWORD tmpToken;
2776 STATEBLOCK *tmpBlock;
2777 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2778 tmpBlock = (STATEBLOCK *)tmpToken;
2779 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2780 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2782 /* FIXME: This will record states of new lights! May need to have and save set_lights
2783 across this action */
2785 } else {
2786 int i,j;
2788 /* Recorded => Only update 'changed' values */
2789 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2790 updateBlock->VertexShader = This->StateBlock.VertexShader;
2791 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2794 /* TODO: Vertex Shader Constants */
2796 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2797 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2798 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2799 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2802 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2803 &updateBlock->lights[i],
2804 sizeof(D3DLIGHT8)) != 0) {
2805 TRACE("Updating lights for light %d\n", i);
2806 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2810 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2811 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2812 updateBlock->lights[i] = This->StateBlock.lights[i];
2813 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2816 /* TODO: Pixel Shader Constants */
2818 /* Others + Render & Texture */
2819 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2820 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2821 &updateBlock->transforms[i],
2822 sizeof(D3DMATRIX)) != 0) {
2823 TRACE("Updating transform %d\n", i);
2824 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2828 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2829 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2830 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2831 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2832 updateBlock->pIndexData = This->StateBlock.pIndexData;
2833 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2836 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2837 &updateBlock->material,
2838 sizeof(D3DMATERIAL8)) != 0) {
2839 TRACE("Updating material\n");
2840 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2843 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2844 &updateBlock->viewport,
2845 sizeof(D3DVIEWPORT8)) != 0) {
2846 TRACE("Updating viewport\n");
2847 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2850 for (i=0; i<MAX_STREAMS; i++) {
2851 if (updateBlock->Set.stream_source[i] &&
2852 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2853 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2854 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2855 This->StateBlock.stream_stride[i]);
2856 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2857 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2861 for (i=0; i<MAX_CLIPPLANES; i++) {
2862 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2863 &updateBlock->clipplane[i],
2864 sizeof(updateBlock->clipplane)) != 0) {
2866 TRACE("Updating clipplane %d\n", i);
2867 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2868 sizeof(updateBlock->clipplane));
2872 /* Render */
2873 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2875 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
2876 This->StateBlock.renderstate[i])) {
2877 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
2878 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
2882 /* Texture */
2883 for (j=0; j<This->TextureUnits; j++) {
2884 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
2886 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
2887 This->StateBlock.texture_state[j][i])) {
2888 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
2889 updateBlock->texture_state[j][i]);
2890 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
2893 if (updateBlock->Set.textures[j] && (updateBlock->textures[j] != This->StateBlock.textures[j])) {
2894 TRACE("Updating texture %d to %p (was %p)\n", j, This->StateBlock.textures[j], updateBlock->textures[j]);
2895 updateBlock->textures[j] = This->StateBlock.textures[j];
2902 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
2904 return D3D_OK;
2906 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2907 ICOM_THIS(IDirect3DDevice8Impl,iface);
2908 TRACE("(%p) : freeing StateBlock %lx\n", This, Token);
2909 HeapFree(GetProcessHeap(), 0, (void *)Token);
2910 return D3D_OK;
2913 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
2914 void *memory;
2915 STATEBLOCK *s;
2916 int i,j;
2918 ICOM_THIS(IDirect3DDevice8Impl,iface);
2919 TRACE("(%p) : for type %d\n", This, Type);
2921 /* Allocate Storage */
2922 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2923 if (memory) {
2924 memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
2925 } else {
2926 *pToken = 0xFFFFFFFF;
2927 return E_OUTOFMEMORY;
2929 *pToken = (DWORD) memory;
2930 s = memory;
2931 s->blockType = Type;
2933 TRACE("Updating changed flags appropriate for type %d\n", Type);
2935 if (Type == D3DSBT_ALL) {
2936 TRACE("ALL => Pretend everything has changed\n");
2937 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
2939 } else if (Type == D3DSBT_PIXELSTATE) {
2941 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2943 /* TODO: Pixel Shader Constants */
2944 s->Changed.pixelShader = TRUE;
2945 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2946 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
2948 for (j=0; j<This->TextureUnits; i++) {
2949 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2950 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
2954 } else if (Type == D3DSBT_VERTEXSTATE) {
2956 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
2958 /* TODO: Vertex Shader Constants */
2959 s->Changed.vertexShader = TRUE;
2961 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2962 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
2964 for (j=0; j<This->TextureUnits; i++) {
2965 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2966 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
2970 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2971 s->Changed.lightEnable[i] = TRUE;
2972 s->Changed.lights[i] = TRUE;
2975 } else {
2976 FIXME("Unrecognized state block type %d\n", Type);
2978 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2979 return D3D_OK;
2982 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2983 ICOM_THIS(IDirect3DDevice8Impl,iface);
2984 FIXME("(%p) : stub\n", This); return D3D_OK;
2986 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2987 ICOM_THIS(IDirect3DDevice8Impl,iface);
2988 FIXME("(%p) : stub\n", This); return D3D_OK;
2990 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2991 ICOM_THIS(IDirect3DDevice8Impl,iface);
2992 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
2993 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
2994 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2995 return D3D_OK;
2997 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2999 IDirect3DBaseTexture8 *oldTxt;
3001 ICOM_THIS(IDirect3DDevice8Impl,iface);
3002 D3DRESOURCETYPE textureType;
3004 oldTxt = This->StateBlock.textures[Stage];
3005 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
3007 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
3008 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
3009 This->UpdateStateBlock->textures[Stage] = pTexture;
3011 /* Handle recording of state blocks */
3012 if (This->isRecordingState) {
3013 TRACE("Recording... not performing anything\n");
3014 return D3D_OK;
3017 /* Make appropriate texture active */
3018 if (This->isMultiTexture) {
3019 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3020 checkGLcall("glActiveTextureARB");
3021 } else if (Stage>0) {
3022 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3025 /* Decrement the count of the previous texture */
3026 /* FIXME PERF: If old == new and not dirty then skip all this */
3027 if (oldTxt != NULL) {
3028 IDirect3DBaseTexture8Impl_Release(oldTxt);
3031 if (pTexture) {
3032 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
3034 /* Now setup the texture appropraitly */
3035 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
3037 if (textureType == D3DRTYPE_TEXTURE) {
3038 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
3039 int i;
3041 /* Standard 2D texture */
3042 TRACE("Standard 2d texture\n");
3043 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
3045 for (i=0; i<pTexture2->levels; i++)
3048 if (i==0 && pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3049 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3050 checkGLcall("glBindTexture");
3051 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3052 } else {
3053 if (i==0) {
3055 if (pTexture2->surfaces[i]->textureName == 0) {
3056 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
3057 checkGLcall("glGenTextures");
3058 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3061 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3062 checkGLcall("glBindTexture");
3064 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", pTexture2->levels-1);
3065 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3066 checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels)");
3069 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3070 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
3071 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3072 pTexture2->surfaces[i]->allocatedMemory);
3073 glTexImage2D(GL_TEXTURE_2D, i,
3074 fmt2glintFmt(pTexture2->format),
3075 pTexture2->surfaces[i]->myDesc.Width,
3076 pTexture2->surfaces[i]->myDesc.Height,
3078 fmt2glFmt(pTexture2->format),
3079 fmt2glType(pTexture2->format),
3080 pTexture2->surfaces[i]->allocatedMemory
3082 checkGLcall("glTexImage2D");
3084 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3085 pTexture2->Dirty = FALSE;
3090 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3091 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3092 int i;
3094 /* Standard 3D (volume) texture */
3095 TRACE("Standard 3d texture\n");
3096 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
3098 for (i=0; i<pTexture2->levels; i++)
3101 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3102 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3103 checkGLcall("glBindTexture");
3104 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3105 } else {
3106 if (i==0) {
3108 if (pTexture2->volumes[i]->textureName == 0) {
3109 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3110 checkGLcall("glGenTextures");
3111 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3114 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3115 checkGLcall("glBindTexture");
3117 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3118 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3121 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3122 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3123 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3124 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3125 pTexture2->volumes[i]->allocatedMemory);
3126 glTexImage3D(GL_TEXTURE_3D, i,
3127 fmt2glintFmt(pTexture2->format),
3128 pTexture2->volumes[i]->myDesc.Width,
3129 pTexture2->volumes[i]->myDesc.Height,
3130 pTexture2->volumes[i]->myDesc.Depth,
3132 fmt2glFmt(pTexture2->format),
3133 fmt2glType(pTexture2->format),
3134 pTexture2->volumes[i]->allocatedMemory
3136 checkGLcall("glTexImage3D");
3138 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3139 pTexture2->Dirty = FALSE;
3143 } else {
3144 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
3146 } else {
3147 TRACE("Setting to no texture (ie default texture)\n");
3148 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
3149 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3150 checkGLcall("glBindTexture");
3151 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3154 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3155 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3156 setupTextureStates (iface, Stage);
3158 return D3D_OK;
3161 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3162 ICOM_THIS(IDirect3DDevice8Impl,iface);
3163 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
3164 *pValue = This->StateBlock.texture_state[Stage][Type];
3165 return D3D_OK;
3168 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
3169 ICOM_THIS(IDirect3DDevice8Impl,iface);
3171 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3173 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
3175 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3176 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3177 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3179 /* Handle recording of state blocks */
3180 if (This->isRecordingState) {
3181 TRACE("Recording... not performing anything\n");
3182 return D3D_OK;
3185 /* Make appropriate texture active */
3186 TRACE("Activating appropriate texture state %ld\n", Stage);
3187 if (This->isMultiTexture) {
3188 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3189 checkGLcall("glActiveTextureARB");
3190 } else if (Stage>0) {
3191 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3194 switch (Type) {
3196 case D3DTSS_MINFILTER :
3197 case D3DTSS_MIPFILTER :
3199 DWORD ValueMIN = This->StateBlock.texture_state[Stage][D3DTSS_MINFILTER];
3200 DWORD ValueMIP = This->StateBlock.texture_state[Stage][D3DTSS_MIPFILTER];
3201 GLint realVal = GL_LINEAR;
3203 if (ValueMIN == D3DTEXF_POINT) {
3204 /* GL_NEAREST_* */
3205 if (ValueMIP == D3DTEXF_POINT) {
3206 realVal = GL_NEAREST_MIPMAP_NEAREST;
3207 } else if (ValueMIP == D3DTEXF_LINEAR) {
3208 realVal = GL_NEAREST_MIPMAP_LINEAR;
3209 } else if (ValueMIP == D3DTEXF_NONE) {
3210 realVal = GL_NEAREST;
3211 } else {
3212 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3213 realVal = GL_NEAREST_MIPMAP_LINEAR;
3215 } else if (ValueMIN == D3DTEXF_LINEAR) {
3216 /* GL_LINEAR_* */
3217 if (ValueMIP == D3DTEXF_POINT) {
3218 realVal = GL_LINEAR_MIPMAP_NEAREST;
3219 } else if (ValueMIP == D3DTEXF_LINEAR) {
3220 realVal = GL_LINEAR_MIPMAP_LINEAR;
3221 } else if (ValueMIP == D3DTEXF_NONE) {
3222 realVal = GL_LINEAR;
3223 } else {
3224 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3225 realVal = GL_LINEAR_MIPMAP_LINEAR;
3227 } else if (ValueMIN == D3DTEXF_NONE) {
3228 /* Doesnt really make sense - Windows just seems to disable
3229 mipmapping when this occurs */
3230 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3231 realVal = GL_LINEAR;
3233 } else {
3234 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3235 realVal = GL_LINEAR_MIPMAP_LINEAR;
3238 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3239 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3240 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3242 break;
3245 case D3DTSS_MAGFILTER :
3246 if (Value == D3DTEXF_POINT) {
3247 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3248 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3249 } else if (Value == D3DTEXF_LINEAR) {
3250 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3251 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3252 } else {
3253 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3255 break;
3257 case D3DTSS_COLORARG0 :
3258 case D3DTSS_ALPHAARG0 :
3259 /* FIXME: Mesa seems to struggle setting these at the moment */
3260 break;
3262 case D3DTSS_COLORARG1 :
3263 case D3DTSS_COLORARG2 :
3264 case D3DTSS_ALPHAARG1 :
3265 case D3DTSS_ALPHAARG2 :
3267 BOOL isAlphaReplicate = FALSE;
3268 BOOL isComplement = FALSE;
3269 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3270 int operand= GL_SRC_COLOR;
3271 int source = GL_TEXTURE;
3273 /* Catch alpha replicate */
3274 if (Value & D3DTA_ALPHAREPLICATE) {
3275 Value = Value & ~D3DTA_ALPHAREPLICATE;
3276 isAlphaReplicate = TRUE;
3279 /* Catch Complement */
3280 if (Value & D3DTA_COMPLEMENT) {
3281 Value = Value & ~D3DTA_COMPLEMENT;
3282 isComplement = TRUE;
3285 /* Calculate the operand */
3286 if (isAlphaReplicate && !isComplement) {
3287 operand = GL_SRC_ALPHA;
3288 } else if (isAlphaReplicate && isComplement) {
3289 operand = GL_ONE_MINUS_SRC_ALPHA;
3290 } else if (isComplement) {
3291 if (isAlphaArg) {
3292 operand = GL_ONE_MINUS_SRC_COLOR;
3293 } else {
3294 operand = GL_ONE_MINUS_SRC_ALPHA;
3296 } else {
3297 if (isAlphaArg) {
3298 operand = GL_SRC_ALPHA;
3299 } else {
3300 operand = GL_SRC_COLOR;
3304 /* Calculate the source */
3305 switch (Value) {
3306 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
3307 break;
3308 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
3309 break;
3310 case D3DTA_TEXTURE: source = GL_TEXTURE;
3311 break;
3312 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
3313 break;
3315 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
3316 isnt supported until base GL supports it
3317 There is no concept of temp registers as far as I can tell */
3319 default:
3320 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
3323 if (isAlphaArg) {
3324 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3325 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3326 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3327 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3328 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3329 } else {
3330 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3331 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3332 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3333 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3334 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3337 break;
3339 case D3DTSS_ALPHAOP :
3340 case D3DTSS_COLOROP :
3343 int Scale = 1;
3344 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3346 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3347 /* TODO: Disable by making this and all later levels disabled */
3348 glDisable(GL_TEXTURE_1D);
3349 checkGLcall("Disable GL_TEXTURE_1D");
3350 glDisable(GL_TEXTURE_2D);
3351 checkGLcall("Disable GL_TEXTURE_2D");
3352 glDisable(GL_TEXTURE_3D);
3353 checkGLcall("Disable GL_TEXTURE_3D");
3354 } else {
3356 /* Enable only the appropriate texture dimension */
3357 if (Type==D3DTSS_COLOROP) {
3358 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
3359 glEnable(GL_TEXTURE_1D);
3360 checkGLcall("Enable GL_TEXTURE_1D");
3361 } else {
3362 glDisable(GL_TEXTURE_1D);
3363 checkGLcall("Disable GL_TEXTURE_1D");
3365 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
3366 glEnable(GL_TEXTURE_2D);
3367 checkGLcall("Enable GL_TEXTURE_2D");
3368 } else {
3369 glDisable(GL_TEXTURE_2D);
3370 checkGLcall("Disable GL_TEXTURE_2D");
3372 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
3373 glEnable(GL_TEXTURE_3D);
3374 checkGLcall("Enable GL_TEXTURE_3D");
3375 } else {
3376 glDisable(GL_TEXTURE_3D);
3377 checkGLcall("Disable GL_TEXTURE_3D");
3381 /* Now set up the operand correctly */
3382 switch (Value) {
3383 case D3DTOP_DISABLE :
3384 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3385 and it works, so ignore this op */
3386 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3387 break;
3389 case D3DTOP_SELECTARG1 :
3390 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3391 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3392 break;
3394 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3395 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3396 case D3DTOP_MODULATE :
3398 /* Correct scale */
3399 if (Type == D3DTSS_ALPHAOP) {
3400 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3401 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3402 } else {
3403 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3404 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3406 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3407 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3408 break;
3410 case D3DTOP_ADD :
3411 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3412 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3413 break;
3415 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3416 case D3DTOP_ADDSIGNED :
3417 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3418 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3419 break;
3421 case D3DTOP_DOTPRODUCT3 :
3422 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3423 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3424 break;*/
3426 case D3DTOP_SUBTRACT :
3427 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3428 case D3DTOP_SELECTARG2 :
3429 /* GL_REPLACE, swap args 0 and 1? */
3430 case D3DTOP_ADDSMOOTH :
3431 case D3DTOP_BLENDDIFFUSEALPHA :
3432 case D3DTOP_BLENDTEXTUREALPHA :
3433 case D3DTOP_BLENDFACTORALPHA :
3434 case D3DTOP_BLENDTEXTUREALPHAPM :
3435 case D3DTOP_BLENDCURRENTALPHA :
3436 case D3DTOP_PREMODULATE :
3437 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3438 case D3DTOP_MODULATECOLOR_ADDALPHA :
3439 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3440 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3441 case D3DTOP_BUMPENVMAP :
3442 case D3DTOP_BUMPENVMAPLUMINANCE :
3443 case D3DTOP_MULTIPLYADD :
3444 case D3DTOP_LERP :
3445 default:
3446 FIXME("Unhandled texture operation %ld\n", Value);
3449 break;
3452 case D3DTSS_ADDRESSU :
3453 case D3DTSS_ADDRESSV :
3454 case D3DTSS_ADDRESSW :
3456 GLint wrapParm = GL_REPEAT;
3457 switch (Value) {
3458 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3459 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP; break;
3460 case D3DTADDRESS_BORDER: wrapParm = GL_CLAMP_TO_EDGE; break;
3462 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL? */
3463 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL? */
3464 default:
3465 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3466 wrapParm = GL_REPEAT;
3469 switch (Type) {
3470 case D3DTSS_ADDRESSU:
3471 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3472 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3473 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3474 break;
3475 case D3DTSS_ADDRESSV:
3476 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3477 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3478 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3479 break;
3480 case D3DTSS_ADDRESSW:
3481 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3482 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3483 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3484 break;
3485 default: /* nop */
3486 break; /** stupic compilator */
3489 break;
3491 case D3DTSS_BORDERCOLOR :
3493 float col[4];
3494 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3495 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3496 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3497 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3499 TRACE("Setting border color for %x to %lx\n", This->StateBlock.textureDimensions[Stage], Value);
3500 glTexParameterfv(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3501 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3503 break;
3505 /* Unhandled */
3506 case D3DTSS_BUMPENVMAT00 :
3507 case D3DTSS_BUMPENVMAT01 :
3508 case D3DTSS_BUMPENVMAT10 :
3509 case D3DTSS_BUMPENVMAT11 :
3510 case D3DTSS_TEXCOORDINDEX :
3511 case D3DTSS_MIPMAPLODBIAS :
3512 case D3DTSS_MAXMIPLEVEL :
3513 case D3DTSS_MAXANISOTROPY :
3514 case D3DTSS_BUMPENVLSCALE :
3515 case D3DTSS_BUMPENVLOFFSET :
3516 case D3DTSS_TEXTURETRANSFORMFLAGS :
3517 case D3DTSS_RESULTARG :
3518 default:
3519 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3520 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3522 return D3D_OK;
3524 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3525 ICOM_THIS(IDirect3DDevice8Impl,iface);
3526 FIXME("(%p) : stub\n", This); return D3D_OK;
3528 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3529 ICOM_THIS(IDirect3DDevice8Impl,iface);
3530 FIXME("(%p) : stub\n", This); return D3D_OK;
3532 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3533 ICOM_THIS(IDirect3DDevice8Impl,iface);
3534 FIXME("(%p) : stub\n", This); return D3D_OK;
3536 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3537 ICOM_THIS(IDirect3DDevice8Impl,iface);
3538 FIXME("(%p) : stub\n", This); return D3D_OK;
3540 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3541 ICOM_THIS(IDirect3DDevice8Impl,iface);
3542 FIXME("(%p) : stub\n", This); return D3D_OK;
3544 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3545 ICOM_THIS(IDirect3DDevice8Impl,iface);
3546 FIXME("(%p) : stub\n", This); return D3D_OK;
3548 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3550 IDirect3DVertexBuffer8 *pVB;
3552 ICOM_THIS(IDirect3DDevice8Impl,iface);
3553 pVB = This->StateBlock.stream_source[0];
3555 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3557 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3558 This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
3560 return D3D_OK;
3562 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3563 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3564 UINT idxStride = 2;
3565 IDirect3DIndexBuffer8 *pIB;
3566 IDirect3DVertexBuffer8 *pVB;
3567 D3DINDEXBUFFER_DESC IdxBufDsc;
3569 ICOM_THIS(IDirect3DDevice8Impl,iface);
3570 pIB = This->StateBlock.pIndexData;
3571 pVB = This->StateBlock.stream_source[0];
3573 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3574 minIndex, NumVertices, startIndex, primCount);
3576 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3577 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3578 idxStride = 2;
3579 } else {
3580 idxStride = 4;
3583 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3584 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3585 minIndex);
3587 return D3D_OK;
3589 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3590 ICOM_THIS(IDirect3DDevice8Impl,iface);
3592 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3594 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3596 This->StateBlock.stream_source[0] = NULL;
3597 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3598 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3599 0, 0, 0, NULL, 0);
3600 This->StateBlock.stream_stride[0] = 0;
3602 /*stream zero settings set to null at end */
3603 return D3D_OK;
3605 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3606 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3607 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3608 UINT VertexStreamZeroStride) {
3609 int idxStride;
3610 ICOM_THIS(IDirect3DDevice8Impl,iface);
3611 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3612 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3614 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3615 if (IndexDataFormat == D3DFMT_INDEX16) {
3616 idxStride = 2;
3617 } else {
3618 idxStride = 4;
3621 This->StateBlock.stream_source[0] = NULL;
3622 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3623 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3624 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3626 /*stream zero settings set to null at end */
3627 This->StateBlock.stream_stride[0] = 0;
3628 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3630 return D3D_OK;
3632 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3633 ICOM_THIS(IDirect3DDevice8Impl,iface);
3634 FIXME("(%p) : stub\n", This); return D3D_OK;
3636 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3637 ICOM_THIS(IDirect3DDevice8Impl,iface);
3638 VERTEXSHADER8* object;
3639 UINT i;
3641 FIXME("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3642 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3643 return D3DERR_INVALIDCALL;
3645 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(VERTEXSHADER8*); ++i) ;
3646 if (i >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) {
3647 return D3DERR_OUTOFVIDEOMEMORY;
3649 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERTEXSHADER8));
3650 if (NULL == object) {
3651 return D3DERR_OUTOFVIDEOMEMORY;
3654 object->usage = Usage;
3655 object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADERDATA8));
3657 VertexShaders[i] = object;
3658 *pHandle = VS_HIGHESTFIXEDFXF + i;
3660 object->decl = (DWORD*) pDeclaration;
3661 object->function = (DWORD*) pFunction;
3663 vshader_decl_parse(object);
3664 vshader_program_parse(object);
3666 /* copy the function ... because it will certainly be released by application */
3667 if (NULL != pFunction) {
3668 object->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->functionLength);
3669 memcpy(object->function, pFunction, object->functionLength);
3671 /* copy the declaration too */
3672 object->decl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declLength);
3673 memcpy(object->decl, pDeclaration, object->declLength);
3674 return D3D_OK;
3676 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3677 ICOM_THIS(IDirect3DDevice8Impl,iface);
3679 This->UpdateStateBlock->VertexShader = Handle;
3680 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3681 This->UpdateStateBlock->Set.vertexShader = TRUE;
3683 /* Handle recording of state blocks */
3684 if (This->isRecordingState) {
3685 TRACE("Recording... not performing anything\n");
3686 return D3D_OK;
3688 if (Handle <= VS_HIGHESTFIXEDFXF) {
3689 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3690 return D3D_OK;
3691 } else {
3692 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3693 return D3D_OK;
3696 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3697 ICOM_THIS(IDirect3DDevice8Impl,iface);
3698 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock.VertexShader);
3699 *pHandle = This->StateBlock.VertexShader;
3700 return D3D_OK;
3703 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3704 ICOM_THIS(IDirect3DDevice8Impl,iface);
3705 VERTEXSHADER8* object;
3707 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3708 return D3DERR_INVALIDCALL;
3710 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3711 if (NULL == object) {
3712 return D3DERR_INVALIDCALL;
3714 TRACE("(%p) : freing VertexShader %p\n", This, object);
3715 /* TODO: check validity of object */
3716 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3717 HeapFree(GetProcessHeap(), 0, (void *)object->decl);
3718 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3719 HeapFree(GetProcessHeap(), 0, (void *)object);
3720 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3721 return D3D_OK;
3724 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3725 ICOM_THIS(IDirect3DDevice8Impl,iface);
3726 VERTEXSHADER8* object;
3727 DWORD Handle = This->UpdateStateBlock->VertexShader;
3729 /* FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); */
3730 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3731 return D3DERR_INVALIDCALL;
3733 object = VERTEX_SHADER(Handle);
3734 if (NULL == object || NULL == pConstantData) {
3735 return D3DERR_INVALIDCALL;
3737 if (NULL == object->data) { /* temporary while datas not supported */
3738 FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
3739 return D3DERR_INVALIDCALL;
3741 memcpy(object->data->C + Register, pConstantData, ConstantCount * sizeof(D3DSHADERVECTOR));
3743 return D3D_OK;
3745 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3746 ICOM_THIS(IDirect3DDevice8Impl,iface);
3747 VERTEXSHADER8* object;
3748 DWORD Handle = This->UpdateStateBlock->VertexShader;
3750 FIXME("(%p) : VertexShader_GetConstant not fully supported yet\n", This);
3752 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3753 return D3DERR_INVALIDCALL;
3755 object = VERTEX_SHADER(Handle);
3756 if (NULL == object || NULL == pConstantData) {
3757 return D3DERR_INVALIDCALL;
3759 if (NULL == object->data) { /* temporary while datas not supported */
3760 return D3DERR_INVALIDCALL;
3762 memcpy(pConstantData, object->data->C + Register, ConstantCount * sizeof(D3DSHADERVECTOR));
3764 return D3D_OK;
3766 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3767 ICOM_THIS(IDirect3DDevice8Impl,iface);
3768 VERTEXSHADER8* object;
3770 object = VERTEX_SHADER(Handle);
3771 if (NULL == object) {
3772 return D3DERR_INVALIDCALL;
3774 if (NULL == pData) {
3775 *pSizeOfData = object->declLength;
3776 return D3D_OK;
3778 if (*pSizeOfData < object->declLength) {
3779 *pSizeOfData = object->declLength;
3780 return D3DERR_MOREDATA;
3782 TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
3783 memcpy(pData, object->decl, object->declLength);
3784 return D3D_OK;
3786 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3787 ICOM_THIS(IDirect3DDevice8Impl,iface);
3788 VERTEXSHADER8* object;
3790 object = VERTEX_SHADER(Handle);
3791 if (NULL == object) {
3792 return D3DERR_INVALIDCALL;
3794 if (NULL == pData) {
3795 *pSizeOfData = object->functionLength;
3796 return D3D_OK;
3798 if (*pSizeOfData < object->functionLength) {
3799 *pSizeOfData = object->functionLength;
3800 return D3DERR_MOREDATA;
3802 if (NULL == object->function) { /* no function defined */
3803 TRACE("(%p) : GetVertexShaderFunction no User Function defined using NULL to %p\n", This, pData);
3804 ((DWORD *) pData) = NULL;
3805 } else {
3806 TRACE("(%p) : GetVertexShaderFunction copying to %p\n", This, pData);
3807 memcpy(pData, object->function, object->functionLength);
3809 return D3D_OK;
3812 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3813 ICOM_THIS(IDirect3DDevice8Impl,iface);
3814 IDirect3DIndexBuffer8 *oldIdxs;
3816 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3817 oldIdxs = This->StateBlock.pIndexData;
3819 This->UpdateStateBlock->Changed.Indices = TRUE;
3820 This->UpdateStateBlock->Set.Indices = TRUE;
3821 This->UpdateStateBlock->pIndexData = pIndexData;
3822 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3824 /* Handle recording of state blocks */
3825 if (This->isRecordingState) {
3826 TRACE("Recording... not performing anything\n");
3827 return D3D_OK;
3830 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3831 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3832 return D3D_OK;
3834 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3835 ICOM_THIS(IDirect3DDevice8Impl,iface);
3836 FIXME("(%p) : stub\n", This);
3838 *ppIndexData = This->StateBlock.pIndexData;
3839 /* up ref count on ppindexdata */
3840 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3841 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3843 return D3D_OK;
3845 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3846 ICOM_THIS(IDirect3DDevice8Impl,iface);
3847 PIXELSHADER8* object;
3848 UINT i;
3850 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3851 if (NULL == pFunction || NULL == pHandle) {
3852 return D3DERR_INVALIDCALL;
3854 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(PIXELSHADER8*); ++i) ;
3855 if (i >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) {
3856 return D3DERR_OUTOFVIDEOMEMORY;
3858 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PIXELSHADER8));
3859 if (NULL == object) {
3860 return D3DERR_OUTOFVIDEOMEMORY;
3863 object->data = NULL; /* TODO */
3865 PixelShaders[i] = object;
3866 *pHandle = VS_HIGHESTFIXEDFXF + i;
3868 object->function = pFunction;
3869 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3870 object->functionLength = i + 1;
3872 return D3D_OK;
3874 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3875 ICOM_THIS(IDirect3DDevice8Impl,iface);
3877 This->UpdateStateBlock->PixelShader = Handle;
3878 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3879 This->UpdateStateBlock->Set.pixelShader = TRUE;
3881 /* Handle recording of state blocks */
3882 if (This->isRecordingState) {
3883 TRACE("Recording... not performing anything\n");
3884 return D3D_OK;
3887 /* FIXME: Quieten when not being used */
3888 if (Handle != 0) {
3889 FIXME("(%p) : stub %ld\n", This, Handle);
3890 } else {
3891 TRACE("(%p) : stub %ld\n", This, Handle);
3894 return D3D_OK;
3896 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3897 ICOM_THIS(IDirect3DDevice8Impl,iface);
3898 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock.PixelShader);
3899 *pHandle = This->StateBlock.PixelShader;
3900 return D3D_OK;
3903 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3904 ICOM_THIS(IDirect3DDevice8Impl,iface);
3905 PIXELSHADER8* object;
3907 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3908 return D3DERR_INVALIDCALL;
3910 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3911 TRACE("(%p) : freeing PixelShader %p\n", This, object);
3912 /* TODO: check validity of object before free */
3913 HeapFree(GetProcessHeap(), 0, (void *)object);
3914 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3915 return D3D_OK;
3917 #define PIXEL_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
3919 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
3920 ICOM_THIS(IDirect3DDevice8Impl,iface);
3921 FIXME("(%p) : stub\n", This);
3922 return D3D_OK;
3924 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
3925 ICOM_THIS(IDirect3DDevice8Impl,iface);
3926 FIXME("(%p) : stub\n", This);
3927 return D3D_OK;
3929 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3930 ICOM_THIS(IDirect3DDevice8Impl,iface);
3931 PIXELSHADER8* object;
3933 object = PIXEL_SHADER(Handle);
3934 if (NULL == object) {
3935 return D3DERR_INVALIDCALL;
3937 if (NULL == pData) {
3938 *pSizeOfData = object->functionLength;
3939 return D3D_OK;
3941 if (*pSizeOfData < object->functionLength) {
3942 *pSizeOfData = object->functionLength;
3943 return D3DERR_MOREDATA;
3945 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
3946 memcpy(pData, object->function, object->functionLength);
3947 return D3D_OK;
3949 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3950 ICOM_THIS(IDirect3DDevice8Impl,iface);
3951 FIXME("(%p) : stub\n", This); return D3D_OK;
3953 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3954 ICOM_THIS(IDirect3DDevice8Impl,iface);
3955 FIXME("(%p) : stub\n", This); return D3D_OK;
3957 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3958 ICOM_THIS(IDirect3DDevice8Impl,iface);
3959 FIXME("(%p) : stub\n", This); return D3D_OK;
3962 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3963 IDirect3DVertexBuffer8 *oldSrc;
3964 ICOM_THIS(IDirect3DDevice8Impl,iface);
3966 oldSrc = This->StateBlock.stream_source[StreamNumber];
3967 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3969 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3970 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3971 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3972 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3974 /* Handle recording of state blocks */
3975 if (This->isRecordingState) {
3976 TRACE("Recording... not performing anything\n");
3977 return D3D_OK;
3980 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3981 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3982 return D3D_OK;
3984 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3985 ICOM_THIS(IDirect3DDevice8Impl,iface);
3986 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
3987 *pStream = This->StateBlock.stream_source[StreamNumber];
3988 *pStride = This->StateBlock.stream_stride[StreamNumber];
3989 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3990 return D3D_OK;
3994 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3996 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3997 IDirect3DDevice8Impl_QueryInterface,
3998 IDirect3DDevice8Impl_AddRef,
3999 IDirect3DDevice8Impl_Release,
4000 IDirect3DDevice8Impl_TestCooperativeLevel,
4001 IDirect3DDevice8Impl_GetAvailableTextureMem,
4002 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
4003 IDirect3DDevice8Impl_GetDirect3D,
4004 IDirect3DDevice8Impl_GetDeviceCaps,
4005 IDirect3DDevice8Impl_GetDisplayMode,
4006 IDirect3DDevice8Impl_GetCreationParameters,
4007 IDirect3DDevice8Impl_SetCursorProperties,
4008 IDirect3DDevice8Impl_SetCursorPosition,
4009 IDirect3DDevice8Impl_ShowCursor,
4010 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
4011 IDirect3DDevice8Impl_Reset,
4012 IDirect3DDevice8Impl_Present,
4013 IDirect3DDevice8Impl_GetBackBuffer,
4014 IDirect3DDevice8Impl_GetRasterStatus,
4015 IDirect3DDevice8Impl_SetGammaRamp,
4016 IDirect3DDevice8Impl_GetGammaRamp,
4017 IDirect3DDevice8Impl_CreateTexture,
4018 IDirect3DDevice8Impl_CreateVolumeTexture,
4019 IDirect3DDevice8Impl_CreateCubeTexture,
4020 IDirect3DDevice8Impl_CreateVertexBuffer,
4021 IDirect3DDevice8Impl_CreateIndexBuffer,
4022 IDirect3DDevice8Impl_CreateRenderTarget,
4023 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4024 IDirect3DDevice8Impl_CreateImageSurface,
4025 IDirect3DDevice8Impl_CopyRects,
4026 IDirect3DDevice8Impl_UpdateTexture,
4027 IDirect3DDevice8Impl_GetFrontBuffer,
4028 IDirect3DDevice8Impl_SetRenderTarget,
4029 IDirect3DDevice8Impl_GetRenderTarget,
4030 IDirect3DDevice8Impl_GetDepthStencilSurface,
4031 IDirect3DDevice8Impl_BeginScene,
4032 IDirect3DDevice8Impl_EndScene,
4033 IDirect3DDevice8Impl_Clear,
4034 IDirect3DDevice8Impl_SetTransform,
4035 IDirect3DDevice8Impl_GetTransform,
4036 IDirect3DDevice8Impl_MultiplyTransform,
4037 IDirect3DDevice8Impl_SetViewport,
4038 IDirect3DDevice8Impl_GetViewport,
4039 IDirect3DDevice8Impl_SetMaterial,
4040 IDirect3DDevice8Impl_GetMaterial,
4041 IDirect3DDevice8Impl_SetLight,
4042 IDirect3DDevice8Impl_GetLight,
4043 IDirect3DDevice8Impl_LightEnable,
4044 IDirect3DDevice8Impl_GetLightEnable,
4045 IDirect3DDevice8Impl_SetClipPlane,
4046 IDirect3DDevice8Impl_GetClipPlane,
4047 IDirect3DDevice8Impl_SetRenderState,
4048 IDirect3DDevice8Impl_GetRenderState,
4049 IDirect3DDevice8Impl_BeginStateBlock,
4050 IDirect3DDevice8Impl_EndStateBlock,
4051 IDirect3DDevice8Impl_ApplyStateBlock,
4052 IDirect3DDevice8Impl_CaptureStateBlock,
4053 IDirect3DDevice8Impl_DeleteStateBlock,
4054 IDirect3DDevice8Impl_CreateStateBlock,
4055 IDirect3DDevice8Impl_SetClipStatus,
4056 IDirect3DDevice8Impl_GetClipStatus,
4057 IDirect3DDevice8Impl_GetTexture,
4058 IDirect3DDevice8Impl_SetTexture,
4059 IDirect3DDevice8Impl_GetTextureStageState,
4060 IDirect3DDevice8Impl_SetTextureStageState,
4061 IDirect3DDevice8Impl_ValidateDevice,
4062 IDirect3DDevice8Impl_GetInfo,
4063 IDirect3DDevice8Impl_SetPaletteEntries,
4064 IDirect3DDevice8Impl_GetPaletteEntries,
4065 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4066 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4067 IDirect3DDevice8Impl_DrawPrimitive,
4068 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4069 IDirect3DDevice8Impl_DrawPrimitiveUP,
4070 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4071 IDirect3DDevice8Impl_ProcessVertices,
4072 IDirect3DDevice8Impl_CreateVertexShader,
4073 IDirect3DDevice8Impl_SetVertexShader,
4074 IDirect3DDevice8Impl_GetVertexShader,
4075 IDirect3DDevice8Impl_DeleteVertexShader,
4076 IDirect3DDevice8Impl_SetVertexShaderConstant,
4077 IDirect3DDevice8Impl_GetVertexShaderConstant,
4078 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4079 IDirect3DDevice8Impl_GetVertexShaderFunction,
4080 IDirect3DDevice8Impl_SetStreamSource,
4081 IDirect3DDevice8Impl_GetStreamSource,
4082 IDirect3DDevice8Impl_SetIndices,
4083 IDirect3DDevice8Impl_GetIndices,
4084 IDirect3DDevice8Impl_CreatePixelShader,
4085 IDirect3DDevice8Impl_SetPixelShader,
4086 IDirect3DDevice8Impl_GetPixelShader,
4087 IDirect3DDevice8Impl_DeletePixelShader,
4088 IDirect3DDevice8Impl_SetPixelShaderConstant,
4089 IDirect3DDevice8Impl_GetPixelShaderConstant,
4090 IDirect3DDevice8Impl_GetPixelShaderFunction,
4091 IDirect3DDevice8Impl_DrawRectPatch,
4092 IDirect3DDevice8Impl_DrawTriPatch,
4093 IDirect3DDevice8Impl_DeletePatch
4096 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
4097 D3DLINEPATTERN lp;
4098 int i;
4100 ICOM_THIS(IDirect3DDevice8Impl,iface);
4102 /* Note this may have a large overhead but it should only be executed
4103 once, in order to initialize the complete state of the device and
4104 all opengl equivalents */
4105 TRACE("-----------------------> Setting up device defaults...\n");
4106 This->StateBlock.blockType = D3DSBT_ALL;
4108 /* FIXME: Set some of the defaults for lights, transforms etc */
4109 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)], &idmatrix, sizeof(idmatrix));
4110 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
4111 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
4113 /* Render states: */
4114 if (This->PresentParms.EnableAutoDepthStencil) {
4115 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
4116 } else {
4117 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
4119 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
4120 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
4121 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
4122 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
4123 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
4124 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
4125 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
4126 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
4127 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
4128 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
4129 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
4130 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
4131 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
4132 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
4133 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
4134 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
4135 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
4136 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
4137 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
4138 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
4139 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
4140 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
4141 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
4142 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
4143 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
4144 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
4145 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
4146 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
4147 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
4148 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
4149 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
4150 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
4151 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
4152 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
4153 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
4154 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
4155 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
4156 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
4157 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
4158 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
4159 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
4160 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
4161 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
4162 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
4163 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
4164 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
4165 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
4166 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
4167 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
4168 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
4169 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
4170 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
4171 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
4172 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
4173 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
4174 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
4175 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
4176 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
4177 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
4178 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
4179 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
4180 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
4181 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
4182 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
4183 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
4184 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
4185 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
4186 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
4187 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
4188 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
4189 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
4190 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
4191 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4192 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
4193 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
4195 /* Texture Stage States - Put directly into state block, we will call function below */
4196 for (i=0; i<This->TextureUnits;i++) {
4197 memcpy(&This->StateBlock.transforms[D3DTS_TEXTURE0+i], &idmatrix, sizeof(idmatrix));
4198 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
4199 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
4200 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
4201 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
4202 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
4203 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
4204 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
4205 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
4206 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
4207 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
4208 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
4209 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
4210 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
4211 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
4212 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
4213 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
4214 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
4215 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
4216 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
4217 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
4218 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
4219 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
4220 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
4221 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
4222 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
4223 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
4224 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
4227 /* Under DirectX you can have texture stage operations even if no texture is
4228 bound, whereas opengl will only do texture operations when a valid texture is
4229 bound. We emulate this by creating dummy textures and binding them to each
4230 texture stage, but disable all stages by default. Hence if a stage is enabled
4231 then the default texture will kick in until replaced by a SetTexture call */
4233 for (i=0; i<This->TextureUnits; i++) {
4234 GLubyte white = 255;
4236 /* Note this avoids calling settexture, so pretend it has been called */
4237 This->StateBlock.Set.textures[i] = TRUE;
4238 This->StateBlock.Changed.textures[i] = TRUE;
4239 This->StateBlock.textures[i] = NULL;
4241 /* Make appropriate texture active */
4242 if (This->isMultiTexture) {
4243 glActiveTextureARB(GL_TEXTURE0_ARB + i);
4244 checkGLcall("glActiveTextureARB");
4245 } else if (i>0) {
4246 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
4249 /* Generate an opengl texture name */
4250 glGenTextures(1, &This->dummyTextureName[i]);
4251 checkGLcall("glGenTextures");
4252 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
4254 /* Generate a dummy 1d texture */
4255 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
4256 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
4257 checkGLcall("glBindTexture");
4259 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
4260 checkGLcall("glTexImage1D");
4262 /* Reapply all the texture state information to this texture */
4263 setupTextureStates(iface, i);
4266 TRACE("-----------------------> Device defaults now set up...\n");
4271 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
4272 D3DRS_ALPHABLENDENABLE ,
4273 D3DRS_ALPHAFUNC ,
4274 D3DRS_ALPHAREF ,
4275 D3DRS_ALPHATESTENABLE ,
4276 D3DRS_BLENDOP ,
4277 D3DRS_COLORWRITEENABLE ,
4278 D3DRS_DESTBLEND ,
4279 D3DRS_DITHERENABLE ,
4280 D3DRS_EDGEANTIALIAS ,
4281 D3DRS_FILLMODE ,
4282 D3DRS_FOGDENSITY ,
4283 D3DRS_FOGEND ,
4284 D3DRS_FOGSTART ,
4285 D3DRS_LASTPIXEL ,
4286 D3DRS_LINEPATTERN ,
4287 D3DRS_SHADEMODE ,
4288 D3DRS_SRCBLEND ,
4289 D3DRS_STENCILENABLE ,
4290 D3DRS_STENCILFAIL ,
4291 D3DRS_STENCILFUNC ,
4292 D3DRS_STENCILMASK ,
4293 D3DRS_STENCILPASS ,
4294 D3DRS_STENCILREF ,
4295 D3DRS_STENCILWRITEMASK ,
4296 D3DRS_STENCILZFAIL ,
4297 D3DRS_TEXTUREFACTOR ,
4298 D3DRS_WRAP0 ,
4299 D3DRS_WRAP1 ,
4300 D3DRS_WRAP2 ,
4301 D3DRS_WRAP3 ,
4302 D3DRS_WRAP4 ,
4303 D3DRS_WRAP5 ,
4304 D3DRS_WRAP6 ,
4305 D3DRS_WRAP7 ,
4306 D3DRS_ZBIAS ,
4307 D3DRS_ZENABLE ,
4308 D3DRS_ZFUNC ,
4309 D3DRS_ZWRITEENABLE
4312 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
4313 D3DTSS_ADDRESSU ,
4314 D3DTSS_ADDRESSV ,
4315 D3DTSS_ADDRESSW ,
4316 D3DTSS_ALPHAARG0 ,
4317 D3DTSS_ALPHAARG1 ,
4318 D3DTSS_ALPHAARG2 ,
4319 D3DTSS_ALPHAOP ,
4320 D3DTSS_BORDERCOLOR ,
4321 D3DTSS_BUMPENVLOFFSET ,
4322 D3DTSS_BUMPENVLSCALE ,
4323 D3DTSS_BUMPENVMAT00 ,
4324 D3DTSS_BUMPENVMAT01 ,
4325 D3DTSS_BUMPENVMAT10 ,
4326 D3DTSS_BUMPENVMAT11 ,
4327 D3DTSS_COLORARG0 ,
4328 D3DTSS_COLORARG1 ,
4329 D3DTSS_COLORARG2 ,
4330 D3DTSS_COLOROP ,
4331 D3DTSS_MAGFILTER ,
4332 D3DTSS_MAXANISOTROPY ,
4333 D3DTSS_MAXMIPLEVEL ,
4334 D3DTSS_MINFILTER ,
4335 D3DTSS_MIPFILTER ,
4336 D3DTSS_MIPMAPLODBIAS ,
4337 D3DTSS_RESULTARG ,
4338 D3DTSS_TEXCOORDINDEX ,
4339 D3DTSS_TEXTURETRANSFORMFLAGS
4342 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
4343 D3DRS_AMBIENT ,
4344 D3DRS_AMBIENTMATERIALSOURCE ,
4345 D3DRS_CLIPPING ,
4346 D3DRS_CLIPPLANEENABLE ,
4347 D3DRS_COLORVERTEX ,
4348 D3DRS_DIFFUSEMATERIALSOURCE ,
4349 D3DRS_EMISSIVEMATERIALSOURCE ,
4350 D3DRS_FOGDENSITY ,
4351 D3DRS_FOGEND ,
4352 D3DRS_FOGSTART ,
4353 D3DRS_FOGTABLEMODE ,
4354 D3DRS_FOGVERTEXMODE ,
4355 D3DRS_INDEXEDVERTEXBLENDENABLE ,
4356 D3DRS_LIGHTING ,
4357 D3DRS_LOCALVIEWER ,
4358 D3DRS_MULTISAMPLEANTIALIAS ,
4359 D3DRS_MULTISAMPLEMASK ,
4360 D3DRS_NORMALIZENORMALS ,
4361 D3DRS_PATCHEDGESTYLE ,
4362 D3DRS_PATCHSEGMENTS ,
4363 D3DRS_POINTSCALE_A ,
4364 D3DRS_POINTSCALE_B ,
4365 D3DRS_POINTSCALE_C ,
4366 D3DRS_POINTSCALEENABLE ,
4367 D3DRS_POINTSIZE ,
4368 D3DRS_POINTSIZE_MAX ,
4369 D3DRS_POINTSIZE_MIN ,
4370 D3DRS_POINTSPRITEENABLE ,
4371 D3DRS_RANGEFOGENABLE ,
4372 D3DRS_SOFTWAREVERTEXPROCESSING ,
4373 D3DRS_SPECULARMATERIALSOURCE ,
4374 D3DRS_TWEENFACTOR ,
4375 D3DRS_VERTEXBLEND
4378 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
4379 D3DTSS_TEXCOORDINDEX ,
4380 D3DTSS_TEXTURETRANSFORMFLAGS