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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
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: */
41 # define VTRACE(A) TRACE A
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) \
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)); \
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);
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] = {
92 /* Routine common to the draw primitive and draw indexed primitive routines */
93 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
100 const void *vertexBufData,
103 long StartVertexIndex,
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);
124 if (NULL == vertex_shader->function) {
125 TRACE("vertex shader declared without program, using FVF pure mode\n");
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;
146 const void *curVtx = NULL;
147 const short *pIdxBufS = NULL;
148 const long *pIdxBufL = NULL;
150 BOOL isLightingOn = FALSE;
151 BOOL enableTexture = FALSE;
156 z = 0.0f; /* x,y,z coordinates */
159 nz = 0.0f; /* normal x,y,z coordinates */
160 float rhw = 0.0f; /* rhw */
161 float ptSize = 0.0f; /* Point size */
162 DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
163 DWORD specularColor = 0; /* Specular Color */
168 if (idxBytes == 2) pIdxBufS = (short *) idxData;
169 else pIdxBufL = (long *) idxData;
172 /* Check vertex formats expected ? */
174 * FVF parser as seen it
175 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/Reference/CPP/D3D/FlexibleVertexFormatFlags.asp
177 normal = fvf & D3DFVF_NORMAL;
178 isRHW = fvf & D3DFVF_XYZRHW;
179 isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
180 numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2 + ((FALSE == isLastUByte4) ? 0 : -1); /* WARNING can be < 0 because -2 */
181 isPtSize = fvf & D3DFVF_PSIZE;
182 isDiffuse = fvf & D3DFVF_DIFFUSE;
183 isSpecular = fvf & D3DFVF_SPECULAR;
184 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
186 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d)\n",
187 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends);
189 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
190 set by the appropriate render state */
192 isLightingOn = glIsEnabled(GL_LIGHTING);
193 glDisable(GL_LIGHTING);
194 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
198 double height, width, minZ, maxZ;
200 * Already transformed vertex do not need transform
201 * matrices. Reset all matrices to identity.
202 * Leave the default matrix in world mode.
204 glMatrixMode(GL_PROJECTION);
205 checkGLcall("glMatrixMode");
207 checkGLcall("glLoadIdentity");
208 glMatrixMode(GL_MODELVIEW);
209 checkGLcall("glMatrixMode");
211 checkGLcall("glLoadIdentity");
212 height = This->StateBlock.viewport.Height;
213 width = This->StateBlock.viewport.Width;
214 minZ = This->StateBlock.viewport.MinZ;
215 maxZ = This->StateBlock.viewport.MaxZ;
216 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
217 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
218 checkGLcall("glOrtho");
220 glMatrixMode(GL_PROJECTION);
221 checkGLcall("glMatrixMode");
222 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
223 checkGLcall("glLoadMatrixf");
224 glMatrixMode(GL_MODELVIEW);
225 checkGLcall("glMatrixMode");
226 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
227 checkGLcall("glLoadMatrixf");
228 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
229 checkGLcall("glMultMatrixf");
232 /* Set OpenGL to the appropriate Primitive Type */
233 switch (PrimitiveType) {
234 case D3DPT_POINTLIST:
236 primType = GL_POINTS;
237 NumVertexes = NumPrimitives;
243 NumVertexes = NumPrimitives * 2;
246 case D3DPT_LINESTRIP:
247 TRACE("LINE_STRIP\n");
248 primType = GL_LINE_STRIP;
249 NumVertexes = NumPrimitives + 1;
252 case D3DPT_TRIANGLELIST:
253 TRACE("TRIANGLES\n");
254 primType = GL_TRIANGLES;
255 NumVertexes = NumPrimitives * 3;
258 case D3DPT_TRIANGLESTRIP:
259 TRACE("TRIANGLE_STRIP\n");
260 primType = GL_TRIANGLE_STRIP;
261 NumVertexes = NumPrimitives + 2;
264 case D3DPT_TRIANGLEFAN:
265 TRACE("TRIANGLE_FAN\n");
266 primType = GL_TRIANGLE_FAN;
267 NumVertexes = NumPrimitives + 2;
271 FIXME("Unhandled primitive\n");
275 /* Fixme, Ideally, only use this per-vertex code for software HAL
276 but until opengl supports all the functions returned to setup
277 vertex arrays, we need to drop down to the slow mechanism for
280 if (isPtSize || isDiffuse || useVertexShaderFunction==TRUE || (numBlends > 0)) {
281 TRACE("Using slow per-vertex code\n");
283 /* Enable this one to be able to debug what is going on, but it is slower
284 than the pointer/array version */
285 VTRACE(("glBegin(%x)\n", primType));
288 /* Draw the primitives */
289 curVtx = vertexBufData + (StartVertexIndex * skip);
291 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
297 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
298 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
300 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
301 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
305 /* Work through the vertex buffer */
306 x = *(float *)curPos;
307 curPos = curPos + sizeof(float);
308 y = *(float *)curPos;
309 curPos = curPos + sizeof(float);
310 z = *(float *)curPos;
311 curPos = curPos + sizeof(float);
312 VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
314 /* RHW follows, only if transformed */
316 rhw = *(float *)curPos;
317 curPos = curPos + sizeof(float);
318 VTRACE(("rhw=%f\n", rhw));
324 D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
325 DWORD skippedBlendLastUByte4 = 0;
327 for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
328 ((float*)&skippedBlend)[i] = *(float *)curPos;
329 curPos = curPos + sizeof(float);
333 skippedBlendLastUByte4 = *(DWORD*)curPos;
334 curPos = curPos + sizeof(DWORD);
338 /* Vertex Normal Data (untransformed only) */
340 nx = *(float *)curPos;
341 curPos = curPos + sizeof(float);
342 ny = *(float *)curPos;
343 curPos = curPos + sizeof(float);
344 nz = *(float *)curPos;
345 curPos = curPos + sizeof(float);
346 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
350 ptSize = *(float *)curPos;
351 VTRACE(("ptSize=%f\n", ptSize));
352 curPos = curPos + sizeof(float);
356 diffuseColor = *(DWORD *)curPos;
357 VTRACE(("diffuseColor=%lx\n", diffuseColor));
358 curPos = curPos + sizeof(DWORD);
362 specularColor = *(DWORD *)curPos;
363 VTRACE(("specularColor=%lx\n", specularColor));
364 curPos = curPos + sizeof(DWORD);
367 /* ToDo: Texture coords */
368 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
371 if (!(This->isMultiTexture) && textureNo > 0) {
372 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
375 if (textureNo > This->TextureUnits) {
376 FIXME("Program using more concurrent textures than this opengl implementation support\n");
380 /* Query tex coords */
381 if (This->StateBlock.textures[textureNo] != NULL) {
382 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
383 case D3DRTYPE_TEXTURE:
384 s = *(float *)curPos;
385 curPos = curPos + sizeof(float);
386 t = *(float *)curPos;
387 curPos = curPos + sizeof(float);
388 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s,t));
390 if (TRUE == useVertexShaderFunction) {
393 if (This->isMultiTexture) {
394 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
401 case D3DRTYPE_VOLUMETEXTURE:
402 s = *(float *)curPos;
403 curPos = curPos + sizeof(float);
404 t = *(float *)curPos;
405 curPos = curPos + sizeof(float);
406 r = *(float *)curPos;
407 curPos = curPos + sizeof(float);
408 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r));
410 if (TRUE == useVertexShaderFunction) {
413 if (This->isMultiTexture) {
414 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
416 glTexCoord3f(s, t, r);
422 r = 0.0f; q = 0.0f; /* Avoid compiler warnings, need these vars later for other textures */
423 FIXME("Unhandled texture type\n");
426 /* Note I have seen a program actually do this, so just hide it and continue */
427 VTRACE(("Very odd - texture requested in FVF but not bound!\n"));
432 /** if vertex shader program specified ... using it */
433 if (TRUE == useVertexShaderFunction) {
436 * this code must become the really
437 * vs input params init
439 * because its possible to use input registers for anything
440 * and some samples use registers for other things than they are
445 * no really valid declaration, user defined input register use
446 * so fill input registers as described in vertex shader declaration
448 vshader_fill_input(vertex_shader, This, vertexBufData, StartVertexIndex,
449 (!isIndexed) ? (vx_index * skip) :
450 (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) :
451 ((pIdxBufL[StartIdx + vx_index]) * skip));
453 memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
454 vshader_program_execute_SW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
456 TRACE_VECTOR(vertex_shader->output.oPos);
457 TRACE_VECTOR(vertex_shader->output.oD[0]);
458 TRACE_VECTOR(vertex_shader->output.oD[1]);
459 TRACE_VECTOR(vertex_shader->output.oT[0]);
460 TRACE_VECTOR(vertex_shader->output.oT[1]);
462 x = vertex_shader->output.oPos.x;
463 y = vertex_shader->output.oPos.y;
464 z = vertex_shader->output.oPos.z;
466 if (1.0f != vertex_shader->output.oPos.w || isRHW) {
467 rhw = vertex_shader->output.oPos.w;
469 /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
470 glColor4fv((float*) &vertex_shader->output.oD[0]);
472 /* Requires secondary color extensions to compile... */
473 if (checkGLSupport(EXT_SECONDARY_COLOR)) {
474 /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/
475 GLExtCall(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]);
476 /*checkGLcall("glSecondaryColor3fvEXT");*/
479 /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
480 for (textureNo = 0; textureNo < 4; ++textureNo) {
483 if (!(This->isMultiTexture) && textureNo > 0) {
484 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
487 /* Query tex coords */
488 if (This->StateBlock.textures[textureNo] != NULL) {
489 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
490 case D3DRTYPE_TEXTURE:
491 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
492 s = vertex_shader->output.oT[textureNo].x;
493 t = vertex_shader->output.oT[textureNo].y;
494 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t));
495 if (This->isMultiTexture) {
496 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
497 /*checkGLcall("glMultiTexCoord2fARB");*/
500 /*checkGLcall("gTexCoord2f");*/
504 case D3DRTYPE_VOLUMETEXTURE:
505 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
506 s = vertex_shader->output.oT[textureNo].x;
507 t = vertex_shader->output.oT[textureNo].y;
508 r = vertex_shader->output.oT[textureNo].z;
509 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r));
510 if (This->isMultiTexture) {
511 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
512 /*checkGLcall("glMultiTexCoord2fARB");*/
514 glTexCoord3f(s, t, r);
515 /*checkGLcall("gTexCoord3f");*/
520 /* Avoid compiler warnings, need these vars later for other textures */
522 FIXME("Unhandled texture type\n");
527 if (1.0f == rhw || rhw < 0.01f) {
528 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
530 /*checkGLcall("glVertex3f");*/
532 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
533 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
534 /*checkGLcall("glVertex4f");*/
538 * FALSE == useVertexShaderFunction
542 /* Handle these vertexes */
544 glColor4ub((diffuseColor >> 16) & 0xFF,
545 (diffuseColor >> 8) & 0xFF,
546 (diffuseColor >> 0) & 0xFF,
547 (diffuseColor >> 24) & 0xFF);
548 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
549 ((diffuseColor >> 16) & 0xFF) / 255.0f,
550 ((diffuseColor >> 8) & 0xFF) / 255.0f,
551 ((diffuseColor >> 0) & 0xFF) / 255.0f,
552 ((diffuseColor >> 24) & 0xFF) / 255.0f));
556 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
557 glNormal3f(nx, ny, nz);
560 if (1.0f == rhw || rhw < 0.01f) {
561 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
564 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
565 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
571 curVtx = curVtx + skip;
576 checkGLcall("glEnd and previous calls");
579 TRACE("Using fast vertex array code\n");
581 /* Faster version, harder to debug */
582 /* Shuffle to the beginning of the vertexes to render and index from there */
583 curVtx = vertexBufData + (StartVertexIndex * skip);
586 /* Set up the vertex pointers */
588 glVertexPointer(4, GL_FLOAT, skip, curPos);
589 checkGLcall("glVertexPointer(4, ...)");
590 curPos += 4 * sizeof(float);
592 glVertexPointer(3, GL_FLOAT, skip, curPos);
593 checkGLcall("glVertexPointer(3, ...)");
594 curPos += 3 * sizeof(float);
596 glEnableClientState(GL_VERTEX_ARRAY);
597 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
600 /* no such functionality in the fixed function GL pipeline */
601 /* FIXME: Wont get here as will drop to slow method */
602 /* FIXME("Cannot handle blending data here in openGl\n");*/
603 if (checkGLSupport(ARB_VERTEX_BLEND)) {
605 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
608 GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
609 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
610 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
611 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
613 curPos += numBlends * sizeof(float);
615 FIXME("unsupported blending in openGl\n");
618 if (checkGLSupport(ARB_VERTEX_BLEND)) {
620 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
623 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
624 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
631 glNormalPointer(GL_FLOAT, skip, curPos);
632 checkGLcall("glNormalPointer");
633 glEnableClientState(GL_NORMAL_ARRAY);
634 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
635 curPos += 3 * sizeof(float);
637 glDisableClientState(GL_NORMAL_ARRAY);
638 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
640 checkGLcall("glNormal3f(0, 0, 1)");
644 /* no such functionality in the fixed function GL pipeline */
645 /* FIXME: Wont get here as will drop to slow method */
646 FIXME("Cannot change ptSize here in openGl\n");
647 curPos = curPos + sizeof(float);
651 glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
652 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
653 glEnableClientState(GL_COLOR_ARRAY);
654 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
655 curPos += sizeof(DWORD);
658 glDisableClientState(GL_COLOR_ARRAY);
659 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
660 glColor4f(1, 1, 1, 1);
661 checkGLcall("glColor4f(1, 1, 1, 1)");
664 /* Requires secondary color extensions to compile... */
667 /* FIXME: check for GL_EXT_secondary_color */
668 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos);
669 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
670 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
671 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
672 curPos += sizeof(DWORD);
674 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
675 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
676 glSecondaryColor3fEXT(0, 0, 0);
677 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
681 /* ToDo: Texture coords */
682 for (textureNo = 0;textureNo<numTextures; textureNo++) {
684 /* Query tex coords */
685 glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
686 if (This->StateBlock.textures[textureNo] != NULL) {
687 enableTexture = TRUE;
688 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
689 case D3DRTYPE_TEXTURE:
690 glTexCoordPointer(2, GL_FLOAT, skip, curPos);
691 checkGLcall("glTexCoordPointer(2, ...)");
692 curPos += 2*sizeof(float);
693 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
694 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
697 case D3DRTYPE_VOLUMETEXTURE:
698 glTexCoordPointer(3, GL_FLOAT, skip, curPos);
699 checkGLcall("glTexCoordPointer(3, ...)");
700 curPos += 3*sizeof(float);
701 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
702 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
706 FIXME("Unhandled texture type\n");
707 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
708 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
713 /* Note I have seen a program actually do this, so just hide it and continue */
714 TRACE("Very odd - texture requested in FVF but not bound!\n");
715 glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1);
716 checkGLcall("glMultiTexCoord4f(... , 0, 0, 0, 1)");
717 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
718 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
724 /* Finally do the drawing */
727 TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
729 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
730 glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT, idxData+(2 * StartIdx));
732 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
733 GL_UNSIGNED_SHORT, idxData+(2 * StartIdx));
736 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
737 glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT, idxData+(4 * StartIdx));
739 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
740 GL_UNSIGNED_INT, idxData+(2 * StartIdx));
743 checkGLcall("glDrawRangeElements");
747 /* Note first is now zero as we shuffled along earlier */
748 TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
749 glDrawArrays(primType, 0, NumVertexes);
750 checkGLcall("glDrawArrays");
755 /* If no normals, restore previous lighting state */
757 if (isLightingOn) glEnable(GL_LIGHTING);
758 else glDisable(GL_LIGHTING);
759 TRACE("Restored lighting to original state\n");
769 Simple utility routines used for dx -> gl mapping of byte formats
771 SHORT bytesPerPixel(D3DFORMAT fmt) {
775 case D3DFMT_A4R4G4B4: retVal = 2; break;
776 case D3DFMT_A8R8G8B8: retVal = 4; break;
777 case D3DFMT_X8R8G8B8: retVal = 4; break;
778 case D3DFMT_R8G8B8: retVal = 3; break;
779 case D3DFMT_R5G6B5: retVal = 2; break;
780 case D3DFMT_A1R5G5B5: retVal = 2; break;
782 /* Guess at the highest value of the above */
783 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt);
787 FIXME("Unhandled fmt %d\n", fmt);
790 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
794 GLint fmt2glintFmt(D3DFORMAT fmt) {
798 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
799 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
800 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
801 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
802 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
803 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
805 FIXME("Unhandled fmt %d\n", fmt);
808 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
811 GLenum fmt2glFmt(D3DFORMAT fmt) {
815 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
816 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
817 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
818 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
819 case D3DFMT_R5G6B5: retVal = GL_BGR; break;
820 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
822 FIXME("Unhandled fmt %d\n", fmt);
825 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
828 DWORD fmt2glType(D3DFORMAT fmt) {
832 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
833 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
834 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
835 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
836 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
837 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
839 FIXME("Unhandled fmt %d\n", fmt);
842 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
846 int SOURCEx_RGB_EXT(DWORD arg) {
848 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
849 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
850 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
851 case D3DTSS_ALPHAARG0:
852 case D3DTSS_ALPHAARG1:
853 case D3DTSS_ALPHAARG2:
855 FIXME("Invalid arg %ld\n", arg);
856 return GL_SOURCE0_RGB_EXT;
859 int OPERANDx_RGB_EXT(DWORD arg) {
861 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
862 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
863 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
864 case D3DTSS_ALPHAARG0:
865 case D3DTSS_ALPHAARG1:
866 case D3DTSS_ALPHAARG2:
868 FIXME("Invalid arg %ld\n", arg);
869 return GL_OPERAND0_RGB_EXT;
872 int SOURCEx_ALPHA_EXT(DWORD arg) {
874 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
875 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
876 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
877 case D3DTSS_COLORARG0:
878 case D3DTSS_COLORARG1:
879 case D3DTSS_COLORARG2:
881 FIXME("Invalid arg %ld\n", arg);
882 return GL_SOURCE0_ALPHA_EXT;
885 int OPERANDx_ALPHA_EXT(DWORD arg) {
887 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
888 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
889 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
890 case D3DTSS_COLORARG0:
891 case D3DTSS_COLORARG1:
892 case D3DTSS_COLORARG2:
894 FIXME("Invalid arg %ld\n", arg);
895 return GL_OPERAND0_ALPHA_EXT;
898 GLenum StencilOp(DWORD op) {
900 case D3DSTENCILOP_KEEP : return GL_KEEP;
901 case D3DSTENCILOP_ZERO : return GL_ZERO;
902 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
903 case D3DSTENCILOP_INCRSAT : return GL_INCR;
904 case D3DSTENCILOP_DECRSAT : return GL_DECR;
905 case D3DSTENCILOP_INVERT : return GL_INVERT;
906 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op %ld\n", op);
907 return GL_INCR; /* Fixme - needs to support wrap */
908 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op %ld\n", op);
909 return GL_DECR; /* Fixme - needs to support wrap */
911 FIXME("Invalid stencil op %ld\n", op);
916 /* Apply the current values to the specified texture stage */
917 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
918 ICOM_THIS(IDirect3DDevice8Impl,iface);
922 /* Make appropriate texture active */
923 if (This->isMultiTexture) {
924 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
925 checkGLcall("glActiveTextureARB");
926 } else if (Stage > 0) {
927 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
930 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
931 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
932 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock.texture_state[Stage][i]);
935 /* Note the D3DRS value applies to all textures, but GL has one
936 per texture, so apply it now ready to be used! */
937 col[0] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
938 col[1] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
939 col[2] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
940 col[3] = ((This->StateBlock.renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
941 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
942 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
944 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
947 /* IDirect3D IUnknown parts follow: */
948 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
950 ICOM_THIS(IDirect3DDevice8Impl,iface);
952 if (IsEqualGUID(riid, &IID_IUnknown)
953 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
954 IDirect3DDevice8Impl_AddRef(iface);
959 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
960 return E_NOINTERFACE;
963 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
964 ICOM_THIS(IDirect3DDevice8Impl,iface);
965 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
966 return ++(This->ref);
969 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
970 ICOM_THIS(IDirect3DDevice8Impl,iface);
971 ULONG ref = --This->ref;
972 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
974 HeapFree(GetProcessHeap(), 0, This);
979 /* IDirect3DDevice Interface follow: */
980 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
981 ICOM_THIS(IDirect3DDevice8Impl,iface);
982 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
986 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
987 ICOM_THIS(IDirect3DDevice8Impl,iface);
988 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
990 * pretend we have 32MB of any type of memory queried.
992 return (1024*1024*32);
995 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
996 ICOM_THIS(IDirect3DDevice8Impl,iface);
997 FIXME("(%p) : stub\n", This); return D3D_OK;
999 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
1000 ICOM_THIS(IDirect3DDevice8Impl,iface);
1001 TRACE("(%p) : returning %p\n", This, This->direct3d8);
1004 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
1006 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
1009 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
1010 ICOM_THIS(IDirect3DDevice8Impl,iface);
1011 FIXME("(%p) : stub, calling idirect3d for now\n", This);
1012 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
1015 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
1020 ICOM_THIS(IDirect3DDevice8Impl,iface);
1021 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
1022 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
1023 pMode->RefreshRate = 85; /*FIXME: How to identify? */
1025 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1026 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1030 case 8: pMode->Format = D3DFMT_R8G8B8; break;
1031 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1032 case 24: pMode->Format = D3DFMT_R8G8B8; break;
1033 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1035 FIXME("Unrecognized display mode format\n");
1036 pMode->Format = D3DFMT_UNKNOWN;
1039 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
1042 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1043 ICOM_THIS(IDirect3DDevice8Impl,iface);
1044 TRACE("(%p) copying to %p\n", This, pParameters);
1045 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1048 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1049 ICOM_THIS(IDirect3DDevice8Impl,iface);
1050 FIXME("(%p) : stub\n", This); return D3D_OK;
1052 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1053 ICOM_THIS(IDirect3DDevice8Impl,iface);
1054 FIXME("(%p) : stub\n", This); return;
1056 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1057 ICOM_THIS(IDirect3DDevice8Impl,iface);
1058 FIXME("(%p) : stub\n", This); return D3D_OK;
1060 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1061 ICOM_THIS(IDirect3DDevice8Impl,iface);
1062 FIXME("(%p) : stub\n", This); return D3D_OK;
1064 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1065 ICOM_THIS(IDirect3DDevice8Impl,iface);
1066 FIXME("(%p) : stub\n", This); return D3D_OK;
1068 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1069 ICOM_THIS(IDirect3DDevice8Impl,iface);
1070 TRACE("(%p) : complete stub!\n", This);
1074 glXSwapBuffers(This->display, This->win);
1075 checkGLcall("glXSwapBuffers");
1081 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
1082 ICOM_THIS(IDirect3DDevice8Impl,iface);
1083 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1084 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1086 /* Note inc ref on returned surface */
1087 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1091 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1092 ICOM_THIS(IDirect3DDevice8Impl,iface);
1093 FIXME("(%p) : stub\n", This); return D3D_OK;
1095 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1096 ICOM_THIS(IDirect3DDevice8Impl,iface);
1097 FIXME("(%p) : stub\n", This); return;
1099 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1100 ICOM_THIS(IDirect3DDevice8Impl,iface);
1101 FIXME("(%p) : stub\n", This); return;
1103 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1104 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1105 IDirect3DTexture8Impl *object;
1110 ICOM_THIS(IDirect3DDevice8Impl,iface);
1112 /* Allocate the storage for the device */
1113 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
1114 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1115 object->lpVtbl = &Direct3DTexture8_Vtbl;
1116 object->Device = This; /* FIXME: AddRef(This) */
1117 object->ResourceType = D3DRTYPE_TEXTURE;
1119 object->width = Width;
1120 object->height = Height;
1121 object->levels = Levels;
1122 object->usage = Usage;
1123 object->format = Format;
1124 object->device = This;
1126 /* Calculate levels for mip mapping */
1131 while (tmpW > 1 && tmpH > 1) {
1132 tmpW = max(1,tmpW / 2);
1133 tmpH = max(1, tmpH / 2);
1136 TRACE("Calculated levels = %d\n", object->levels);
1139 /* Generate all the surfaces */
1142 for (i=0; i<object->levels; i++)
1144 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1145 object->surfaces[i]->Container = (IUnknown*) object; /* FIXME: AddRef(object) */
1146 object->surfaces[i]->myDesc.Usage = Usage;
1147 object->surfaces[i]->myDesc.Pool = Pool ;
1149 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1150 tmpW = max(1, tmpW / 2);
1151 tmpH = max(1, tmpH / 2);
1154 *ppTexture = (LPDIRECT3DTEXTURE8)object;
1157 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1159 IDirect3DVolumeTexture8Impl *object;
1165 ICOM_THIS(IDirect3DDevice8Impl,iface);
1167 /* Allocate the storage for it */
1168 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);
1169 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1170 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1171 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1175 object->width = Width;
1176 object->height = Height;
1177 object->depth = Depth;
1178 object->levels = Levels;
1179 object->usage = Usage;
1180 object->format = Format;
1181 object->device = This;
1183 /* Calculate levels for mip mapping */
1189 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1190 tmpW = max(1,tmpW / 2);
1191 tmpH = max(1, tmpH / 2);
1192 tmpD = max(1, tmpD / 2);
1195 TRACE("Calculated levels = %d\n", object->levels);
1198 /* Generate all the surfaces */
1203 for (i=0; i<object->levels; i++)
1205 IDirect3DVolume8Impl *volume;
1207 /* Create the volume - No entry point for this seperately?? */
1208 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1209 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1211 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1212 volume->Device = This; /* FIXME: AddRef(This) */
1213 volume->ResourceType = D3DRTYPE_VOLUME;
1214 volume->Container = object;
1217 volume->myDesc.Width = Width;
1218 volume->myDesc.Height= Height;
1219 volume->myDesc.Depth = Depth;
1220 volume->myDesc.Format= Format;
1221 volume->myDesc.Type = D3DRTYPE_VOLUME;
1222 volume->myDesc.Pool = Pool;
1223 volume->myDesc.Usage = Usage;
1224 volume->bytesPerPixel = bytesPerPixel(Format);
1225 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1226 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1228 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
1229 volume, volume->allocatedMemory, volume->myDesc.Size);
1231 tmpW = max(1,tmpW / 2);
1232 tmpH = max(1, tmpH / 2);
1233 tmpD = max(1, tmpD / 2);
1236 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
1239 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
1241 IDirect3DCubeTexture8Impl *object;
1242 ICOM_THIS(IDirect3DDevice8Impl,iface);
1246 /* Allocate the storage for it */
1247 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
1248 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1249 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1251 object->Device = This; /* FIXME: AddRef(This) */
1252 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1254 object->edgeLength = EdgeLength;
1255 object->levels = Levels;
1256 object->usage = Usage;
1257 object->format = Format;
1258 object->device = This;
1260 /* Calculate levels for mip mapping */
1265 tmpW = max(1,tmpW / 2);
1268 TRACE("Calculated levels = %d\n", object->levels);
1271 /* Generate all the surfaces */
1273 for (i=0; i<object->levels; i++)
1275 /* Create the 6 faces */
1277 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1278 object->surfaces[j][i]->Container = (IUnknown*) object;
1279 object->surfaces[j][i]->myDesc.Usage = Usage;
1280 object->surfaces[j][i]->myDesc.Pool = Pool ;
1282 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1283 tmpW = max(1,tmpW / 2);
1287 TRACE("(%p) : Iface@%p\n", This, object);
1288 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1291 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage,
1292 DWORD FVF,D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1293 IDirect3DVertexBuffer8Impl *object;
1295 ICOM_THIS(IDirect3DDevice8Impl,iface);
1297 /* Allocate the storage for the device */
1298 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1299 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1300 object->Device = This;
1301 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1303 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1304 object->currentDesc.Usage = Usage;
1305 object->currentDesc.Pool = Pool;
1306 object->currentDesc.FVF = FVF;
1307 object->currentDesc.Size = Size;
1309 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1311 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1315 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
1317 IDirect3DIndexBuffer8Impl *object;
1319 ICOM_THIS(IDirect3DDevice8Impl,iface);
1320 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
1322 /* Allocate the storage for the device */
1323 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1324 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1326 object->Device = This;
1327 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1329 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1330 object->currentDesc.Usage = Usage;
1331 object->currentDesc.Pool = Pool;
1332 object->currentDesc.Format = Format;
1333 object->currentDesc.Size = Length;
1335 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1337 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1339 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1343 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
1344 ICOM_THIS(IDirect3DDevice8Impl,iface);
1345 /* up ref count on surface, surface->container = This */
1346 FIXME("(%p) : stub\n", This); return D3D_OK;
1348 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
1349 ICOM_THIS(IDirect3DDevice8Impl,iface);
1350 /* surface->container = This */
1351 FIXME("(%p) : stub\n", This); return D3D_OK;
1353 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
1354 IDirect3DSurface8Impl *object;
1356 ICOM_THIS(IDirect3DDevice8Impl,iface);
1358 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1359 *ppSurface = (LPDIRECT3DSURFACE8) object;
1360 object->lpVtbl = &Direct3DSurface8_Vtbl;
1361 object->Device = This;
1362 object->ResourceType = D3DRTYPE_SURFACE;
1363 object->Container = (IUnknown*) This;
1366 object->myDesc.Width = Width;
1367 object->myDesc.Height= Height;
1368 object->myDesc.Format= Format;
1369 object->myDesc.Type = D3DRTYPE_SURFACE;
1370 /*object->myDesc.Usage */
1371 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
1372 object->bytesPerPixel = bytesPerPixel(Format);
1373 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1374 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1376 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);
1379 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1380 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1382 HRESULT rc = D3D_OK;
1383 IDirect3DBaseTexture8* texture = NULL;
1386 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
1387 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1389 ICOM_THIS(IDirect3DDevice8Impl,iface);
1390 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1391 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1393 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1394 a sample and doesnt seem to break anything as far as I can tell */
1395 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1396 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1397 rc = D3DERR_INVALIDCALL;
1399 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1400 TRACE("Converting dest to same format as source, since dest was unknown\n");
1401 dst->myDesc.Format = src->myDesc.Format;
1403 /* Convert container as well */
1404 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1405 if (texture != NULL) {
1407 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1408 case D3DRTYPE_TEXTURE:
1409 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1411 case D3DRTYPE_VOLUMETEXTURE:
1412 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1414 case D3DRTYPE_CUBETEXTURE:
1415 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1418 FIXME("Unhandled texture type\n");
1421 /** Releasing texture after GetContainer */
1422 IDirect3DBaseTexture8_Release(texture);
1426 /* Quick if complete copy ... */
1427 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1428 src->myDesc.Width == dst->myDesc.Width &&
1429 src->myDesc.Height == dst->myDesc.Height)) {
1430 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1431 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1435 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1436 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1437 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1439 void *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1440 void *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1442 /* Copy rect by rect */
1443 for (i=0; i<cRects; i++) {
1444 CONST RECT *r = &pSourceRectsArray[i];
1445 CONST POINT *p = &pDestPointsArray[i];
1448 int copyperline = (r->right - r->left) * bytesPerPixel;
1451 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top,
1452 r->right, r->bottom, p->x, p->y);
1454 /* Find where to start */
1455 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1456 to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel);
1458 /* Copy line by line */
1459 for (j=0; j<(r->bottom - r->top); j++) {
1460 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1467 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1468 if (texture != NULL) {
1470 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1471 case D3DRTYPE_TEXTURE:
1473 IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)texture;
1474 pTexture->Dirty = TRUE;
1477 case D3DRTYPE_VOLUMETEXTURE:
1479 IDirect3DVolumeTexture8Impl *pTexture = (IDirect3DVolumeTexture8Impl *)texture;
1480 pTexture->Dirty = TRUE;
1483 case D3DRTYPE_CUBETEXTURE:
1485 IDirect3DCubeTexture8Impl *pTexture = (IDirect3DCubeTexture8Impl *)texture;
1486 pTexture->Dirty = TRUE;
1490 FIXME("Unhandled texture type\n");
1493 /** Releasing texture after GetContainer */
1494 IDirect3DBaseTexture8_Release(texture);
1500 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1501 ICOM_THIS(IDirect3DDevice8Impl,iface);
1502 FIXME("(%p) : stub\n", This); return D3D_OK;
1504 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1505 ICOM_THIS(IDirect3DDevice8Impl,iface);
1506 FIXME("(%p) : stub\n", This); return D3D_OK;
1508 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1509 ICOM_THIS(IDirect3DDevice8Impl,iface);
1510 FIXME("(%p) : stub\n", This);
1514 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1515 ICOM_THIS(IDirect3DDevice8Impl,iface);
1516 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1517 FIXME("(%p) : stub\n", This);
1520 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1521 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1526 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1528 ICOM_THIS(IDirect3DDevice8Impl,iface);
1530 /* Note inc ref on returned surface *
1531 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1533 FIXME("(%p) : stub\n", This);
1537 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1538 ICOM_THIS(IDirect3DDevice8Impl,iface);
1539 TRACE("(%p) : stub\n", This);
1542 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1543 ICOM_THIS(IDirect3DDevice8Impl,iface);
1544 TRACE("(%p)\n", This);
1549 checkGLcall("glFlush");
1551 /* Useful for debugging sometimes!
1552 printf("Hit Enter ...\n");
1558 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1559 ICOM_THIS(IDirect3DDevice8Impl,iface);
1561 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1562 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1563 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1564 GLbitfield glMask = 0;
1566 CONST D3DRECT *curRect;
1568 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1569 Count, pRects, Flags, Z, Stencil);
1572 if (Count > 0 && pRects) {
1573 glEnable(GL_SCISSOR_TEST);
1574 checkGLcall("glEnable GL_SCISSOR_TEST");
1580 for (i=0;i<Count || i==0; i++) {
1583 /* Note gl uses lower left, width/height */
1584 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1585 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1586 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1587 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1588 checkGLcall("glScissor");
1591 /* Clear the whole screen */
1592 if (Flags & D3DCLEAR_STENCIL) {
1593 glClearStencil(Stencil);
1594 checkGLcall("glClearStencil");
1595 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1598 if (Flags & D3DCLEAR_ZBUFFER) {
1600 checkGLcall("glClearDepth");
1601 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1604 if (Flags & D3DCLEAR_TARGET) {
1605 TRACE("Clearing screen with glClear to color %lx\n", Color);
1606 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1607 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1608 checkGLcall("glClearColor");
1609 glMask = glMask | GL_COLOR_BUFFER_BIT;
1613 checkGLcall("glClear");
1615 if (curRect) curRect = curRect + sizeof(D3DRECT);
1618 if (Count > 0 && pRects) {
1619 glDisable(GL_SCISSOR_TEST);
1620 checkGLcall("glDisable");
1626 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1627 ICOM_THIS(IDirect3DDevice8Impl,iface);
1632 /* Most of this routine, comments included copied from ddraw tree initially: */
1633 TRACE("(%p) : State=%d\n", This, d3dts);
1635 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1636 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1637 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1639 /* Handle recording of state blocks */
1640 if (This->isRecordingState) {
1641 TRACE("Recording... not performing anything\n");
1646 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1648 where ViewMat = Camera space, WorldMat = world space.
1650 In OpenGL, camera and world space is combined into GL_MODELVIEW
1651 matrix. The Projection matrix stay projection matrix. */
1653 /* After reading through both OpenGL and Direct3D documentations, I
1654 thought that D3D matrices were written in 'line major mode' transposed
1655 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1656 works fine to transfer one matrix format to the other (it did not work
1657 when transposing)....
1660 1) are the documentations wrong
1661 2) does the matrix work even if they are not read correctly
1662 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1663 loading using glLoadMatrix ?
1665 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1666 to the other so that if I ever find out that I need to transpose them, I
1667 will able to do it quickly, only by changing the macro conv_mat. */
1671 case D3DTS_WORLDMATRIX(0):
1672 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)]);
1676 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_VIEW]);
1679 case D3DTS_PROJECTION:
1680 conv_mat(lpmatrix, &This->StateBlock.transforms[D3DTS_PROJECTION]);
1683 case D3DTS_TEXTURE0:
1684 case D3DTS_TEXTURE1:
1685 case D3DTS_TEXTURE2:
1686 case D3DTS_TEXTURE3:
1687 case D3DTS_TEXTURE4:
1688 case D3DTS_TEXTURE5:
1689 case D3DTS_TEXTURE6:
1690 case D3DTS_TEXTURE7:
1691 conv_mat(lpmatrix, &This->StateBlock.transforms[d3dts]);
1692 FIXME("Unhandled transform state for TEXTURE%d!!!\n", d3dts - D3DTS_TEXTURE0);
1693 FIXME("must use glMatrixMode(GL_TEXTURE) before texturing\n");
1697 FIXME("Unhandled transform state!!\n");
1702 * Indexed Vertex Blending Matrices 256 -> 511
1705 conv_mat(lpmatrix, &This->StateBlock.transforms[d3dts]);
1706 if (checkGLSupport(ARB_VERTEX_BLEND)) {
1708 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
1714 * Move the GL operation to outside of switch to make it work
1715 * regardless of transform set order. Optimize later.
1718 glMatrixMode(GL_PROJECTION);
1719 checkGLcall("glMatrixMode");
1720 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
1721 checkGLcall("glLoadMatrixf");
1723 glMatrixMode(GL_MODELVIEW);
1724 checkGLcall("glMatrixMode");
1725 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1726 checkGLcall("glLoadMatrixf");
1728 /* If we are changing the View matrix, reset the light information to the new view */
1729 if (d3dts == D3DTS_VIEW) {
1730 for (k = 0; k < MAX_ACTIVE_LIGHTS; k++) {
1731 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1732 checkGLcall("glLightfv posn");
1733 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1734 checkGLcall("glLightfv dirn");
1739 * Vertex Blending as described
1740 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/enums/d3dvertexblendflags.asp
1742 switch (This->UpdateStateBlock->vertex_blend) {
1743 case D3DVBF_DISABLE:
1745 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1746 checkGLcall("glMultMatrixf");
1749 case D3DVBF_1WEIGHTS:
1750 case D3DVBF_2WEIGHTS:
1751 case D3DVBF_3WEIGHTS:
1753 FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n");
1755 * doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*)
1756 * so waiting for the values before matrix work
1757 for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
1758 glMultMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
1759 checkGLcall("glMultMatrixf");
1764 case D3DVBF_TWEENING:
1766 FIXME("valid/correct D3DVBF_TWEENING\n");
1767 f = This->UpdateStateBlock->tween_factor;
1768 m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f;
1769 m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f;
1770 m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f;
1771 m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
1772 glMultMatrixf((float *) &m.u.m[0][0]);
1773 checkGLcall("glMultMatrixf");
1776 case D3DVBF_0WEIGHTS:
1778 FIXME("valid/correct D3DVBF_0WEIGHTS\n");
1779 /* single matrix of weight 1.0f */
1780 m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f;
1781 m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f;
1782 m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f;
1783 m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
1784 glMultMatrixf((float *) &m.u.m[0][0]);
1785 checkGLcall("glMultMatrixf");
1789 break; /* stupid compilator */
1797 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1798 ICOM_THIS(IDirect3DDevice8Impl,iface);
1799 TRACE("(%p) : for State %d\n", This, State);
1800 memcpy(pMatrix, &This->StateBlock.transforms[State], sizeof(D3DMATRIX));
1804 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1805 ICOM_THIS(IDirect3DDevice8Impl,iface);
1806 FIXME("(%p) : stub\n", This); return D3D_OK;
1808 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1809 ICOM_THIS(IDirect3DDevice8Impl,iface);
1811 TRACE("(%p)\n", This);
1812 This->UpdateStateBlock->Changed.viewport = TRUE;
1813 This->UpdateStateBlock->Set.viewport = TRUE;
1814 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1816 /* Handle recording of state blocks */
1817 if (This->isRecordingState) {
1818 TRACE("Recording... not performing anything\n");
1822 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1823 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1825 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1826 checkGLcall("glDepthRange");
1827 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1828 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1829 checkGLcall("glViewport");
1835 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1836 ICOM_THIS(IDirect3DDevice8Impl,iface);
1837 TRACE("(%p)\n", This);
1838 memcpy(pViewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
1842 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1843 ICOM_THIS(IDirect3DDevice8Impl,iface);
1845 This->UpdateStateBlock->Changed.material = TRUE;
1846 This->UpdateStateBlock->Set.material = TRUE;
1847 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1849 /* Handle recording of state blocks */
1850 if (This->isRecordingState) {
1851 TRACE("Recording... not performing anything\n");
1856 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1857 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1858 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1859 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1860 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1862 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1863 checkGLcall("glMaterialfv");
1864 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1865 checkGLcall("glMaterialfv");
1867 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1868 checkGLcall("glMaterialfv");
1869 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1870 checkGLcall("glMaterialfv");
1871 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1872 checkGLcall("glMaterialf");
1877 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1878 ICOM_THIS(IDirect3DDevice8Impl,iface);
1879 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1880 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1881 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1882 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1883 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1884 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1888 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1889 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1893 ICOM_THIS(IDirect3DDevice8Impl,iface);
1894 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1896 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,
1897 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1898 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1899 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1900 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1901 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1902 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1904 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1905 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1906 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1908 /* Handle recording of state blocks */
1909 if (This->isRecordingState) {
1910 TRACE("Recording... not performing anything\n");
1915 colRGBA[0] = pLight->Diffuse.r;
1916 colRGBA[1] = pLight->Diffuse.g;
1917 colRGBA[2] = pLight->Diffuse.b;
1918 colRGBA[3] = pLight->Diffuse.a;
1919 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1920 checkGLcall("glLightfv");
1923 colRGBA[0] = pLight->Specular.r;
1924 colRGBA[1] = pLight->Specular.g;
1925 colRGBA[2] = pLight->Specular.b;
1926 colRGBA[3] = pLight->Specular.a;
1927 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1928 checkGLcall("glLightfv");
1931 colRGBA[0] = pLight->Ambient.r;
1932 colRGBA[1] = pLight->Ambient.g;
1933 colRGBA[2] = pLight->Ambient.b;
1934 colRGBA[3] = pLight->Ambient.a;
1935 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1936 checkGLcall("glLightfv");
1938 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1939 glMatrixMode(GL_MODELVIEW);
1941 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_VIEW].u.m[0][0]);
1943 /* Attenuation - Are these right? guessing... */
1944 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
1945 checkGLcall("glLightf");
1946 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
1947 checkGLcall("glLightf");
1949 quad_att = 1.4/(pLight->Range*pLight->Range);
1950 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1951 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1952 checkGLcall("glLightf");
1954 switch (pLight->Type) {
1955 case D3DLIGHT_POINT:
1957 This->lightPosn[Index][0] = pLight->Position.x;
1958 This->lightPosn[Index][1] = pLight->Position.y;
1959 This->lightPosn[Index][2] = pLight->Position.z;
1960 This->lightPosn[Index][3] = 1.0;
1961 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1962 checkGLcall("glLightfv");
1964 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1965 checkGLcall("glLightf");
1972 This->lightPosn[Index][0] = pLight->Position.x;
1973 This->lightPosn[Index][1] = pLight->Position.y;
1974 This->lightPosn[Index][2] = pLight->Position.z;
1975 This->lightPosn[Index][3] = 1.0;
1976 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1977 checkGLcall("glLightfv");
1980 This->lightDirn[Index][0] = pLight->Direction.x;
1981 This->lightDirn[Index][1] = pLight->Direction.y;
1982 This->lightDirn[Index][2] = pLight->Direction.z;
1983 This->lightDirn[Index][3] = 1.0;
1984 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1985 checkGLcall("glLightfv");
1988 * opengl-ish and d3d-ish spot lights use too different models for the
1989 * light "intensity" as a function of the angle towards the main light direction,
1990 * so we only can approximate very roughly.
1991 * however spot lights are rather rarely used in games (if ever used at all).
1992 * furthermore if still used, probably nobody pays attention to such details.
1994 if (pLight->Falloff == 0) {
1997 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1999 if (rho < 0.0001) rho = 0.0001f;
2000 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
2001 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
2005 case D3DLIGHT_DIRECTIONAL:
2007 This->lightPosn[Index][0] = -pLight->Direction.x;
2008 This->lightPosn[Index][1] = -pLight->Direction.y;
2009 This->lightPosn[Index][2] = -pLight->Direction.z;
2010 This->lightPosn[Index][3] = 0.0;
2011 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
2012 checkGLcall("glLightfv");
2014 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
2015 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
2020 FIXME("Unrecognized light type %d\n", pLight->Type);
2023 /* Restore the modelview matrix */
2028 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
2029 ICOM_THIS(IDirect3DDevice8Impl,iface);
2030 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2031 memcpy(pLight, &This->StateBlock.lights[Index], sizeof(D3DLIGHT8));
2034 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
2035 ICOM_THIS(IDirect3DDevice8Impl,iface);
2036 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
2038 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
2039 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
2040 This->UpdateStateBlock->lightEnable[Index] = Enable;
2042 /* Handle recording of state blocks */
2043 if (This->isRecordingState) {
2044 TRACE("Recording... not performing anything\n");
2049 glEnable(GL_LIGHT0+Index);
2050 checkGLcall("glEnable GL_LIGHT0+Index");
2052 glDisable(GL_LIGHT0+Index);
2053 checkGLcall("glDisable GL_LIGHT0+Index");
2057 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
2058 ICOM_THIS(IDirect3DDevice8Impl,iface);
2059 TRACE("(%p) : for idx(%ld)\n", This, Index);
2060 *pEnable = This->StateBlock.lightEnable[Index];
2063 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
2064 ICOM_THIS(IDirect3DDevice8Impl,iface);
2065 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
2067 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
2068 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
2069 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
2070 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
2071 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
2072 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
2074 /* Handle recording of state blocks */
2075 if (This->isRecordingState) {
2076 TRACE("Recording... not performing anything\n");
2082 /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
2083 glMatrixMode(GL_MODELVIEW);
2085 glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_WORLD].u.m[0][0]);
2087 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
2088 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
2089 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
2092 checkGLcall("glClipPlane");
2096 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
2097 ICOM_THIS(IDirect3DDevice8Impl,iface);
2098 TRACE("(%p) : for idx %ld\n", This, Index);
2099 pPlane[0] = This->StateBlock.clipplane[Index][0];
2100 pPlane[1] = This->StateBlock.clipplane[Index][0];
2101 pPlane[2] = This->StateBlock.clipplane[Index][0];
2102 pPlane[3] = This->StateBlock.clipplane[Index][0];
2105 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
2106 ICOM_THIS(IDirect3DDevice8Impl,iface);
2107 DWORD OldValue = This->StateBlock.renderstate[State];
2109 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
2110 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2111 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2112 This->UpdateStateBlock->renderstate[State] = Value;
2114 /* Handle recording of state blocks */
2115 if (This->isRecordingState) {
2116 TRACE("Recording... not performing anything\n");
2121 case D3DRS_FILLMODE :
2122 switch ((D3DFILLMODE) Value) {
2123 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2124 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2125 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2127 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2129 checkGLcall("glPolygonMode (fillmode)");
2132 case D3DRS_LIGHTING :
2134 glEnable(GL_LIGHTING);
2135 checkGLcall("glEnable GL_LIGHTING");
2137 glDisable(GL_LIGHTING);
2138 checkGLcall("glDisable GL_LIGHTING");
2142 case D3DRS_ZENABLE :
2143 switch ((D3DZBUFFERTYPE) Value) {
2145 glDisable(GL_DEPTH_TEST);
2146 checkGLcall("glDisable GL_DEPTH_TEST");
2149 glEnable(GL_DEPTH_TEST);
2150 checkGLcall("glEnable GL_DEPTH_TEST");
2155 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2159 case D3DRS_CULLMODE :
2161 /* If we are culling "back faces with clockwise vertices" then
2162 set front faces to be counter clockwise and enable culling
2164 switch ((D3DCULL) Value) {
2166 glDisable(GL_CULL_FACE);
2167 checkGLcall("glDisable GL_CULL_FACE");
2170 glEnable(GL_CULL_FACE);
2171 checkGLcall("glEnable GL_CULL_FACE");
2172 glFrontFace(GL_CCW);
2173 checkGLcall("glFrontFace GL_CCW");
2174 glCullFace(GL_BACK);
2177 glEnable(GL_CULL_FACE);
2178 checkGLcall("glEnable GL_CULL_FACE");
2180 checkGLcall("glFrontFace GL_CW");
2181 glCullFace(GL_BACK);
2184 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2188 case D3DRS_SHADEMODE :
2189 switch ((D3DSHADEMODE) Value) {
2191 glShadeModel(GL_FLAT);
2192 checkGLcall("glShadeModel");
2194 case D3DSHADE_GOURAUD:
2195 glShadeModel(GL_SMOOTH);
2196 checkGLcall("glShadeModel");
2198 case D3DSHADE_PHONG:
2199 FIXME("D3DSHADE_PHONG isnt supported?\n");
2200 return D3DERR_INVALIDCALL;
2202 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
2206 case D3DRS_DITHERENABLE :
2208 glEnable(GL_DITHER);
2209 checkGLcall("glEnable GL_DITHER");
2211 glDisable(GL_DITHER);
2212 checkGLcall("glDisable GL_DITHER");
2216 case D3DRS_ZWRITEENABLE :
2219 checkGLcall("glDepthMask");
2222 checkGLcall("glDepthMask");
2228 int glParm = GL_LESS;
2230 switch ((D3DCMPFUNC) Value) {
2231 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2232 case D3DCMP_LESS: glParm=GL_LESS; break;
2233 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2234 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2235 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2236 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2237 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2238 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2240 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2242 glDepthFunc(glParm);
2243 checkGLcall("glDepthFunc");
2247 case D3DRS_AMBIENT :
2251 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2252 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2253 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2254 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2255 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
2256 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2257 checkGLcall("glLightModel for MODEL_AMBIENT");
2262 case D3DRS_ALPHABLENDENABLE :
2265 checkGLcall("glEnable GL_BLEND");
2267 glDisable(GL_BLEND);
2268 checkGLcall("glDisable GL_BLEND");
2272 case D3DRS_SRCBLEND :
2273 case D3DRS_DESTBLEND :
2275 int newVal = GL_ZERO;
2277 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2278 case D3DBLEND_ONE : newVal = GL_ONE; break;
2279 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2280 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2281 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2282 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2283 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2284 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2285 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2286 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2287 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2289 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2290 This->srcBlend = newVal;
2291 This->dstBlend = newVal;
2294 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2295 This->srcBlend = newVal;
2296 This->dstBlend = newVal;
2299 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
2302 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
2303 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
2304 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
2305 glBlendFunc(This->srcBlend, This->dstBlend);
2307 checkGLcall("glBlendFunc");
2311 case D3DRS_ALPHATESTENABLE :
2313 glEnable(GL_ALPHA_TEST);
2314 checkGLcall("glEnable GL_ALPHA_TEST");
2316 glDisable(GL_ALPHA_TEST);
2317 checkGLcall("glDisable GL_ALPHA_TEST");
2321 case D3DRS_ALPHAFUNC :
2323 int glParm = GL_LESS;
2326 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
2327 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
2329 switch ((D3DCMPFUNC) Value) {
2330 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2331 case D3DCMP_LESS: glParm=GL_LESS; break;
2332 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2333 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2334 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2335 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2336 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2337 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2339 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2341 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2342 glAlphaFunc(glParm, ref);
2343 checkGLcall("glAlphaFunc");
2347 case D3DRS_ALPHAREF :
2349 int glParm = GL_LESS;
2352 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
2353 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
2355 ref = ((float) Value) / 255.0;
2356 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2357 glAlphaFunc(glParm, ref);
2358 checkGLcall("glAlphaFunc");
2362 case D3DRS_CLIPPLANEENABLE :
2363 case D3DRS_CLIPPING :
2365 /* Ensure we only do the changed clip planes */
2366 DWORD enable = 0xFFFFFFFF;
2367 DWORD disable = 0x00000000;
2369 /* If enabling / disabling all */
2370 if (State == D3DRS_CLIPPING) {
2372 enable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
2375 disable = This->StateBlock.renderstate[D3DRS_CLIPPLANEENABLE];
2379 enable = Value & ~OldValue;
2380 disable = ~Value & OldValue;
2383 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
2384 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
2385 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
2386 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
2387 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
2388 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
2390 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
2391 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
2392 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
2393 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
2394 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
2395 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
2399 case D3DRS_BLENDOP :
2401 int glParm = GL_FUNC_ADD;
2403 switch ((D3DBLENDOP) Value) {
2404 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
2405 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
2406 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
2407 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
2408 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
2410 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
2412 TRACE("glBlendEquation(%x)\n", glParm);
2413 glBlendEquation(glParm);
2414 checkGLcall("glBlendEquation");
2418 case D3DRS_TEXTUREFACTOR :
2422 /* Note the texture color applies to all textures whereas
2423 GL_TEXTURE_ENV_COLOR applies to active only */
2425 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2426 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2427 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2428 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2430 /* Set the default alpha blend color */
2431 glBlendColor(col[0], col[1], col[2], col[3]);
2432 checkGLcall("glBlendColor");
2434 /* And now the default texture color as well */
2435 for (i = 0; i < This->TextureUnits; i++) {
2437 /* Note the D3DRS value applies to all textures, but GL has one
2438 per texture, so apply it now ready to be used! */
2439 if (This->isMultiTexture) {
2440 glActiveTextureARB(GL_TEXTURE0_ARB + i);
2441 checkGLcall("Activate texture.. to update const color");
2443 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2446 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
2447 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2452 case D3DRS_SPECULARENABLE :
2455 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
2456 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
2458 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
2459 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
2464 case D3DRS_STENCILENABLE :
2466 glEnable(GL_STENCIL_TEST);
2467 checkGLcall("glEnable GL_STENCIL_TEST");
2469 glDisable(GL_STENCIL_TEST);
2470 checkGLcall("glDisable GL_STENCIL_TEST");
2474 case D3DRS_STENCILFUNC :
2476 int glParm = GL_ALWAYS;
2478 GLuint mask = 0xFFFFFFFF;
2480 glGetIntegerv(GL_STENCIL_REF, &ref);
2481 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2482 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2483 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2485 switch ((D3DCMPFUNC) Value) {
2486 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2487 case D3DCMP_LESS: glParm=GL_LESS; break;
2488 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2489 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2490 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2491 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2492 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2493 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2495 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2497 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2498 glStencilFunc(glParm, ref, mask);
2499 checkGLcall("glStencilFunc");
2503 case D3DRS_STENCILREF :
2505 int glParm = GL_ALWAYS;
2507 GLuint mask = 0xFFFFFFFF;
2509 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2510 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2511 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2512 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2515 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2516 glStencilFunc(glParm, ref, mask);
2517 checkGLcall("glStencilFunc");
2521 case D3DRS_STENCILMASK :
2523 int glParm = GL_ALWAYS;
2525 GLuint mask = Value;
2527 glGetIntegerv(GL_STENCIL_REF, &ref);
2528 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2529 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2530 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2532 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2533 glStencilFunc(glParm, ref, mask);
2534 checkGLcall("glStencilFunc");
2538 case D3DRS_STENCILFAIL :
2544 fail = StencilOp(Value);
2545 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2546 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2547 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2548 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2550 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2551 glStencilOp(fail, zfail, zpass);
2552 checkGLcall("glStencilOp(fail, zfail, zpass);");
2555 case D3DRS_STENCILZFAIL :
2561 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2562 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2563 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2564 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2565 zfail = StencilOp(Value);
2567 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2568 glStencilOp(fail, zfail, zpass);
2569 checkGLcall("glStencilOp(fail, zfail, zpass);");
2572 case D3DRS_STENCILPASS :
2578 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2579 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2580 zpass = StencilOp(Value);
2581 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2582 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2584 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2585 glStencilOp(fail, zfail, zpass);
2586 checkGLcall("glStencilOp(fail, zfail, zpass);");
2590 case D3DRS_STENCILWRITEMASK :
2592 glStencilMask(Value);
2593 TRACE("glStencilMask(%lu)\n", Value);
2594 checkGLcall("glStencilMask");
2598 case D3DRS_FOGENABLE :
2600 if (Value && This->StateBlock.renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
2602 checkGLcall("glEnable GL_FOG\n");
2605 checkGLcall("glDisable GL_FOG\n");
2610 case D3DRS_FOGCOLOR :
2613 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2614 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2615 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2616 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2618 /* Set the default alpha blend color */
2619 glFogfv(GL_FOG_COLOR, &col[0]);
2620 checkGLcall("glFog GL_FOG_COLOR");
2624 case D3DRS_FOGSTART :
2626 float *f = (float *)&Value;
2627 glFogfv(GL_FOG_START, f);
2628 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2629 TRACE("Fog Start == %f\n", *f);
2635 float *f = (float *)&Value;
2636 glFogfv(GL_FOG_END, f);
2637 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2638 TRACE("Fog End == %f\n", *f);
2642 case D3DRS_FOGDENSITY :
2644 glFogf(GL_FOG_DENSITY, (float) Value);
2645 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2649 case D3DRS_VERTEXBLEND :
2651 This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
2652 TRACE("Vertex Blending state to %ld\n", Value);
2656 case D3DRS_TWEENFACTOR :
2658 This->UpdateStateBlock->tween_factor = *((float*) &Value);
2659 TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
2663 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2665 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
2670 /* Unhandled yet...! */
2671 case D3DRS_LINEPATTERN :
2672 case D3DRS_LASTPIXEL :
2673 case D3DRS_ZVISIBLE :
2674 case D3DRS_FOGTABLEMODE :
2675 case D3DRS_EDGEANTIALIAS :
2677 case D3DRS_RANGEFOGENABLE :
2686 case D3DRS_FOGVERTEXMODE :
2687 case D3DRS_COLORVERTEX :
2688 case D3DRS_LOCALVIEWER :
2689 case D3DRS_NORMALIZENORMALS :
2690 case D3DRS_DIFFUSEMATERIALSOURCE :
2691 case D3DRS_SPECULARMATERIALSOURCE :
2692 case D3DRS_AMBIENTMATERIALSOURCE :
2693 case D3DRS_EMISSIVEMATERIALSOURCE :
2694 case D3DRS_SOFTWAREVERTEXPROCESSING :
2695 case D3DRS_POINTSIZE :
2696 case D3DRS_POINTSIZE_MIN :
2697 case D3DRS_POINTSPRITEENABLE :
2698 case D3DRS_POINTSCALEENABLE :
2699 case D3DRS_POINTSCALE_A :
2700 case D3DRS_POINTSCALE_B :
2701 case D3DRS_POINTSCALE_C :
2702 case D3DRS_MULTISAMPLEANTIALIAS :
2703 case D3DRS_MULTISAMPLEMASK :
2704 case D3DRS_PATCHEDGESTYLE :
2705 case D3DRS_PATCHSEGMENTS :
2706 case D3DRS_DEBUGMONITORTOKEN :
2707 case D3DRS_POINTSIZE_MAX :
2708 case D3DRS_COLORWRITEENABLE :
2709 case D3DRS_POSITIONORDER :
2710 case D3DRS_NORMALORDER :
2711 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2712 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2715 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2720 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2721 ICOM_THIS(IDirect3DDevice8Impl,iface);
2722 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2723 *pValue = This->StateBlock.renderstate[State];
2726 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2727 ICOM_THIS(IDirect3DDevice8Impl,iface);
2731 TRACE("(%p)\n", This);
2732 if (This->isRecordingState) {
2733 TRACE("(%p) already recording! returning error\n", This);
2734 return D3DERR_INVALIDCALL;
2737 /* Allocate Storage */
2738 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
2739 This->isRecordingState = TRUE;
2740 This->UpdateStateBlock = memory;
2744 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2746 ICOM_THIS(IDirect3DDevice8Impl,iface);
2747 TRACE("(%p)\n", This);
2749 if (!This->isRecordingState) {
2750 TRACE("(%p) not recording! returning error\n", This);
2751 return D3DERR_INVALIDCALL;
2754 This->UpdateStateBlock->blockType = D3DSBT_RECORDED;
2755 *pToken = (DWORD) This->UpdateStateBlock;
2756 This->isRecordingState = FALSE;
2757 This->UpdateStateBlock = &This->StateBlock;
2759 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
2763 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2765 STATEBLOCK *pSB = (STATEBLOCK *)Token;
2768 ICOM_THIS(IDirect3DDevice8Impl,iface);
2769 TRACE("(%p) : Applying state block %lx ------------------v\n", This, Token);
2771 /* FIXME: Only apply applicable states not all states */
2773 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_VERTEXSTATE) {
2775 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2777 if (pSB->Set.lightEnable[i] && pSB->Changed.lightEnable[i])
2778 IDirect3DDevice8Impl_LightEnable(iface, i, pSB->lightEnable[i]);
2779 if (pSB->Set.lights[i] && pSB->Changed.lights[i])
2780 IDirect3DDevice8Impl_SetLight(iface, i, &pSB->lights[i]);
2783 if (pSB->Set.vertexShader && pSB->Changed.vertexShader)
2784 IDirect3DDevice8Impl_SetVertexShader(iface, pSB->VertexShader);
2786 /* TODO: Vertex Shader Constants */
2789 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL || pSB->blockType == D3DSBT_PIXELSTATE) {
2791 if (pSB->Set.pixelShader && pSB->Changed.pixelShader)
2792 IDirect3DDevice8Impl_SetPixelShader(iface, pSB->PixelShader);
2794 /* TODO: Pixel Shader Constants */
2797 /* Others + Render & Texture */
2798 if (pSB->blockType == D3DSBT_RECORDED || pSB->blockType == D3DSBT_ALL) {
2799 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2800 if (pSB->Set.transform[i] && pSB->Changed.transform[i])
2801 IDirect3DDevice8Impl_SetTransform(iface, i, &pSB->transforms[i]);
2804 if (pSB->Set.Indices && pSB->Changed.Indices)
2805 IDirect3DDevice8Impl_SetIndices(iface, pSB->pIndexData, pSB->baseVertexIndex);
2807 if (pSB->Set.material && pSB->Changed.material)
2808 IDirect3DDevice8Impl_SetMaterial(iface, &pSB->material);
2810 if (pSB->Set.viewport && pSB->Changed.viewport)
2811 IDirect3DDevice8Impl_SetViewport(iface, &pSB->viewport);
2813 for (i=0; i<MAX_STREAMS; i++) {
2814 if (pSB->Set.stream_source[i] && pSB->Changed.stream_source[i])
2815 IDirect3DDevice8Impl_SetStreamSource(iface, i, pSB->stream_source[i], pSB->stream_stride[i]);
2818 for (i=0; i<MAX_CLIPPLANES; i++) {
2819 if (pSB->Set.clipplane[i] && pSB->Changed.clipplane[i]) {
2822 clip[0] = pSB->clipplane[i][0];
2823 clip[1] = pSB->clipplane[i][1];
2824 clip[2] = pSB->clipplane[i][2];
2825 clip[3] = pSB->clipplane[i][3];
2826 IDirect3DDevice8Impl_SetClipPlane(iface, i, clip);
2831 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
2833 if (pSB->Set.renderstate[i] && pSB->Changed.renderstate[i])
2834 IDirect3DDevice8Impl_SetRenderState(iface, i, pSB->renderstate[i]);
2839 for (j = 0; j < This->TextureUnits; j++) {
2840 for (i = 0; i < HIGHEST_TEXTURE_STATE; i++) {
2841 if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i]) {
2842 IDirect3DDevice8Impl_SetTextureStageState(iface, j, i, pSB->texture_state[j][i]);
2845 if (pSB->Set.textures[j] && pSB->Changed.textures[j]) {
2846 IDirect3DDevice8Impl_SetTexture(iface, j, pSB->textures[j]);
2851 } else if (pSB->blockType == D3DSBT_PIXELSTATE) {
2853 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
2854 if (pSB->Set.renderstate[SavedPixelStates_R[i]] && pSB->Changed.renderstate[SavedPixelStates_R[i]])
2855 IDirect3DDevice8Impl_SetRenderState(iface, SavedPixelStates_R[i], pSB->renderstate[SavedPixelStates_R[i]]);
2859 for (j=0; j<This->TextureUnits; i++) {
2860 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
2862 if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
2863 pSB->Changed.texture_state[j][SavedPixelStates_T[i]])
2864 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedPixelStates_T[i], pSB->texture_state[j][SavedPixelStates_T[i]]);
2868 } else if (pSB->blockType == D3DSBT_VERTEXSTATE) {
2870 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
2871 if (pSB->Set.renderstate[SavedVertexStates_R[i]] && pSB->Changed.renderstate[SavedVertexStates_R[i]])
2872 IDirect3DDevice8Impl_SetRenderState(iface, SavedVertexStates_R[i], pSB->renderstate[SavedVertexStates_R[i]]);
2876 for (j=0; j<This->TextureUnits; i++) {
2877 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
2879 if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
2880 pSB->Changed.texture_state[j][SavedVertexStates_T[i]])
2881 IDirect3DDevice8Impl_SetTextureStageState(iface, j, SavedVertexStates_T[i], pSB->texture_state[j][SavedVertexStates_T[i]]);
2887 FIXME("Unrecognized state block type %d\n", pSB->blockType);
2889 memcpy(&This->StateBlock.Changed, &pSB->Changed, sizeof(This->StateBlock.Changed));
2890 TRACE("(%p) : Applied state block %lx ------------------^\n", This, Token);
2894 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2896 STATEBLOCK *updateBlock = (STATEBLOCK *)Token;
2898 ICOM_THIS(IDirect3DDevice8Impl,iface);
2900 TRACE("(%p) : Updating state block %lx ------------------v \n", This, Token);
2902 /* If not recorded, then update can just recapture */
2903 if (updateBlock->blockType != D3DSBT_RECORDED) {
2905 STATEBLOCK *tmpBlock;
2906 IDirect3DDevice8Impl_CreateStateBlock(iface, updateBlock->blockType, &tmpToken);
2907 tmpBlock = (STATEBLOCK *)tmpToken;
2908 memcpy(updateBlock, tmpBlock, sizeof(STATEBLOCK));
2909 IDirect3DDevice8Impl_DeleteStateBlock(iface, tmpToken);
2911 /* FIXME: This will record states of new lights! May need to have and save set_lights
2912 across this action */
2917 /* Recorded => Only update 'changed' values */
2918 if (updateBlock->Set.vertexShader && updateBlock->VertexShader != This->StateBlock.VertexShader) {
2919 updateBlock->VertexShader = This->StateBlock.VertexShader;
2920 TRACE("Updating vertex shader to %ld\n", This->StateBlock.VertexShader);
2923 /* TODO: Vertex Shader Constants */
2925 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
2926 if (updateBlock->Set.lightEnable[i] && This->StateBlock.lightEnable[i] != updateBlock->lightEnable[i]) {
2927 TRACE("Updating light enable for light %d to %d\n", i, This->StateBlock.lightEnable[i]);
2928 updateBlock->lightEnable[i] = This->StateBlock.lightEnable[i];
2931 if (updateBlock->Set.lights[i] && memcmp(&This->StateBlock.lights[i],
2932 &updateBlock->lights[i],
2933 sizeof(D3DLIGHT8)) != 0) {
2934 TRACE("Updating lights for light %d\n", i);
2935 memcpy(&updateBlock->lights[i], &This->StateBlock.lights[i], sizeof(D3DLIGHT8));
2939 if (updateBlock->Set.pixelShader && updateBlock->PixelShader != This->StateBlock.PixelShader) {
2940 TRACE("Updating pixel shader to %ld\n", This->StateBlock.PixelShader);
2941 updateBlock->lights[i] = This->StateBlock.lights[i];
2942 IDirect3DDevice8Impl_SetVertexShader(iface, updateBlock->PixelShader);
2945 /* TODO: Pixel Shader Constants */
2947 /* Others + Render & Texture */
2948 for (i=0; i<HIGHEST_TRANSFORMSTATE; i++) {
2949 if (updateBlock->Set.transform[i] && memcmp(&This->StateBlock.transforms[i],
2950 &updateBlock->transforms[i],
2951 sizeof(D3DMATRIX)) != 0) {
2952 TRACE("Updating transform %d\n", i);
2953 memcpy(&updateBlock->transforms[i], &This->StateBlock.transforms[i], sizeof(D3DMATRIX));
2957 if (updateBlock->Set.Indices && ((updateBlock->pIndexData != This->StateBlock.pIndexData)
2958 || (updateBlock->baseVertexIndex != This->StateBlock.baseVertexIndex))) {
2959 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2960 This->StateBlock.pIndexData, This->StateBlock.baseVertexIndex);
2961 updateBlock->pIndexData = This->StateBlock.pIndexData;
2962 updateBlock->baseVertexIndex = This->StateBlock.baseVertexIndex;
2965 if (updateBlock->Set.material && memcmp(&This->StateBlock.material,
2966 &updateBlock->material,
2967 sizeof(D3DMATERIAL8)) != 0) {
2968 TRACE("Updating material\n");
2969 memcpy(&updateBlock->material, &This->StateBlock.material, sizeof(D3DMATERIAL8));
2972 if (updateBlock->Set.viewport && memcmp(&This->StateBlock.viewport,
2973 &updateBlock->viewport,
2974 sizeof(D3DVIEWPORT8)) != 0) {
2975 TRACE("Updating viewport\n");
2976 memcpy(&updateBlock->viewport, &This->StateBlock.viewport, sizeof(D3DVIEWPORT8));
2979 for (i=0; i<MAX_STREAMS; i++) {
2980 if (updateBlock->Set.stream_source[i] &&
2981 ((updateBlock->stream_stride[i] != This->StateBlock.stream_stride[i]) ||
2982 (updateBlock->stream_source[i] != This->StateBlock.stream_source[i]))) {
2983 TRACE("Updating stream source %d to %p, stride to %d\n", i, This->StateBlock.stream_source[i],
2984 This->StateBlock.stream_stride[i]);
2985 updateBlock->stream_stride[i] = This->StateBlock.stream_stride[i];
2986 updateBlock->stream_source[i] = This->StateBlock.stream_source[i];
2990 for (i=0; i<MAX_CLIPPLANES; i++) {
2991 if (updateBlock->Set.clipplane[i] && memcmp(&This->StateBlock.clipplane[i],
2992 &updateBlock->clipplane[i],
2993 sizeof(updateBlock->clipplane)) != 0) {
2995 TRACE("Updating clipplane %d\n", i);
2996 memcpy(&updateBlock->clipplane[i], &This->StateBlock.clipplane[i],
2997 sizeof(updateBlock->clipplane));
3002 for (i=0; i<HIGHEST_RENDER_STATE; i++) {
3004 if (updateBlock->Set.renderstate[i] && (updateBlock->renderstate[i] !=
3005 This->StateBlock.renderstate[i])) {
3006 TRACE("Updating renderstate %d to %ld\n", i, This->StateBlock.renderstate[i]);
3007 updateBlock->renderstate[i] = This->StateBlock.renderstate[i];
3012 for (j=0; j<This->TextureUnits; j++) {
3013 for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
3015 if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
3016 This->StateBlock.texture_state[j][i])) {
3017 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, This->StateBlock.texture_state[j][i],
3018 updateBlock->texture_state[j][i]);
3019 updateBlock->texture_state[j][i] = This->StateBlock.texture_state[j][i];
3022 if (updateBlock->Set.textures[j] && (updateBlock->textures[j] != This->StateBlock.textures[j])) {
3023 TRACE("Updating texture %d to %p (was %p)\n", j, This->StateBlock.textures[j], updateBlock->textures[j]);
3024 updateBlock->textures[j] = This->StateBlock.textures[j];
3031 TRACE("(%p) : Updated state block %lx ------------------^\n", This, Token);
3035 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3036 ICOM_THIS(IDirect3DDevice8Impl,iface);
3037 TRACE("(%p) : freeing StateBlock %lx\n", This, Token);
3038 HeapFree(GetProcessHeap(), 0, (void *)Token);
3042 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
3047 ICOM_THIS(IDirect3DDevice8Impl,iface);
3048 TRACE("(%p) : for type %d\n", This, Type);
3050 /* Allocate Storage */
3051 memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STATEBLOCK));
3053 memcpy(memory, &This->StateBlock, sizeof(STATEBLOCK));
3055 *pToken = 0xFFFFFFFF;
3056 return E_OUTOFMEMORY;
3058 *pToken = (DWORD) memory;
3060 s->blockType = Type;
3062 TRACE("Updating changed flags appropriate for type %d\n", Type);
3064 if (Type == D3DSBT_ALL) {
3065 TRACE("ALL => Pretend everything has changed\n");
3066 memset(&s->Changed, TRUE, sizeof(This->StateBlock.Changed));
3068 } else if (Type == D3DSBT_PIXELSTATE) {
3070 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
3072 /* TODO: Pixel Shader Constants */
3073 s->Changed.pixelShader = TRUE;
3074 for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
3075 s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
3077 for (j=0; j<This->TextureUnits; i++) {
3078 for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
3079 s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
3083 } else if (Type == D3DSBT_VERTEXSTATE) {
3085 memset(&s->Changed, FALSE, sizeof(This->StateBlock.Changed));
3087 /* TODO: Vertex Shader Constants */
3088 s->Changed.vertexShader = TRUE;
3090 for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
3091 s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
3093 for (j=0; j<This->TextureUnits; i++) {
3094 for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
3095 s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
3099 for (i=0; i<MAX_ACTIVE_LIGHTS; i++) {
3100 s->Changed.lightEnable[i] = TRUE;
3101 s->Changed.lights[i] = TRUE;
3105 FIXME("Unrecognized state block type %d\n", Type);
3107 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This, *pToken);
3111 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
3112 ICOM_THIS(IDirect3DDevice8Impl,iface);
3113 FIXME("(%p) : stub\n", This); return D3D_OK;
3115 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
3116 ICOM_THIS(IDirect3DDevice8Impl,iface);
3117 FIXME("(%p) : stub\n", This); return D3D_OK;
3119 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
3120 ICOM_THIS(IDirect3DDevice8Impl,iface);
3121 TRACE("(%p) : returning %p for stage %ld\n", This, This->StateBlock.textures[Stage], Stage);
3122 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage];
3123 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
3126 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
3128 IDirect3DBaseTexture8 *oldTxt;
3130 ICOM_THIS(IDirect3DDevice8Impl,iface);
3131 D3DRESOURCETYPE textureType;
3133 oldTxt = This->StateBlock.textures[Stage];
3134 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
3136 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
3137 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
3138 This->UpdateStateBlock->textures[Stage] = pTexture;
3140 /* Handle recording of state blocks */
3141 if (This->isRecordingState) {
3142 TRACE("Recording... not performing anything\n");
3146 /* Make appropriate texture active */
3147 if (This->isMultiTexture) {
3148 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3149 checkGLcall("glActiveTextureARB");
3150 } else if (Stage>0) {
3151 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3154 /* Decrement the count of the previous texture */
3155 /* FIXME PERF: If old == new and not dirty then skip all this */
3156 if (oldTxt != NULL) {
3157 IDirect3DBaseTexture8Impl_Release(oldTxt);
3161 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->StateBlock.textures[Stage]);
3163 /* Now setup the texture appropraitly */
3164 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
3166 if (textureType == D3DRTYPE_TEXTURE) {
3167 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
3170 /* Standard 2D texture */
3171 TRACE("Standard 2d texture\n");
3172 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_2D;
3174 for (i=0; i<pTexture2->levels; i++)
3177 if (i==0 && pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3178 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3179 checkGLcall("glBindTexture");
3180 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3181 /* No need to walk through all mip-map levels, since already all assigned */
3182 i = pTexture2->levels;
3187 if (pTexture2->surfaces[i]->textureName == 0) {
3188 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
3189 checkGLcall("glGenTextures");
3190 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3193 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3194 checkGLcall("glBindTexture");
3196 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", pTexture2->levels-1);
3197 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3198 checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels)");
3201 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3202 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
3203 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3204 pTexture2->surfaces[i]->allocatedMemory);
3205 glTexImage2D(GL_TEXTURE_2D, i,
3206 fmt2glintFmt(pTexture2->format),
3207 pTexture2->surfaces[i]->myDesc.Width,
3208 pTexture2->surfaces[i]->myDesc.Height,
3210 fmt2glFmt(pTexture2->format),
3211 fmt2glType(pTexture2->format),
3212 pTexture2->surfaces[i]->allocatedMemory
3214 checkGLcall("glTexImage2D");
3216 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3217 pTexture2->Dirty = FALSE;
3222 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3223 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3226 /* Standard 3D (volume) texture */
3227 TRACE("Standard 3d texture\n");
3228 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
3230 for (i=0; i<pTexture2->levels; i++)
3233 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3234 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3235 checkGLcall("glBindTexture");
3236 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3238 /* No need to walk through all mip-map levels, since already all assigned */
3239 i = pTexture2->levels;
3243 if (pTexture2->volumes[i]->textureName == 0) {
3244 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3245 checkGLcall("glGenTextures");
3246 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3249 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3250 checkGLcall("glBindTexture");
3252 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3253 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3256 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3257 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3258 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3259 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3260 pTexture2->volumes[i]->allocatedMemory);
3261 glTexImage3D(GL_TEXTURE_3D, i,
3262 fmt2glintFmt(pTexture2->format),
3263 pTexture2->volumes[i]->myDesc.Width,
3264 pTexture2->volumes[i]->myDesc.Height,
3265 pTexture2->volumes[i]->myDesc.Depth,
3267 fmt2glFmt(pTexture2->format),
3268 fmt2glType(pTexture2->format),
3269 pTexture2->volumes[i]->allocatedMemory
3271 checkGLcall("glTexImage3D");
3273 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3274 pTexture2->Dirty = FALSE;
3279 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
3282 TRACE("Setting to no texture (ie default texture)\n");
3283 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
3284 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3285 checkGLcall("glBindTexture");
3286 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3289 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3290 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3291 setupTextureStates (iface, Stage);
3296 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3297 ICOM_THIS(IDirect3DDevice8Impl,iface);
3298 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
3299 *pValue = This->StateBlock.texture_state[Stage][Type];
3303 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
3304 ICOM_THIS(IDirect3DDevice8Impl,iface);
3306 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3308 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
3310 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3311 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3312 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3314 /* Handle recording of state blocks */
3315 if (This->isRecordingState) {
3316 TRACE("Recording... not performing anything\n");
3320 /* Make appropriate texture active */
3321 TRACE("Activating appropriate texture state %ld\n", Stage);
3322 if (This->isMultiTexture) {
3323 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3324 checkGLcall("glActiveTextureARB");
3325 } else if (Stage>0) {
3326 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3331 case D3DTSS_MINFILTER :
3332 case D3DTSS_MIPFILTER :
3334 DWORD ValueMIN = This->StateBlock.texture_state[Stage][D3DTSS_MINFILTER];
3335 DWORD ValueMIP = This->StateBlock.texture_state[Stage][D3DTSS_MIPFILTER];
3336 GLint realVal = GL_LINEAR;
3338 if (ValueMIN == D3DTEXF_POINT) {
3340 if (ValueMIP == D3DTEXF_POINT) {
3341 realVal = GL_NEAREST_MIPMAP_NEAREST;
3342 } else if (ValueMIP == D3DTEXF_LINEAR) {
3343 realVal = GL_NEAREST_MIPMAP_LINEAR;
3344 } else if (ValueMIP == D3DTEXF_NONE) {
3345 realVal = GL_NEAREST;
3347 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3348 realVal = GL_NEAREST_MIPMAP_LINEAR;
3350 } else if (ValueMIN == D3DTEXF_LINEAR) {
3352 if (ValueMIP == D3DTEXF_POINT) {
3353 realVal = GL_LINEAR_MIPMAP_NEAREST;
3354 } else if (ValueMIP == D3DTEXF_LINEAR) {
3355 realVal = GL_LINEAR_MIPMAP_LINEAR;
3356 } else if (ValueMIP == D3DTEXF_NONE) {
3357 realVal = GL_LINEAR;
3359 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3360 realVal = GL_LINEAR_MIPMAP_LINEAR;
3362 } else if (ValueMIN == D3DTEXF_NONE) {
3363 /* Doesnt really make sense - Windows just seems to disable
3364 mipmapping when this occurs */
3365 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3366 realVal = GL_LINEAR;
3369 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3370 realVal = GL_LINEAR_MIPMAP_LINEAR;
3373 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3374 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3375 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3380 case D3DTSS_MAGFILTER :
3381 if (Value == D3DTEXF_POINT) {
3382 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3383 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3384 } else if (Value == D3DTEXF_LINEAR) {
3385 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3386 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3388 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3392 case D3DTSS_COLORARG0 :
3393 case D3DTSS_ALPHAARG0 :
3394 /* FIXME: Mesa seems to struggle setting these at the moment */
3397 case D3DTSS_COLORARG1 :
3398 case D3DTSS_COLORARG2 :
3399 case D3DTSS_ALPHAARG1 :
3400 case D3DTSS_ALPHAARG2 :
3402 BOOL isAlphaReplicate = FALSE;
3403 BOOL isComplement = FALSE;
3404 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3405 int operand= GL_SRC_COLOR;
3406 int source = GL_TEXTURE;
3408 /* Catch alpha replicate */
3409 if (Value & D3DTA_ALPHAREPLICATE) {
3410 Value = Value & ~D3DTA_ALPHAREPLICATE;
3411 isAlphaReplicate = TRUE;
3414 /* Catch Complement */
3415 if (Value & D3DTA_COMPLEMENT) {
3416 Value = Value & ~D3DTA_COMPLEMENT;
3417 isComplement = TRUE;
3420 /* Calculate the operand */
3421 if (isAlphaReplicate && !isComplement) {
3422 operand = GL_SRC_ALPHA;
3423 } else if (isAlphaReplicate && isComplement) {
3424 operand = GL_ONE_MINUS_SRC_ALPHA;
3425 } else if (isComplement) {
3427 operand = GL_ONE_MINUS_SRC_COLOR;
3429 operand = GL_ONE_MINUS_SRC_ALPHA;
3433 operand = GL_SRC_ALPHA;
3435 operand = GL_SRC_COLOR;
3439 /* Calculate the source */
3441 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
3443 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
3445 case D3DTA_TEXTURE: source = GL_TEXTURE;
3447 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
3450 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
3451 isnt supported until base GL supports it
3452 There is no concept of temp registers as far as I can tell */
3455 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
3459 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3460 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3461 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3462 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3463 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3465 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3466 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3467 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3468 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3469 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3474 case D3DTSS_ALPHAOP :
3475 case D3DTSS_COLOROP :
3479 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3481 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3482 /* TODO: Disable by making this and all later levels disabled */
3483 glDisable(GL_TEXTURE_1D);
3484 checkGLcall("Disable GL_TEXTURE_1D");
3485 glDisable(GL_TEXTURE_2D);
3486 checkGLcall("Disable GL_TEXTURE_2D");
3487 glDisable(GL_TEXTURE_3D);
3488 checkGLcall("Disable GL_TEXTURE_3D");
3491 /* Enable only the appropriate texture dimension */
3492 if (Type==D3DTSS_COLOROP) {
3493 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
3494 glEnable(GL_TEXTURE_1D);
3495 checkGLcall("Enable GL_TEXTURE_1D");
3497 glDisable(GL_TEXTURE_1D);
3498 checkGLcall("Disable GL_TEXTURE_1D");
3500 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
3501 glEnable(GL_TEXTURE_2D);
3502 checkGLcall("Enable GL_TEXTURE_2D");
3504 glDisable(GL_TEXTURE_2D);
3505 checkGLcall("Disable GL_TEXTURE_2D");
3507 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
3508 glEnable(GL_TEXTURE_3D);
3509 checkGLcall("Enable GL_TEXTURE_3D");
3511 glDisable(GL_TEXTURE_3D);
3512 checkGLcall("Disable GL_TEXTURE_3D");
3516 /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
3517 if (Value != D3DTOP_DISABLE) {
3518 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
3521 /* Now set up the operand correctly */
3523 case D3DTOP_DISABLE :
3524 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3525 and it works, so ignore this op */
3526 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3529 case D3DTOP_SELECTARG1 :
3530 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3531 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3534 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3535 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3536 case D3DTOP_MODULATE :
3539 if (Type == D3DTSS_ALPHAOP) {
3540 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3541 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3543 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3544 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3546 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3547 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3551 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3552 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3555 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3556 case D3DTOP_ADDSIGNED :
3557 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3558 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3561 case D3DTOP_DOTPRODUCT3 :
3562 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3563 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3566 case D3DTOP_SUBTRACT :
3567 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3568 case D3DTOP_SELECTARG2 :
3569 /* GL_REPLACE, swap args 0 and 1? */
3570 case D3DTOP_ADDSMOOTH :
3571 case D3DTOP_BLENDDIFFUSEALPHA :
3572 case D3DTOP_BLENDTEXTUREALPHA :
3573 case D3DTOP_BLENDFACTORALPHA :
3574 case D3DTOP_BLENDTEXTUREALPHAPM :
3575 case D3DTOP_BLENDCURRENTALPHA :
3576 case D3DTOP_PREMODULATE :
3577 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3578 case D3DTOP_MODULATECOLOR_ADDALPHA :
3579 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3580 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3581 case D3DTOP_BUMPENVMAP :
3582 case D3DTOP_BUMPENVMAPLUMINANCE :
3583 case D3DTOP_MULTIPLYADD :
3586 FIXME("Unhandled texture operation %ld\n", Value);
3592 case D3DTSS_ADDRESSU :
3593 case D3DTSS_ADDRESSV :
3594 case D3DTSS_ADDRESSW :
3596 GLint wrapParm = GL_REPEAT;
3598 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3599 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP; break;
3600 case D3DTADDRESS_BORDER: wrapParm = GL_CLAMP_TO_EDGE; break;
3602 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL? */
3603 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL? */
3605 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3606 wrapParm = GL_REPEAT;
3610 case D3DTSS_ADDRESSU:
3611 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3612 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3613 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3615 case D3DTSS_ADDRESSV:
3616 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3617 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3618 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3620 case D3DTSS_ADDRESSW:
3621 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3622 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3623 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3626 break; /** stupic compilator */
3631 case D3DTSS_BORDERCOLOR :
3634 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3635 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3636 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3637 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3639 TRACE("Setting border color for %x to %lx\n", This->StateBlock.textureDimensions[Stage], Value);
3640 glTexParameterfv(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3641 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3646 case D3DTSS_BUMPENVMAT00 :
3647 case D3DTSS_BUMPENVMAT01 :
3648 case D3DTSS_BUMPENVMAT10 :
3649 case D3DTSS_BUMPENVMAT11 :
3650 case D3DTSS_TEXCOORDINDEX :
3651 case D3DTSS_MIPMAPLODBIAS :
3652 case D3DTSS_MAXMIPLEVEL :
3653 case D3DTSS_MAXANISOTROPY :
3654 case D3DTSS_BUMPENVLSCALE :
3655 case D3DTSS_BUMPENVLOFFSET :
3656 case D3DTSS_TEXTURETRANSFORMFLAGS :
3657 case D3DTSS_RESULTARG :
3659 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3660 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3664 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3665 ICOM_THIS(IDirect3DDevice8Impl,iface);
3666 FIXME("(%p) : stub\n", This); return D3D_OK;
3668 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3669 ICOM_THIS(IDirect3DDevice8Impl,iface);
3670 FIXME("(%p) : stub\n", This); return D3D_OK;
3672 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3673 ICOM_THIS(IDirect3DDevice8Impl,iface);
3674 FIXME("(%p) : stub\n", This); return D3D_OK;
3676 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3677 ICOM_THIS(IDirect3DDevice8Impl,iface);
3678 FIXME("(%p) : stub\n", This); return D3D_OK;
3680 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3681 ICOM_THIS(IDirect3DDevice8Impl,iface);
3682 FIXME("(%p) : stub\n", This); return D3D_OK;
3684 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3685 ICOM_THIS(IDirect3DDevice8Impl,iface);
3686 FIXME("(%p) : stub\n", This); return D3D_OK;
3688 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3690 IDirect3DVertexBuffer8 *pVB;
3692 ICOM_THIS(IDirect3DDevice8Impl,iface);
3693 pVB = This->StateBlock.stream_source[0];
3695 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3697 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3698 This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
3702 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3703 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3705 IDirect3DIndexBuffer8 *pIB;
3706 IDirect3DVertexBuffer8 *pVB;
3707 D3DINDEXBUFFER_DESC IdxBufDsc;
3709 ICOM_THIS(IDirect3DDevice8Impl,iface);
3710 pIB = This->StateBlock.pIndexData;
3711 pVB = This->StateBlock.stream_source[0];
3713 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3714 minIndex, NumVertices, startIndex, primCount);
3716 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3717 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3723 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3724 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3729 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3730 ICOM_THIS(IDirect3DDevice8Impl,iface);
3732 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3734 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3736 This->StateBlock.stream_source[0] = NULL;
3737 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3738 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3740 This->StateBlock.stream_stride[0] = 0;
3742 /*stream zero settings set to null at end */
3745 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3746 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3747 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3748 UINT VertexStreamZeroStride) {
3750 ICOM_THIS(IDirect3DDevice8Impl,iface);
3751 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3752 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3754 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3755 if (IndexDataFormat == D3DFMT_INDEX16) {
3761 This->StateBlock.stream_source[0] = NULL;
3762 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3763 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3764 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3766 /*stream zero settings set to null at end */
3767 This->StateBlock.stream_stride[0] = 0;
3768 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3772 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3773 ICOM_THIS(IDirect3DDevice8Impl,iface);
3774 FIXME("(%p) : stub\n", This); return D3D_OK;
3776 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3777 ICOM_THIS(IDirect3DDevice8Impl,iface);
3778 VERTEXSHADER8* object;
3781 TRACE("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3782 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3783 return D3DERR_INVALIDCALL;
3785 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(VERTEXSHADER8*); ++i) ;
3786 if (i >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) {
3787 return D3DERR_OUTOFVIDEOMEMORY;
3789 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERTEXSHADER8));
3790 if (NULL == object) {
3791 return D3DERR_OUTOFVIDEOMEMORY;
3794 object->usage = Usage;
3795 object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADERDATA8));
3797 VertexShaders[i] = object;
3798 *pHandle = VS_HIGHESTFIXEDFXF + i;
3800 object->decl = (DWORD*) pDeclaration;
3801 object->function = (DWORD*) pFunction;
3803 vshader_decl_parse(object);
3804 vshader_program_parse(object);
3806 /* copy the function ... because it will certainly be released by application */
3807 if (NULL != pFunction) {
3808 object->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->functionLength);
3809 memcpy(object->function, pFunction, object->functionLength);
3811 /* copy the declaration too */
3812 object->decl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declLength);
3813 memcpy(object->decl, pDeclaration, object->declLength);
3816 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3817 ICOM_THIS(IDirect3DDevice8Impl,iface);
3819 This->UpdateStateBlock->VertexShader = Handle;
3820 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3821 This->UpdateStateBlock->Set.vertexShader = TRUE;
3823 /* Handle recording of state blocks */
3824 if (This->isRecordingState) {
3825 TRACE("Recording... not performing anything\n");
3828 if (Handle <= VS_HIGHESTFIXEDFXF) {
3829 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3832 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3836 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3837 ICOM_THIS(IDirect3DDevice8Impl,iface);
3838 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock.VertexShader);
3839 *pHandle = This->StateBlock.VertexShader;
3843 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3844 ICOM_THIS(IDirect3DDevice8Impl,iface);
3845 VERTEXSHADER8* object;
3847 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3848 return D3DERR_INVALIDCALL;
3850 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3851 if (NULL == object) {
3852 return D3DERR_INVALIDCALL;
3854 TRACE("(%p) : freing VertexShader %p\n", This, object);
3855 /* TODO: check validity of object */
3856 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3857 HeapFree(GetProcessHeap(), 0, (void *)object->decl);
3858 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3859 HeapFree(GetProcessHeap(), 0, (void *)object);
3860 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3864 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3865 ICOM_THIS(IDirect3DDevice8Impl,iface);
3866 VERTEXSHADER8* object;
3867 DWORD Handle = This->UpdateStateBlock->VertexShader;
3869 /* FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); */
3870 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3871 return D3DERR_INVALIDCALL;
3873 object = VERTEX_SHADER(Handle);
3874 if (NULL == object || NULL == pConstantData) {
3875 return D3DERR_INVALIDCALL;
3877 if (NULL == object->data) { /* temporary while datas not supported */
3878 FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
3879 return D3DERR_INVALIDCALL;
3881 memcpy(object->data->C + Register, pConstantData, ConstantCount * sizeof(D3DSHADERVECTOR));
3885 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3886 ICOM_THIS(IDirect3DDevice8Impl,iface);
3887 VERTEXSHADER8* object;
3888 DWORD Handle = This->UpdateStateBlock->VertexShader;
3890 FIXME("(%p) : VertexShader_GetConstant not fully supported yet\n", This);
3892 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3893 return D3DERR_INVALIDCALL;
3895 object = VERTEX_SHADER(Handle);
3896 if (NULL == object || NULL == pConstantData) {
3897 return D3DERR_INVALIDCALL;
3899 if (NULL == object->data) { /* temporary while datas not supported */
3900 return D3DERR_INVALIDCALL;
3902 memcpy(pConstantData, object->data->C + Register, ConstantCount * sizeof(D3DSHADERVECTOR));
3906 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3907 ICOM_THIS(IDirect3DDevice8Impl,iface);
3908 VERTEXSHADER8* object;
3910 object = VERTEX_SHADER(Handle);
3911 if (NULL == object) {
3912 return D3DERR_INVALIDCALL;
3914 if (NULL == pData) {
3915 *pSizeOfData = object->declLength;
3918 if (*pSizeOfData < object->declLength) {
3919 *pSizeOfData = object->declLength;
3920 return D3DERR_MOREDATA;
3922 TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
3923 memcpy(pData, object->decl, object->declLength);
3926 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3927 ICOM_THIS(IDirect3DDevice8Impl,iface);
3928 VERTEXSHADER8* object;
3930 object = VERTEX_SHADER(Handle);
3931 if (NULL == object) {
3932 return D3DERR_INVALIDCALL;
3934 if (NULL == pData) {
3935 *pSizeOfData = object->functionLength;
3938 if (*pSizeOfData < object->functionLength) {
3939 *pSizeOfData = object->functionLength;
3940 return D3DERR_MOREDATA;
3942 if (NULL == object->function) { /* no function defined */
3943 TRACE("(%p) : GetVertexShaderFunction no User Function defined using NULL to %p\n", This, pData);
3944 ((DWORD *) pData) = NULL;
3946 TRACE("(%p) : GetVertexShaderFunction copying to %p\n", This, pData);
3947 memcpy(pData, object->function, object->functionLength);
3952 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3953 ICOM_THIS(IDirect3DDevice8Impl,iface);
3954 IDirect3DIndexBuffer8 *oldIdxs;
3956 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3957 oldIdxs = This->StateBlock.pIndexData;
3959 This->UpdateStateBlock->Changed.Indices = TRUE;
3960 This->UpdateStateBlock->Set.Indices = TRUE;
3961 This->UpdateStateBlock->pIndexData = pIndexData;
3962 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3964 /* Handle recording of state blocks */
3965 if (This->isRecordingState) {
3966 TRACE("Recording... not performing anything\n");
3970 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3971 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3974 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3975 ICOM_THIS(IDirect3DDevice8Impl,iface);
3976 FIXME("(%p) : stub\n", This);
3978 *ppIndexData = This->StateBlock.pIndexData;
3979 /* up ref count on ppindexdata */
3980 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3981 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3985 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3986 ICOM_THIS(IDirect3DDevice8Impl,iface);
3987 PIXELSHADER8* object;
3990 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3991 if (NULL == pFunction || NULL == pHandle) {
3992 return D3DERR_INVALIDCALL;
3994 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(PIXELSHADER8*); ++i) ;
3995 if (i >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) {
3996 return D3DERR_OUTOFVIDEOMEMORY;
3998 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PIXELSHADER8));
3999 if (NULL == object) {
4000 return D3DERR_OUTOFVIDEOMEMORY;
4003 object->data = NULL; /* TODO */
4005 PixelShaders[i] = object;
4006 *pHandle = VS_HIGHESTFIXEDFXF + i;
4008 object->function = pFunction;
4009 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
4010 object->functionLength = i + 1;
4014 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4015 ICOM_THIS(IDirect3DDevice8Impl,iface);
4017 This->UpdateStateBlock->PixelShader = Handle;
4018 This->UpdateStateBlock->Changed.pixelShader = TRUE;
4019 This->UpdateStateBlock->Set.pixelShader = TRUE;
4021 /* Handle recording of state blocks */
4022 if (This->isRecordingState) {
4023 TRACE("Recording... not performing anything\n");
4027 /* FIXME: Quieten when not being used */
4029 FIXME("(%p) : stub %ld\n", This, Handle);
4031 TRACE("(%p) : stub %ld\n", This, Handle);
4036 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4037 ICOM_THIS(IDirect3DDevice8Impl,iface);
4038 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock.PixelShader);
4039 *pHandle = This->StateBlock.PixelShader;
4043 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4044 ICOM_THIS(IDirect3DDevice8Impl,iface);
4045 PIXELSHADER8* object;
4047 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4048 return D3DERR_INVALIDCALL;
4050 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
4051 TRACE("(%p) : freeing PixelShader %p\n", This, object);
4052 /* TODO: check validity of object before free */
4053 HeapFree(GetProcessHeap(), 0, (void *)object);
4054 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
4057 #define PIXEL_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
4059 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
4060 ICOM_THIS(IDirect3DDevice8Impl,iface);
4061 FIXME("(%p) : stub\n", This);
4064 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
4065 ICOM_THIS(IDirect3DDevice8Impl,iface);
4066 FIXME("(%p) : stub\n", This);
4069 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4070 ICOM_THIS(IDirect3DDevice8Impl,iface);
4071 PIXELSHADER8* object;
4073 object = PIXEL_SHADER(Handle);
4074 if (NULL == object) {
4075 return D3DERR_INVALIDCALL;
4077 if (NULL == pData) {
4078 *pSizeOfData = object->functionLength;
4081 if (*pSizeOfData < object->functionLength) {
4082 *pSizeOfData = object->functionLength;
4083 return D3DERR_MOREDATA;
4085 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
4086 memcpy(pData, object->function, object->functionLength);
4089 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
4090 ICOM_THIS(IDirect3DDevice8Impl,iface);
4091 FIXME("(%p) : stub\n", This); return D3D_OK;
4093 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
4094 ICOM_THIS(IDirect3DDevice8Impl,iface);
4095 FIXME("(%p) : stub\n", This); return D3D_OK;
4097 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
4098 ICOM_THIS(IDirect3DDevice8Impl,iface);
4099 FIXME("(%p) : stub\n", This); return D3D_OK;
4102 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
4103 IDirect3DVertexBuffer8 *oldSrc;
4104 ICOM_THIS(IDirect3DDevice8Impl,iface);
4106 oldSrc = This->StateBlock.stream_source[StreamNumber];
4107 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
4109 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
4110 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
4111 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
4112 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
4114 /* Handle recording of state blocks */
4115 if (This->isRecordingState) {
4116 TRACE("Recording... not performing anything\n");
4120 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
4121 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
4124 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
4125 ICOM_THIS(IDirect3DDevice8Impl,iface);
4126 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
4127 *pStream = This->StateBlock.stream_source[StreamNumber];
4128 *pStride = This->StateBlock.stream_stride[StreamNumber];
4129 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
4134 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
4136 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4137 IDirect3DDevice8Impl_QueryInterface,
4138 IDirect3DDevice8Impl_AddRef,
4139 IDirect3DDevice8Impl_Release,
4140 IDirect3DDevice8Impl_TestCooperativeLevel,
4141 IDirect3DDevice8Impl_GetAvailableTextureMem,
4142 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
4143 IDirect3DDevice8Impl_GetDirect3D,
4144 IDirect3DDevice8Impl_GetDeviceCaps,
4145 IDirect3DDevice8Impl_GetDisplayMode,
4146 IDirect3DDevice8Impl_GetCreationParameters,
4147 IDirect3DDevice8Impl_SetCursorProperties,
4148 IDirect3DDevice8Impl_SetCursorPosition,
4149 IDirect3DDevice8Impl_ShowCursor,
4150 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
4151 IDirect3DDevice8Impl_Reset,
4152 IDirect3DDevice8Impl_Present,
4153 IDirect3DDevice8Impl_GetBackBuffer,
4154 IDirect3DDevice8Impl_GetRasterStatus,
4155 IDirect3DDevice8Impl_SetGammaRamp,
4156 IDirect3DDevice8Impl_GetGammaRamp,
4157 IDirect3DDevice8Impl_CreateTexture,
4158 IDirect3DDevice8Impl_CreateVolumeTexture,
4159 IDirect3DDevice8Impl_CreateCubeTexture,
4160 IDirect3DDevice8Impl_CreateVertexBuffer,
4161 IDirect3DDevice8Impl_CreateIndexBuffer,
4162 IDirect3DDevice8Impl_CreateRenderTarget,
4163 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4164 IDirect3DDevice8Impl_CreateImageSurface,
4165 IDirect3DDevice8Impl_CopyRects,
4166 IDirect3DDevice8Impl_UpdateTexture,
4167 IDirect3DDevice8Impl_GetFrontBuffer,
4168 IDirect3DDevice8Impl_SetRenderTarget,
4169 IDirect3DDevice8Impl_GetRenderTarget,
4170 IDirect3DDevice8Impl_GetDepthStencilSurface,
4171 IDirect3DDevice8Impl_BeginScene,
4172 IDirect3DDevice8Impl_EndScene,
4173 IDirect3DDevice8Impl_Clear,
4174 IDirect3DDevice8Impl_SetTransform,
4175 IDirect3DDevice8Impl_GetTransform,
4176 IDirect3DDevice8Impl_MultiplyTransform,
4177 IDirect3DDevice8Impl_SetViewport,
4178 IDirect3DDevice8Impl_GetViewport,
4179 IDirect3DDevice8Impl_SetMaterial,
4180 IDirect3DDevice8Impl_GetMaterial,
4181 IDirect3DDevice8Impl_SetLight,
4182 IDirect3DDevice8Impl_GetLight,
4183 IDirect3DDevice8Impl_LightEnable,
4184 IDirect3DDevice8Impl_GetLightEnable,
4185 IDirect3DDevice8Impl_SetClipPlane,
4186 IDirect3DDevice8Impl_GetClipPlane,
4187 IDirect3DDevice8Impl_SetRenderState,
4188 IDirect3DDevice8Impl_GetRenderState,
4189 IDirect3DDevice8Impl_BeginStateBlock,
4190 IDirect3DDevice8Impl_EndStateBlock,
4191 IDirect3DDevice8Impl_ApplyStateBlock,
4192 IDirect3DDevice8Impl_CaptureStateBlock,
4193 IDirect3DDevice8Impl_DeleteStateBlock,
4194 IDirect3DDevice8Impl_CreateStateBlock,
4195 IDirect3DDevice8Impl_SetClipStatus,
4196 IDirect3DDevice8Impl_GetClipStatus,
4197 IDirect3DDevice8Impl_GetTexture,
4198 IDirect3DDevice8Impl_SetTexture,
4199 IDirect3DDevice8Impl_GetTextureStageState,
4200 IDirect3DDevice8Impl_SetTextureStageState,
4201 IDirect3DDevice8Impl_ValidateDevice,
4202 IDirect3DDevice8Impl_GetInfo,
4203 IDirect3DDevice8Impl_SetPaletteEntries,
4204 IDirect3DDevice8Impl_GetPaletteEntries,
4205 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4206 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4207 IDirect3DDevice8Impl_DrawPrimitive,
4208 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4209 IDirect3DDevice8Impl_DrawPrimitiveUP,
4210 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4211 IDirect3DDevice8Impl_ProcessVertices,
4212 IDirect3DDevice8Impl_CreateVertexShader,
4213 IDirect3DDevice8Impl_SetVertexShader,
4214 IDirect3DDevice8Impl_GetVertexShader,
4215 IDirect3DDevice8Impl_DeleteVertexShader,
4216 IDirect3DDevice8Impl_SetVertexShaderConstant,
4217 IDirect3DDevice8Impl_GetVertexShaderConstant,
4218 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4219 IDirect3DDevice8Impl_GetVertexShaderFunction,
4220 IDirect3DDevice8Impl_SetStreamSource,
4221 IDirect3DDevice8Impl_GetStreamSource,
4222 IDirect3DDevice8Impl_SetIndices,
4223 IDirect3DDevice8Impl_GetIndices,
4224 IDirect3DDevice8Impl_CreatePixelShader,
4225 IDirect3DDevice8Impl_SetPixelShader,
4226 IDirect3DDevice8Impl_GetPixelShader,
4227 IDirect3DDevice8Impl_DeletePixelShader,
4228 IDirect3DDevice8Impl_SetPixelShaderConstant,
4229 IDirect3DDevice8Impl_GetPixelShaderConstant,
4230 IDirect3DDevice8Impl_GetPixelShaderFunction,
4231 IDirect3DDevice8Impl_DrawRectPatch,
4232 IDirect3DDevice8Impl_DrawTriPatch,
4233 IDirect3DDevice8Impl_DeletePatch
4236 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
4240 ICOM_THIS(IDirect3DDevice8Impl,iface);
4242 /* Note this may have a large overhead but it should only be executed
4243 once, in order to initialize the complete state of the device and
4244 all opengl equivalents */
4245 TRACE("-----------------------> Setting up device defaults...\n");
4246 This->StateBlock.blockType = D3DSBT_ALL;
4248 /* FIXME: Set some of the defaults for lights, transforms etc */
4249 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
4250 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
4251 for (i = 0; i < 256; ++i) {
4252 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(i)], &idmatrix, sizeof(idmatrix));
4255 /* Render states: */
4256 if (This->PresentParms.EnableAutoDepthStencil) {
4257 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
4259 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
4261 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
4262 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
4263 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
4264 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
4265 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
4266 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
4267 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
4268 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
4269 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
4270 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
4271 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
4272 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
4273 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
4274 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
4275 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
4276 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
4277 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
4278 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
4279 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
4280 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
4281 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
4282 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
4283 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
4284 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
4285 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
4286 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
4287 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
4288 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
4289 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
4290 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
4291 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
4292 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
4293 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
4294 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
4295 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
4296 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
4297 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
4298 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
4299 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
4300 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
4301 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
4302 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
4303 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
4304 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
4305 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
4306 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
4307 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
4308 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
4309 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
4310 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
4311 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
4312 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
4313 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
4314 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
4315 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
4316 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
4317 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
4318 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
4319 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
4320 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
4321 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
4322 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
4323 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
4324 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
4325 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
4326 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
4327 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
4328 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
4329 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
4330 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
4331 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
4332 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
4333 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4334 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
4335 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
4337 /* Texture Stage States - Put directly into state block, we will call function below */
4338 for (i=0; i<This->TextureUnits;i++) {
4339 memcpy(&This->StateBlock.transforms[D3DTS_TEXTURE0+i], &idmatrix, sizeof(idmatrix));
4340 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
4341 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
4342 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
4343 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
4344 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
4345 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
4346 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
4347 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
4348 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
4349 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
4350 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
4351 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
4352 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
4353 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
4354 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
4355 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
4356 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
4357 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
4358 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
4359 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
4360 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
4361 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
4362 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
4363 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
4364 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
4365 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
4366 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
4369 /* Under DirectX you can have texture stage operations even if no texture is
4370 bound, whereas opengl will only do texture operations when a valid texture is
4371 bound. We emulate this by creating dummy textures and binding them to each
4372 texture stage, but disable all stages by default. Hence if a stage is enabled
4373 then the default texture will kick in until replaced by a SetTexture call */
4375 for (i=0; i<This->TextureUnits; i++) {
4376 GLubyte white = 255;
4378 /* Note this avoids calling settexture, so pretend it has been called */
4379 This->StateBlock.Set.textures[i] = TRUE;
4380 This->StateBlock.Changed.textures[i] = TRUE;
4381 This->StateBlock.textures[i] = NULL;
4383 /* Make appropriate texture active */
4384 if (This->isMultiTexture) {
4385 glActiveTextureARB(GL_TEXTURE0_ARB + i);
4386 checkGLcall("glActiveTextureARB");
4388 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
4391 /* Generate an opengl texture name */
4392 glGenTextures(1, &This->dummyTextureName[i]);
4393 checkGLcall("glGenTextures");
4394 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
4396 /* Generate a dummy 1d texture */
4397 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
4398 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
4399 checkGLcall("glBindTexture");
4401 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
4402 checkGLcall("glTexImage1D");
4404 /* Reapply all the texture state information to this texture */
4405 setupTextureStates(iface, i);
4408 TRACE("-----------------------> Device defaults now set up...\n");
4413 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
4414 D3DRS_ALPHABLENDENABLE ,
4417 D3DRS_ALPHATESTENABLE ,
4419 D3DRS_COLORWRITEENABLE ,
4421 D3DRS_DITHERENABLE ,
4422 D3DRS_EDGEANTIALIAS ,
4431 D3DRS_STENCILENABLE ,
4437 D3DRS_STENCILWRITEMASK ,
4438 D3DRS_STENCILZFAIL ,
4439 D3DRS_TEXTUREFACTOR ,
4454 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
4462 D3DTSS_BORDERCOLOR ,
4463 D3DTSS_BUMPENVLOFFSET ,
4464 D3DTSS_BUMPENVLSCALE ,
4465 D3DTSS_BUMPENVMAT00 ,
4466 D3DTSS_BUMPENVMAT01 ,
4467 D3DTSS_BUMPENVMAT10 ,
4468 D3DTSS_BUMPENVMAT11 ,
4474 D3DTSS_MAXANISOTROPY ,
4475 D3DTSS_MAXMIPLEVEL ,
4478 D3DTSS_MIPMAPLODBIAS ,
4480 D3DTSS_TEXCOORDINDEX ,
4481 D3DTSS_TEXTURETRANSFORMFLAGS
4484 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
4486 D3DRS_AMBIENTMATERIALSOURCE ,
4488 D3DRS_CLIPPLANEENABLE ,
4490 D3DRS_DIFFUSEMATERIALSOURCE ,
4491 D3DRS_EMISSIVEMATERIALSOURCE ,
4495 D3DRS_FOGTABLEMODE ,
4496 D3DRS_FOGVERTEXMODE ,
4497 D3DRS_INDEXEDVERTEXBLENDENABLE ,
4500 D3DRS_MULTISAMPLEANTIALIAS ,
4501 D3DRS_MULTISAMPLEMASK ,
4502 D3DRS_NORMALIZENORMALS ,
4503 D3DRS_PATCHEDGESTYLE ,
4504 D3DRS_PATCHSEGMENTS ,
4505 D3DRS_POINTSCALE_A ,
4506 D3DRS_POINTSCALE_B ,
4507 D3DRS_POINTSCALE_C ,
4508 D3DRS_POINTSCALEENABLE ,
4510 D3DRS_POINTSIZE_MAX ,
4511 D3DRS_POINTSIZE_MIN ,
4512 D3DRS_POINTSPRITEENABLE ,
4513 D3DRS_RANGEFOGENABLE ,
4514 D3DRS_SOFTWAREVERTEXPROCESSING ,
4515 D3DRS_SPECULARMATERIALSOURCE ,
4520 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
4521 D3DTSS_TEXCOORDINDEX ,
4522 D3DTSS_TEXTURETRANSFORMFLAGS