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);
3184 if (pTexture2->surfaces[i]->textureName == 0) {
3185 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
3186 checkGLcall("glGenTextures");
3187 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3190 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3191 checkGLcall("glBindTexture");
3193 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", pTexture2->levels-1);
3194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3195 checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels)");
3198 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3199 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
3200 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3201 pTexture2->surfaces[i]->allocatedMemory);
3202 glTexImage2D(GL_TEXTURE_2D, i,
3203 fmt2glintFmt(pTexture2->format),
3204 pTexture2->surfaces[i]->myDesc.Width,
3205 pTexture2->surfaces[i]->myDesc.Height,
3207 fmt2glFmt(pTexture2->format),
3208 fmt2glType(pTexture2->format),
3209 pTexture2->surfaces[i]->allocatedMemory
3211 checkGLcall("glTexImage2D");
3213 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3214 pTexture2->Dirty = FALSE;
3219 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3220 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3223 /* Standard 3D (volume) texture */
3224 TRACE("Standard 3d texture\n");
3225 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_3D;
3227 for (i=0; i<pTexture2->levels; i++)
3230 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3231 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3232 checkGLcall("glBindTexture");
3233 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3237 if (pTexture2->volumes[i]->textureName == 0) {
3238 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3239 checkGLcall("glGenTextures");
3240 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3243 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3244 checkGLcall("glBindTexture");
3246 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3247 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3250 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3251 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3252 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3253 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3254 pTexture2->volumes[i]->allocatedMemory);
3255 glTexImage3D(GL_TEXTURE_3D, i,
3256 fmt2glintFmt(pTexture2->format),
3257 pTexture2->volumes[i]->myDesc.Width,
3258 pTexture2->volumes[i]->myDesc.Height,
3259 pTexture2->volumes[i]->myDesc.Depth,
3261 fmt2glFmt(pTexture2->format),
3262 fmt2glType(pTexture2->format),
3263 pTexture2->volumes[i]->allocatedMemory
3265 checkGLcall("glTexImage3D");
3267 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3268 pTexture2->Dirty = FALSE;
3273 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
3276 TRACE("Setting to no texture (ie default texture)\n");
3277 This->StateBlock.textureDimensions[Stage] = GL_TEXTURE_1D;
3278 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3279 checkGLcall("glBindTexture");
3280 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3283 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3284 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3285 setupTextureStates (iface, Stage);
3290 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3291 ICOM_THIS(IDirect3DDevice8Impl,iface);
3292 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->StateBlock.texture_state[Stage][Type]);
3293 *pValue = This->StateBlock.texture_state[Stage][Type];
3297 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
3298 ICOM_THIS(IDirect3DDevice8Impl,iface);
3300 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3302 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
3304 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3305 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3306 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3308 /* Handle recording of state blocks */
3309 if (This->isRecordingState) {
3310 TRACE("Recording... not performing anything\n");
3314 /* Make appropriate texture active */
3315 TRACE("Activating appropriate texture state %ld\n", Stage);
3316 if (This->isMultiTexture) {
3317 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3318 checkGLcall("glActiveTextureARB");
3319 } else if (Stage>0) {
3320 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3325 case D3DTSS_MINFILTER :
3326 case D3DTSS_MIPFILTER :
3328 DWORD ValueMIN = This->StateBlock.texture_state[Stage][D3DTSS_MINFILTER];
3329 DWORD ValueMIP = This->StateBlock.texture_state[Stage][D3DTSS_MIPFILTER];
3330 GLint realVal = GL_LINEAR;
3332 if (ValueMIN == D3DTEXF_POINT) {
3334 if (ValueMIP == D3DTEXF_POINT) {
3335 realVal = GL_NEAREST_MIPMAP_NEAREST;
3336 } else if (ValueMIP == D3DTEXF_LINEAR) {
3337 realVal = GL_NEAREST_MIPMAP_LINEAR;
3338 } else if (ValueMIP == D3DTEXF_NONE) {
3339 realVal = GL_NEAREST;
3341 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3342 realVal = GL_NEAREST_MIPMAP_LINEAR;
3344 } else if (ValueMIN == D3DTEXF_LINEAR) {
3346 if (ValueMIP == D3DTEXF_POINT) {
3347 realVal = GL_LINEAR_MIPMAP_NEAREST;
3348 } else if (ValueMIP == D3DTEXF_LINEAR) {
3349 realVal = GL_LINEAR_MIPMAP_LINEAR;
3350 } else if (ValueMIP == D3DTEXF_NONE) {
3351 realVal = GL_LINEAR;
3353 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3354 realVal = GL_LINEAR_MIPMAP_LINEAR;
3356 } else if (ValueMIN == D3DTEXF_NONE) {
3357 /* Doesnt really make sense - Windows just seems to disable
3358 mipmapping when this occurs */
3359 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3360 realVal = GL_LINEAR;
3363 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3364 realVal = GL_LINEAR_MIPMAP_LINEAR;
3367 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3368 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3369 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3374 case D3DTSS_MAGFILTER :
3375 if (Value == D3DTEXF_POINT) {
3376 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3377 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3378 } else if (Value == D3DTEXF_LINEAR) {
3379 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3380 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3382 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3386 case D3DTSS_COLORARG0 :
3387 case D3DTSS_ALPHAARG0 :
3388 /* FIXME: Mesa seems to struggle setting these at the moment */
3391 case D3DTSS_COLORARG1 :
3392 case D3DTSS_COLORARG2 :
3393 case D3DTSS_ALPHAARG1 :
3394 case D3DTSS_ALPHAARG2 :
3396 BOOL isAlphaReplicate = FALSE;
3397 BOOL isComplement = FALSE;
3398 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3399 int operand= GL_SRC_COLOR;
3400 int source = GL_TEXTURE;
3402 /* Catch alpha replicate */
3403 if (Value & D3DTA_ALPHAREPLICATE) {
3404 Value = Value & ~D3DTA_ALPHAREPLICATE;
3405 isAlphaReplicate = TRUE;
3408 /* Catch Complement */
3409 if (Value & D3DTA_COMPLEMENT) {
3410 Value = Value & ~D3DTA_COMPLEMENT;
3411 isComplement = TRUE;
3414 /* Calculate the operand */
3415 if (isAlphaReplicate && !isComplement) {
3416 operand = GL_SRC_ALPHA;
3417 } else if (isAlphaReplicate && isComplement) {
3418 operand = GL_ONE_MINUS_SRC_ALPHA;
3419 } else if (isComplement) {
3421 operand = GL_ONE_MINUS_SRC_COLOR;
3423 operand = GL_ONE_MINUS_SRC_ALPHA;
3427 operand = GL_SRC_ALPHA;
3429 operand = GL_SRC_COLOR;
3433 /* Calculate the source */
3435 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
3437 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
3439 case D3DTA_TEXTURE: source = GL_TEXTURE;
3441 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
3444 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
3445 isnt supported until base GL supports it
3446 There is no concept of temp registers as far as I can tell */
3449 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
3453 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3454 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3455 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3456 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3457 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3459 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3460 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3461 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3462 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3463 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3468 case D3DTSS_ALPHAOP :
3469 case D3DTSS_COLOROP :
3473 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3475 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3476 /* TODO: Disable by making this and all later levels disabled */
3477 glDisable(GL_TEXTURE_1D);
3478 checkGLcall("Disable GL_TEXTURE_1D");
3479 glDisable(GL_TEXTURE_2D);
3480 checkGLcall("Disable GL_TEXTURE_2D");
3481 glDisable(GL_TEXTURE_3D);
3482 checkGLcall("Disable GL_TEXTURE_3D");
3485 /* Enable only the appropriate texture dimension */
3486 if (Type==D3DTSS_COLOROP) {
3487 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_1D) {
3488 glEnable(GL_TEXTURE_1D);
3489 checkGLcall("Enable GL_TEXTURE_1D");
3491 glDisable(GL_TEXTURE_1D);
3492 checkGLcall("Disable GL_TEXTURE_1D");
3494 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_2D) {
3495 glEnable(GL_TEXTURE_2D);
3496 checkGLcall("Enable GL_TEXTURE_2D");
3498 glDisable(GL_TEXTURE_2D);
3499 checkGLcall("Disable GL_TEXTURE_2D");
3501 if (This->StateBlock.textureDimensions[Stage] == GL_TEXTURE_3D) {
3502 glEnable(GL_TEXTURE_3D);
3503 checkGLcall("Enable GL_TEXTURE_3D");
3505 glDisable(GL_TEXTURE_3D);
3506 checkGLcall("Disable GL_TEXTURE_3D");
3510 /* Now set up the operand correctly */
3512 case D3DTOP_DISABLE :
3513 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3514 and it works, so ignore this op */
3515 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3518 case D3DTOP_SELECTARG1 :
3519 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3520 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3523 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3524 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3525 case D3DTOP_MODULATE :
3528 if (Type == D3DTSS_ALPHAOP) {
3529 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3530 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3532 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3533 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3535 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3536 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3540 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3541 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3544 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3545 case D3DTOP_ADDSIGNED :
3546 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3547 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3550 case D3DTOP_DOTPRODUCT3 :
3551 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3552 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3555 case D3DTOP_SUBTRACT :
3556 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3557 case D3DTOP_SELECTARG2 :
3558 /* GL_REPLACE, swap args 0 and 1? */
3559 case D3DTOP_ADDSMOOTH :
3560 case D3DTOP_BLENDDIFFUSEALPHA :
3561 case D3DTOP_BLENDTEXTUREALPHA :
3562 case D3DTOP_BLENDFACTORALPHA :
3563 case D3DTOP_BLENDTEXTUREALPHAPM :
3564 case D3DTOP_BLENDCURRENTALPHA :
3565 case D3DTOP_PREMODULATE :
3566 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3567 case D3DTOP_MODULATECOLOR_ADDALPHA :
3568 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3569 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3570 case D3DTOP_BUMPENVMAP :
3571 case D3DTOP_BUMPENVMAPLUMINANCE :
3572 case D3DTOP_MULTIPLYADD :
3575 FIXME("Unhandled texture operation %ld\n", Value);
3581 case D3DTSS_ADDRESSU :
3582 case D3DTSS_ADDRESSV :
3583 case D3DTSS_ADDRESSW :
3585 GLint wrapParm = GL_REPEAT;
3587 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3588 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP; break;
3589 case D3DTADDRESS_BORDER: wrapParm = GL_CLAMP_TO_EDGE; break;
3591 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL? */
3592 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL? */
3594 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3595 wrapParm = GL_REPEAT;
3599 case D3DTSS_ADDRESSU:
3600 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3601 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3602 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3604 case D3DTSS_ADDRESSV:
3605 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3606 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3607 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3609 case D3DTSS_ADDRESSW:
3610 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock.textureDimensions[Stage]);
3611 glTexParameteri(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3612 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3615 break; /** stupic compilator */
3620 case D3DTSS_BORDERCOLOR :
3623 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3624 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3625 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3626 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3628 TRACE("Setting border color for %x to %lx\n", This->StateBlock.textureDimensions[Stage], Value);
3629 glTexParameterfv(This->StateBlock.textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3630 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3635 case D3DTSS_BUMPENVMAT00 :
3636 case D3DTSS_BUMPENVMAT01 :
3637 case D3DTSS_BUMPENVMAT10 :
3638 case D3DTSS_BUMPENVMAT11 :
3639 case D3DTSS_TEXCOORDINDEX :
3640 case D3DTSS_MIPMAPLODBIAS :
3641 case D3DTSS_MAXMIPLEVEL :
3642 case D3DTSS_MAXANISOTROPY :
3643 case D3DTSS_BUMPENVLSCALE :
3644 case D3DTSS_BUMPENVLOFFSET :
3645 case D3DTSS_TEXTURETRANSFORMFLAGS :
3646 case D3DTSS_RESULTARG :
3648 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3649 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3653 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3654 ICOM_THIS(IDirect3DDevice8Impl,iface);
3655 FIXME("(%p) : stub\n", This); return D3D_OK;
3657 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3658 ICOM_THIS(IDirect3DDevice8Impl,iface);
3659 FIXME("(%p) : stub\n", This); return D3D_OK;
3661 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3662 ICOM_THIS(IDirect3DDevice8Impl,iface);
3663 FIXME("(%p) : stub\n", This); return D3D_OK;
3665 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3666 ICOM_THIS(IDirect3DDevice8Impl,iface);
3667 FIXME("(%p) : stub\n", This); return D3D_OK;
3669 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3670 ICOM_THIS(IDirect3DDevice8Impl,iface);
3671 FIXME("(%p) : stub\n", This); return D3D_OK;
3673 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3674 ICOM_THIS(IDirect3DDevice8Impl,iface);
3675 FIXME("(%p) : stub\n", This); return D3D_OK;
3677 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3679 IDirect3DVertexBuffer8 *pVB;
3681 ICOM_THIS(IDirect3DDevice8Impl,iface);
3682 pVB = This->StateBlock.stream_source[0];
3684 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3686 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3687 This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
3691 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3692 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3694 IDirect3DIndexBuffer8 *pIB;
3695 IDirect3DVertexBuffer8 *pVB;
3696 D3DINDEXBUFFER_DESC IdxBufDsc;
3698 ICOM_THIS(IDirect3DDevice8Impl,iface);
3699 pIB = This->StateBlock.pIndexData;
3700 pVB = This->StateBlock.stream_source[0];
3702 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3703 minIndex, NumVertices, startIndex, primCount);
3705 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3706 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3712 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock.VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3713 This->StateBlock.baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3718 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3719 ICOM_THIS(IDirect3DDevice8Impl,iface);
3721 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3723 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3725 This->StateBlock.stream_source[0] = NULL;
3726 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3727 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3729 This->StateBlock.stream_stride[0] = 0;
3731 /*stream zero settings set to null at end */
3734 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3735 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3736 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3737 UINT VertexStreamZeroStride) {
3739 ICOM_THIS(IDirect3DDevice8Impl,iface);
3740 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3741 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3743 if (This->StateBlock.stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock.stream_source[0]);
3744 if (IndexDataFormat == D3DFMT_INDEX16) {
3750 This->StateBlock.stream_source[0] = NULL;
3751 This->StateBlock.stream_stride[0] = VertexStreamZeroStride;
3752 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock.VertexShader, pVertexStreamZeroData,
3753 This->StateBlock.baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3755 /*stream zero settings set to null at end */
3756 This->StateBlock.stream_stride[0] = 0;
3757 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3761 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3762 ICOM_THIS(IDirect3DDevice8Impl,iface);
3763 FIXME("(%p) : stub\n", This); return D3D_OK;
3765 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3766 ICOM_THIS(IDirect3DDevice8Impl,iface);
3767 VERTEXSHADER8* object;
3770 TRACE("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3771 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3772 return D3DERR_INVALIDCALL;
3774 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(VERTEXSHADER8*); ++i) ;
3775 if (i >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) {
3776 return D3DERR_OUTOFVIDEOMEMORY;
3778 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VERTEXSHADER8));
3779 if (NULL == object) {
3780 return D3DERR_OUTOFVIDEOMEMORY;
3783 object->usage = Usage;
3784 object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADERDATA8));
3786 VertexShaders[i] = object;
3787 *pHandle = VS_HIGHESTFIXEDFXF + i;
3789 object->decl = (DWORD*) pDeclaration;
3790 object->function = (DWORD*) pFunction;
3792 vshader_decl_parse(object);
3793 vshader_program_parse(object);
3795 /* copy the function ... because it will certainly be released by application */
3796 if (NULL != pFunction) {
3797 object->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->functionLength);
3798 memcpy(object->function, pFunction, object->functionLength);
3800 /* copy the declaration too */
3801 object->decl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declLength);
3802 memcpy(object->decl, pDeclaration, object->declLength);
3805 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3806 ICOM_THIS(IDirect3DDevice8Impl,iface);
3808 This->UpdateStateBlock->VertexShader = Handle;
3809 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3810 This->UpdateStateBlock->Set.vertexShader = TRUE;
3812 /* Handle recording of state blocks */
3813 if (This->isRecordingState) {
3814 TRACE("Recording... not performing anything\n");
3817 if (Handle <= VS_HIGHESTFIXEDFXF) {
3818 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3821 FIXME("(%p) : Created shader, Handle=%lx stub\n", This, Handle);
3825 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3826 ICOM_THIS(IDirect3DDevice8Impl,iface);
3827 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock.VertexShader);
3828 *pHandle = This->StateBlock.VertexShader;
3832 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3833 ICOM_THIS(IDirect3DDevice8Impl,iface);
3834 VERTEXSHADER8* object;
3836 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3837 return D3DERR_INVALIDCALL;
3839 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3840 if (NULL == object) {
3841 return D3DERR_INVALIDCALL;
3843 TRACE("(%p) : freing VertexShader %p\n", This, object);
3844 /* TODO: check validity of object */
3845 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3846 HeapFree(GetProcessHeap(), 0, (void *)object->decl);
3847 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3848 HeapFree(GetProcessHeap(), 0, (void *)object);
3849 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3853 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3854 ICOM_THIS(IDirect3DDevice8Impl,iface);
3855 VERTEXSHADER8* object;
3856 DWORD Handle = This->UpdateStateBlock->VertexShader;
3858 /* FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); */
3859 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3860 return D3DERR_INVALIDCALL;
3862 object = VERTEX_SHADER(Handle);
3863 if (NULL == object || NULL == pConstantData) {
3864 return D3DERR_INVALIDCALL;
3866 if (NULL == object->data) { /* temporary while datas not supported */
3867 FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
3868 return D3DERR_INVALIDCALL;
3870 memcpy(object->data->C + Register, pConstantData, ConstantCount * sizeof(D3DSHADERVECTOR));
3874 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3875 ICOM_THIS(IDirect3DDevice8Impl,iface);
3876 VERTEXSHADER8* object;
3877 DWORD Handle = This->UpdateStateBlock->VertexShader;
3879 FIXME("(%p) : VertexShader_GetConstant not fully supported yet\n", This);
3881 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3882 return D3DERR_INVALIDCALL;
3884 object = VERTEX_SHADER(Handle);
3885 if (NULL == object || NULL == pConstantData) {
3886 return D3DERR_INVALIDCALL;
3888 if (NULL == object->data) { /* temporary while datas not supported */
3889 return D3DERR_INVALIDCALL;
3891 memcpy(pConstantData, object->data->C + Register, ConstantCount * sizeof(D3DSHADERVECTOR));
3895 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3896 ICOM_THIS(IDirect3DDevice8Impl,iface);
3897 VERTEXSHADER8* object;
3899 object = VERTEX_SHADER(Handle);
3900 if (NULL == object) {
3901 return D3DERR_INVALIDCALL;
3903 if (NULL == pData) {
3904 *pSizeOfData = object->declLength;
3907 if (*pSizeOfData < object->declLength) {
3908 *pSizeOfData = object->declLength;
3909 return D3DERR_MOREDATA;
3911 TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
3912 memcpy(pData, object->decl, object->declLength);
3915 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3916 ICOM_THIS(IDirect3DDevice8Impl,iface);
3917 VERTEXSHADER8* object;
3919 object = VERTEX_SHADER(Handle);
3920 if (NULL == object) {
3921 return D3DERR_INVALIDCALL;
3923 if (NULL == pData) {
3924 *pSizeOfData = object->functionLength;
3927 if (*pSizeOfData < object->functionLength) {
3928 *pSizeOfData = object->functionLength;
3929 return D3DERR_MOREDATA;
3931 if (NULL == object->function) { /* no function defined */
3932 TRACE("(%p) : GetVertexShaderFunction no User Function defined using NULL to %p\n", This, pData);
3933 ((DWORD *) pData) = NULL;
3935 TRACE("(%p) : GetVertexShaderFunction copying to %p\n", This, pData);
3936 memcpy(pData, object->function, object->functionLength);
3941 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) {
3942 ICOM_THIS(IDirect3DDevice8Impl,iface);
3943 IDirect3DIndexBuffer8 *oldIdxs;
3945 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3946 oldIdxs = This->StateBlock.pIndexData;
3948 This->UpdateStateBlock->Changed.Indices = TRUE;
3949 This->UpdateStateBlock->Set.Indices = TRUE;
3950 This->UpdateStateBlock->pIndexData = pIndexData;
3951 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3953 /* Handle recording of state blocks */
3954 if (This->isRecordingState) {
3955 TRACE("Recording... not performing anything\n");
3959 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3960 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock.pIndexData);
3963 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3964 ICOM_THIS(IDirect3DDevice8Impl,iface);
3965 FIXME("(%p) : stub\n", This);
3967 *ppIndexData = This->StateBlock.pIndexData;
3968 /* up ref count on ppindexdata */
3969 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3970 *pBaseVertexIndex = This->StateBlock.baseVertexIndex;
3974 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3975 ICOM_THIS(IDirect3DDevice8Impl,iface);
3976 PIXELSHADER8* object;
3979 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3980 if (NULL == pFunction || NULL == pHandle) {
3981 return D3DERR_INVALIDCALL;
3983 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(PIXELSHADER8*); ++i) ;
3984 if (i >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) {
3985 return D3DERR_OUTOFVIDEOMEMORY;
3987 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PIXELSHADER8));
3988 if (NULL == object) {
3989 return D3DERR_OUTOFVIDEOMEMORY;
3992 object->data = NULL; /* TODO */
3994 PixelShaders[i] = object;
3995 *pHandle = VS_HIGHESTFIXEDFXF + i;
3997 object->function = pFunction;
3998 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3999 object->functionLength = i + 1;
4003 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4004 ICOM_THIS(IDirect3DDevice8Impl,iface);
4006 This->UpdateStateBlock->PixelShader = Handle;
4007 This->UpdateStateBlock->Changed.pixelShader = TRUE;
4008 This->UpdateStateBlock->Set.pixelShader = TRUE;
4010 /* Handle recording of state blocks */
4011 if (This->isRecordingState) {
4012 TRACE("Recording... not performing anything\n");
4016 /* FIXME: Quieten when not being used */
4018 FIXME("(%p) : stub %ld\n", This, Handle);
4020 TRACE("(%p) : stub %ld\n", This, Handle);
4025 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4026 ICOM_THIS(IDirect3DDevice8Impl,iface);
4027 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock.PixelShader);
4028 *pHandle = This->StateBlock.PixelShader;
4032 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4033 ICOM_THIS(IDirect3DDevice8Impl,iface);
4034 PIXELSHADER8* object;
4036 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4037 return D3DERR_INVALIDCALL;
4039 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
4040 TRACE("(%p) : freeing PixelShader %p\n", This, object);
4041 /* TODO: check validity of object before free */
4042 HeapFree(GetProcessHeap(), 0, (void *)object);
4043 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
4046 #define PIXEL_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
4048 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
4049 ICOM_THIS(IDirect3DDevice8Impl,iface);
4050 FIXME("(%p) : stub\n", This);
4053 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
4054 ICOM_THIS(IDirect3DDevice8Impl,iface);
4055 FIXME("(%p) : stub\n", This);
4058 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4059 ICOM_THIS(IDirect3DDevice8Impl,iface);
4060 PIXELSHADER8* object;
4062 object = PIXEL_SHADER(Handle);
4063 if (NULL == object) {
4064 return D3DERR_INVALIDCALL;
4066 if (NULL == pData) {
4067 *pSizeOfData = object->functionLength;
4070 if (*pSizeOfData < object->functionLength) {
4071 *pSizeOfData = object->functionLength;
4072 return D3DERR_MOREDATA;
4074 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
4075 memcpy(pData, object->function, object->functionLength);
4078 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
4079 ICOM_THIS(IDirect3DDevice8Impl,iface);
4080 FIXME("(%p) : stub\n", This); return D3D_OK;
4082 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
4083 ICOM_THIS(IDirect3DDevice8Impl,iface);
4084 FIXME("(%p) : stub\n", This); return D3D_OK;
4086 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
4087 ICOM_THIS(IDirect3DDevice8Impl,iface);
4088 FIXME("(%p) : stub\n", This); return D3D_OK;
4091 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
4092 IDirect3DVertexBuffer8 *oldSrc;
4093 ICOM_THIS(IDirect3DDevice8Impl,iface);
4095 oldSrc = This->StateBlock.stream_source[StreamNumber];
4096 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
4098 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
4099 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
4100 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
4101 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
4103 /* Handle recording of state blocks */
4104 if (This->isRecordingState) {
4105 TRACE("Recording... not performing anything\n");
4109 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
4110 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
4113 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
4114 ICOM_THIS(IDirect3DDevice8Impl,iface);
4115 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock.stream_source[StreamNumber], This->StateBlock.stream_stride[StreamNumber]);
4116 *pStream = This->StateBlock.stream_source[StreamNumber];
4117 *pStride = This->StateBlock.stream_stride[StreamNumber];
4118 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
4123 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
4125 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4126 IDirect3DDevice8Impl_QueryInterface,
4127 IDirect3DDevice8Impl_AddRef,
4128 IDirect3DDevice8Impl_Release,
4129 IDirect3DDevice8Impl_TestCooperativeLevel,
4130 IDirect3DDevice8Impl_GetAvailableTextureMem,
4131 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
4132 IDirect3DDevice8Impl_GetDirect3D,
4133 IDirect3DDevice8Impl_GetDeviceCaps,
4134 IDirect3DDevice8Impl_GetDisplayMode,
4135 IDirect3DDevice8Impl_GetCreationParameters,
4136 IDirect3DDevice8Impl_SetCursorProperties,
4137 IDirect3DDevice8Impl_SetCursorPosition,
4138 IDirect3DDevice8Impl_ShowCursor,
4139 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
4140 IDirect3DDevice8Impl_Reset,
4141 IDirect3DDevice8Impl_Present,
4142 IDirect3DDevice8Impl_GetBackBuffer,
4143 IDirect3DDevice8Impl_GetRasterStatus,
4144 IDirect3DDevice8Impl_SetGammaRamp,
4145 IDirect3DDevice8Impl_GetGammaRamp,
4146 IDirect3DDevice8Impl_CreateTexture,
4147 IDirect3DDevice8Impl_CreateVolumeTexture,
4148 IDirect3DDevice8Impl_CreateCubeTexture,
4149 IDirect3DDevice8Impl_CreateVertexBuffer,
4150 IDirect3DDevice8Impl_CreateIndexBuffer,
4151 IDirect3DDevice8Impl_CreateRenderTarget,
4152 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4153 IDirect3DDevice8Impl_CreateImageSurface,
4154 IDirect3DDevice8Impl_CopyRects,
4155 IDirect3DDevice8Impl_UpdateTexture,
4156 IDirect3DDevice8Impl_GetFrontBuffer,
4157 IDirect3DDevice8Impl_SetRenderTarget,
4158 IDirect3DDevice8Impl_GetRenderTarget,
4159 IDirect3DDevice8Impl_GetDepthStencilSurface,
4160 IDirect3DDevice8Impl_BeginScene,
4161 IDirect3DDevice8Impl_EndScene,
4162 IDirect3DDevice8Impl_Clear,
4163 IDirect3DDevice8Impl_SetTransform,
4164 IDirect3DDevice8Impl_GetTransform,
4165 IDirect3DDevice8Impl_MultiplyTransform,
4166 IDirect3DDevice8Impl_SetViewport,
4167 IDirect3DDevice8Impl_GetViewport,
4168 IDirect3DDevice8Impl_SetMaterial,
4169 IDirect3DDevice8Impl_GetMaterial,
4170 IDirect3DDevice8Impl_SetLight,
4171 IDirect3DDevice8Impl_GetLight,
4172 IDirect3DDevice8Impl_LightEnable,
4173 IDirect3DDevice8Impl_GetLightEnable,
4174 IDirect3DDevice8Impl_SetClipPlane,
4175 IDirect3DDevice8Impl_GetClipPlane,
4176 IDirect3DDevice8Impl_SetRenderState,
4177 IDirect3DDevice8Impl_GetRenderState,
4178 IDirect3DDevice8Impl_BeginStateBlock,
4179 IDirect3DDevice8Impl_EndStateBlock,
4180 IDirect3DDevice8Impl_ApplyStateBlock,
4181 IDirect3DDevice8Impl_CaptureStateBlock,
4182 IDirect3DDevice8Impl_DeleteStateBlock,
4183 IDirect3DDevice8Impl_CreateStateBlock,
4184 IDirect3DDevice8Impl_SetClipStatus,
4185 IDirect3DDevice8Impl_GetClipStatus,
4186 IDirect3DDevice8Impl_GetTexture,
4187 IDirect3DDevice8Impl_SetTexture,
4188 IDirect3DDevice8Impl_GetTextureStageState,
4189 IDirect3DDevice8Impl_SetTextureStageState,
4190 IDirect3DDevice8Impl_ValidateDevice,
4191 IDirect3DDevice8Impl_GetInfo,
4192 IDirect3DDevice8Impl_SetPaletteEntries,
4193 IDirect3DDevice8Impl_GetPaletteEntries,
4194 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4195 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4196 IDirect3DDevice8Impl_DrawPrimitive,
4197 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4198 IDirect3DDevice8Impl_DrawPrimitiveUP,
4199 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4200 IDirect3DDevice8Impl_ProcessVertices,
4201 IDirect3DDevice8Impl_CreateVertexShader,
4202 IDirect3DDevice8Impl_SetVertexShader,
4203 IDirect3DDevice8Impl_GetVertexShader,
4204 IDirect3DDevice8Impl_DeleteVertexShader,
4205 IDirect3DDevice8Impl_SetVertexShaderConstant,
4206 IDirect3DDevice8Impl_GetVertexShaderConstant,
4207 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4208 IDirect3DDevice8Impl_GetVertexShaderFunction,
4209 IDirect3DDevice8Impl_SetStreamSource,
4210 IDirect3DDevice8Impl_GetStreamSource,
4211 IDirect3DDevice8Impl_SetIndices,
4212 IDirect3DDevice8Impl_GetIndices,
4213 IDirect3DDevice8Impl_CreatePixelShader,
4214 IDirect3DDevice8Impl_SetPixelShader,
4215 IDirect3DDevice8Impl_GetPixelShader,
4216 IDirect3DDevice8Impl_DeletePixelShader,
4217 IDirect3DDevice8Impl_SetPixelShaderConstant,
4218 IDirect3DDevice8Impl_GetPixelShaderConstant,
4219 IDirect3DDevice8Impl_GetPixelShaderFunction,
4220 IDirect3DDevice8Impl_DrawRectPatch,
4221 IDirect3DDevice8Impl_DrawTriPatch,
4222 IDirect3DDevice8Impl_DeletePatch
4225 void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
4229 ICOM_THIS(IDirect3DDevice8Impl,iface);
4231 /* Note this may have a large overhead but it should only be executed
4232 once, in order to initialize the complete state of the device and
4233 all opengl equivalents */
4234 TRACE("-----------------------> Setting up device defaults...\n");
4235 This->StateBlock.blockType = D3DSBT_ALL;
4237 /* FIXME: Set some of the defaults for lights, transforms etc */
4238 memcpy(&This->StateBlock.transforms[D3DTS_PROJECTION], &idmatrix, sizeof(idmatrix));
4239 memcpy(&This->StateBlock.transforms[D3DTS_VIEW], &idmatrix, sizeof(idmatrix));
4240 for (i = 0; i < 256; ++i) {
4241 memcpy(&This->StateBlock.transforms[D3DTS_WORLDMATRIX(i)], &idmatrix, sizeof(idmatrix));
4244 /* Render states: */
4245 if (This->PresentParms.EnableAutoDepthStencil) {
4246 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_TRUE );
4248 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZENABLE, D3DZB_FALSE );
4250 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FILLMODE, D3DFILL_SOLID);
4251 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
4252 lp.wRepeatFactor = 0; lp.wLinePattern = 0; IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LINEPATTERN, (DWORD) &lp);
4253 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZWRITEENABLE, TRUE);
4254 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHATESTENABLE, FALSE);
4255 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LASTPIXEL, TRUE);
4256 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SRCBLEND, D3DBLEND_ONE);
4257 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DESTBLEND, D3DBLEND_ZERO);
4258 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CULLMODE, D3DCULL_CCW);
4259 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
4260 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
4261 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHAREF, 0xff); /*??*/
4262 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DITHERENABLE, FALSE);
4263 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ALPHABLENDENABLE, FALSE);
4264 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGENABLE, FALSE);
4265 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARENABLE, FALSE);
4266 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZVISIBLE, 0);
4267 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGCOLOR, 0);
4268 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
4269 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGSTART, 0.0f);
4270 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGEND, 1.0f);
4271 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGDENSITY, 1.0f);
4272 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EDGEANTIALIAS, FALSE);
4273 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_ZBIAS, 0);
4274 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_RANGEFOGENABLE, FALSE);
4275 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILENABLE, FALSE);
4276 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
4277 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
4278 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
4279 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
4280 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILREF, 0);
4281 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILMASK, 0xFFFFFFFF);
4282 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
4283 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
4284 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP0, 0);
4285 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP1, 0);
4286 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP2, 0);
4287 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP3, 0);
4288 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP4, 0);
4289 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP5, 0);
4290 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP6, 0);
4291 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_WRAP7, 0);
4292 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPING, TRUE);
4293 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LIGHTING, TRUE);
4294 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENT, 0);
4295 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
4296 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORVERTEX, TRUE);
4297 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_LOCALVIEWER, TRUE);
4298 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALIZENORMALS, FALSE);
4299 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
4300 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
4301 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
4302 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
4303 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
4304 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_CLIPPLANEENABLE, 0);
4305 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
4306 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE, 1.0f);
4307 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MIN, 0.0f);
4308 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSPRITEENABLE, FALSE);
4309 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALEENABLE, FALSE);
4310 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_A, TRUE);
4311 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_B, TRUE);
4312 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSCALE_C, TRUE);
4313 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
4314 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
4315 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
4316 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_PATCHSEGMENTS, 1.0f);
4317 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
4318 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POINTSIZE_MAX, (DWORD) 64.0f);
4319 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
4320 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_COLORWRITEENABLE, 0x0000000F);
4321 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_TWEENFACTOR, (DWORD) 0.0f);
4322 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_BLENDOP, D3DBLENDOP_ADD);
4323 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
4324 IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
4326 /* Texture Stage States - Put directly into state block, we will call function below */
4327 for (i=0; i<This->TextureUnits;i++) {
4328 memcpy(&This->StateBlock.transforms[D3DTS_TEXTURE0+i], &idmatrix, sizeof(idmatrix));
4329 This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
4330 This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
4331 This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
4332 This->StateBlock.texture_state[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
4333 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
4334 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
4335 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
4336 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
4337 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
4338 This->StateBlock.texture_state[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
4339 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
4340 This->StateBlock.texture_state[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
4341 This->StateBlock.texture_state[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
4342 This->StateBlock.texture_state[i][D3DTSS_BORDERCOLOR ] = 0x00;
4343 This->StateBlock.texture_state[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
4344 This->StateBlock.texture_state[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
4345 This->StateBlock.texture_state[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
4346 This->StateBlock.texture_state[i][D3DTSS_MIPMAPLODBIAS ] = 0;
4347 This->StateBlock.texture_state[i][D3DTSS_MAXMIPLEVEL ] = 0;
4348 This->StateBlock.texture_state[i][D3DTSS_MAXANISOTROPY ] = 1;
4349 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
4350 This->StateBlock.texture_state[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
4351 This->StateBlock.texture_state[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
4352 This->StateBlock.texture_state[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
4353 This->StateBlock.texture_state[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
4354 This->StateBlock.texture_state[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
4355 This->StateBlock.texture_state[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
4358 /* Under DirectX you can have texture stage operations even if no texture is
4359 bound, whereas opengl will only do texture operations when a valid texture is
4360 bound. We emulate this by creating dummy textures and binding them to each
4361 texture stage, but disable all stages by default. Hence if a stage is enabled
4362 then the default texture will kick in until replaced by a SetTexture call */
4364 for (i=0; i<This->TextureUnits; i++) {
4365 GLubyte white = 255;
4367 /* Note this avoids calling settexture, so pretend it has been called */
4368 This->StateBlock.Set.textures[i] = TRUE;
4369 This->StateBlock.Changed.textures[i] = TRUE;
4370 This->StateBlock.textures[i] = NULL;
4372 /* Make appropriate texture active */
4373 if (This->isMultiTexture) {
4374 glActiveTextureARB(GL_TEXTURE0_ARB + i);
4375 checkGLcall("glActiveTextureARB");
4377 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
4380 /* Generate an opengl texture name */
4381 glGenTextures(1, &This->dummyTextureName[i]);
4382 checkGLcall("glGenTextures");
4383 TRACE("Dummy Texture %d given name %d\n", i, This->dummyTextureName[i]);
4385 /* Generate a dummy 1d texture */
4386 This->StateBlock.textureDimensions[i] = GL_TEXTURE_1D;
4387 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
4388 checkGLcall("glBindTexture");
4390 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
4391 checkGLcall("glTexImage1D");
4393 /* Reapply all the texture state information to this texture */
4394 setupTextureStates(iface, i);
4397 TRACE("-----------------------> Device defaults now set up...\n");
4402 DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
4403 D3DRS_ALPHABLENDENABLE ,
4406 D3DRS_ALPHATESTENABLE ,
4408 D3DRS_COLORWRITEENABLE ,
4410 D3DRS_DITHERENABLE ,
4411 D3DRS_EDGEANTIALIAS ,
4420 D3DRS_STENCILENABLE ,
4426 D3DRS_STENCILWRITEMASK ,
4427 D3DRS_STENCILZFAIL ,
4428 D3DRS_TEXTUREFACTOR ,
4443 DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
4451 D3DTSS_BORDERCOLOR ,
4452 D3DTSS_BUMPENVLOFFSET ,
4453 D3DTSS_BUMPENVLSCALE ,
4454 D3DTSS_BUMPENVMAT00 ,
4455 D3DTSS_BUMPENVMAT01 ,
4456 D3DTSS_BUMPENVMAT10 ,
4457 D3DTSS_BUMPENVMAT11 ,
4463 D3DTSS_MAXANISOTROPY ,
4464 D3DTSS_MAXMIPLEVEL ,
4467 D3DTSS_MIPMAPLODBIAS ,
4469 D3DTSS_TEXCOORDINDEX ,
4470 D3DTSS_TEXTURETRANSFORMFLAGS
4473 DWORD SavedVertexStates_R[NUM_SAVEDVERTEXSTATES_R] = {
4475 D3DRS_AMBIENTMATERIALSOURCE ,
4477 D3DRS_CLIPPLANEENABLE ,
4479 D3DRS_DIFFUSEMATERIALSOURCE ,
4480 D3DRS_EMISSIVEMATERIALSOURCE ,
4484 D3DRS_FOGTABLEMODE ,
4485 D3DRS_FOGVERTEXMODE ,
4486 D3DRS_INDEXEDVERTEXBLENDENABLE ,
4489 D3DRS_MULTISAMPLEANTIALIAS ,
4490 D3DRS_MULTISAMPLEMASK ,
4491 D3DRS_NORMALIZENORMALS ,
4492 D3DRS_PATCHEDGESTYLE ,
4493 D3DRS_PATCHSEGMENTS ,
4494 D3DRS_POINTSCALE_A ,
4495 D3DRS_POINTSCALE_B ,
4496 D3DRS_POINTSCALE_C ,
4497 D3DRS_POINTSCALEENABLE ,
4499 D3DRS_POINTSIZE_MAX ,
4500 D3DRS_POINTSIZE_MIN ,
4501 D3DRS_POINTSPRITEENABLE ,
4502 D3DRS_RANGEFOGENABLE ,
4503 D3DRS_SOFTWAREVERTEXPROCESSING ,
4504 D3DRS_SPECULARMATERIALSOURCE ,
4509 DWORD SavedVertexStates_T[NUM_SAVEDVERTEXSTATES_T] = {
4510 D3DTSS_TEXCOORDINDEX ,
4511 D3DTSS_TEXTURETRANSFORMFLAGS