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 /** define GL_GLEXT_PROTOTYPES for having extensions prototypes defined */
34 /*#define GL_GLEXT_PROTOTYPES*/
35 #include "d3d8_private.h"
37 /** currently desactiving 1_4 support as mesa doesn't implement all 1_4 support while defining it */
40 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
42 /* Some #defines for additional diagnostics */
44 /* Per-vertex trace: */
46 # define VTRACE(A) TRACE A
52 static IDirect3DVertexShaderImpl* VertexShaders[64];
53 static IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
54 static IDirect3DPixelShaderImpl* PixelShaders[64];
56 /* CreateVertexShader can return > 0xFFFF */
57 #define VS_HIGHESTFIXEDFXF 0xF0000000
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(IDirect3DVertexShaderImpl*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
73 #define VERTEX_SHADER_DECL(Handle) \
74 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaderDeclarations) / sizeof(IDirect3DVertexShaderDeclarationImpl*)) ? NULL : VertexShaderDeclarations[Handle]) : VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF])
75 #define PIXEL_SHADER(Handle) \
76 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
78 #define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
82 /* Routine common to the draw primitive and draw indexed primitive routines */
83 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
90 const void *vertexBufData,
93 long StartVertexIndex,
99 int NumVertexes = NumPrimitives;
100 IDirect3DVertexShaderImpl* vertex_shader = NULL;
101 BOOL useVertexShaderFunction = FALSE;
103 ICOM_THIS(IDirect3DDevice8Impl,iface);
105 /* Dont understand how to handle multiple streams, but if a fixed
106 FVF is passed in rather than a handle, it must use stream 0 */
108 if (This->UpdateStateBlock->VertexShader > VS_HIGHESTFIXEDFXF) {
109 vertex_shader = VERTEX_SHADER(This->UpdateStateBlock->VertexShader);
110 if (NULL == vertex_shader) {
111 ERR("trying to use unitialised vertex shader: %lu\n", This->UpdateStateBlock->VertexShader);
114 if (NULL == vertex_shader->function) {
115 TRACE("vertex shader declared without program, using FVF pure mode\n");
117 useVertexShaderFunction = TRUE;
119 fvf = (D3DFORMAT) This->UpdateStateBlock->vertexShaderDecl->fvf;
120 TRACE("vertex shader declared FVF: %lx\n", This->UpdateStateBlock->vertexShaderDecl->fvf);
121 memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8));
123 /** init Constants */
124 if (TRUE == This->UpdateStateBlock->Changed.vertexShaderConstant) {
125 TRACE("vertex shader init Constant\n");
126 IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96);
132 int skip = This->StateBlock->stream_stride[0];
133 GLenum primType = GL_POINTS;
143 const char *curVtx = NULL;
144 const short *pIdxBufS = NULL;
145 const long *pIdxBufL = NULL;
147 BOOL isLightingOn = FALSE;
148 BOOL enableTexture = FALSE;
153 z = 0.0f; /* x,y,z coordinates */
156 nz = 0.0f; /* normal x,y,z coordinates */
157 float rhw = 0.0f; /* rhw */
158 float ptSize = 0.0f; /* Point size */
159 DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
160 DWORD specularColor = 0; /* Specular Color */
165 if (idxBytes == 2) pIdxBufS = (short *) idxData;
166 else pIdxBufL = (long *) idxData;
169 /* Check vertex formats expected ? */
171 * FVF parser as seen it
172 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/Reference/CPP/D3D/FlexibleVertexFormatFlags.asp
174 normal = fvf & D3DFVF_NORMAL;
175 isRHW = fvf & D3DFVF_XYZRHW;
176 isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
177 numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2 + ((FALSE == isLastUByte4) ? 0 : -1); /* WARNING can be < 0 because -2 */
178 isPtSize = fvf & D3DFVF_PSIZE;
179 isDiffuse = fvf & D3DFVF_DIFFUSE;
180 isSpecular = fvf & D3DFVF_SPECULAR;
181 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
183 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d)\n",
184 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends);
186 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
187 set by the appropriate render state */
189 isLightingOn = glIsEnabled(GL_LIGHTING);
190 glDisable(GL_LIGHTING);
191 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
195 double height, width, minZ, maxZ;
197 * Already transformed vertex do not need transform
198 * matrices. Reset all matrices to identity.
199 * Leave the default matrix in world mode.
201 glMatrixMode(GL_PROJECTION);
202 checkGLcall("glMatrixMode");
204 checkGLcall("glLoadIdentity");
205 glMatrixMode(GL_MODELVIEW);
206 checkGLcall("glMatrixMode");
208 checkGLcall("glLoadIdentity");
209 height = This->StateBlock->viewport.Height;
210 width = This->StateBlock->viewport.Width;
211 minZ = This->StateBlock->viewport.MinZ;
212 maxZ = This->StateBlock->viewport.MaxZ;
213 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
214 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
215 checkGLcall("glOrtho");
217 glMatrixMode(GL_PROJECTION);
218 checkGLcall("glMatrixMode");
219 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
220 checkGLcall("glLoadMatrixf");
221 glMatrixMode(GL_MODELVIEW);
222 checkGLcall("glMatrixMode");
223 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
224 checkGLcall("glLoadMatrixf");
225 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
226 checkGLcall("glMultMatrixf");
229 /* Set OpenGL to the appropriate Primitive Type */
230 switch (PrimitiveType) {
231 case D3DPT_POINTLIST:
233 primType = GL_POINTS;
234 NumVertexes = NumPrimitives;
240 NumVertexes = NumPrimitives * 2;
243 case D3DPT_LINESTRIP:
244 TRACE("LINE_STRIP\n");
245 primType = GL_LINE_STRIP;
246 NumVertexes = NumPrimitives + 1;
249 case D3DPT_TRIANGLELIST:
250 TRACE("TRIANGLES\n");
251 primType = GL_TRIANGLES;
252 NumVertexes = NumPrimitives * 3;
255 case D3DPT_TRIANGLESTRIP:
256 TRACE("TRIANGLE_STRIP\n");
257 primType = GL_TRIANGLE_STRIP;
258 NumVertexes = NumPrimitives + 2;
261 case D3DPT_TRIANGLEFAN:
262 TRACE("TRIANGLE_FAN\n");
263 primType = GL_TRIANGLE_FAN;
264 NumVertexes = NumPrimitives + 2;
268 FIXME("Unhandled primitive\n");
272 /* Fixme, Ideally, only use this per-vertex code for software HAL
273 but until opengl supports all the functions returned to setup
274 vertex arrays, we need to drop down to the slow mechanism for
277 if (isPtSize || isDiffuse || useVertexShaderFunction==TRUE || (numBlends > 0)) {
278 TRACE("Using slow per-vertex code\n");
280 /* Enable this one to be able to debug what is going on, but it is slower
281 than the pointer/array version */
282 VTRACE(("glBegin(%x)\n", primType));
285 /* Draw the primitives */
286 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
288 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
294 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
295 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
297 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
298 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
302 /* Work through the vertex buffer */
303 x = *(float *)curPos;
304 curPos = curPos + sizeof(float);
305 y = *(float *)curPos;
306 curPos = curPos + sizeof(float);
307 z = *(float *)curPos;
308 curPos = curPos + sizeof(float);
309 VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
311 /* RHW follows, only if transformed */
313 rhw = *(float *)curPos;
314 curPos = curPos + sizeof(float);
315 VTRACE(("rhw=%f\n", rhw));
321 D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
322 DWORD skippedBlendLastUByte4 = 0;
324 for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
325 ((float*)&skippedBlend)[i] = *(float *)curPos;
326 curPos = curPos + sizeof(float);
330 skippedBlendLastUByte4 = *(DWORD*)curPos;
331 curPos = curPos + sizeof(DWORD);
335 /* Vertex Normal Data (untransformed only) */
337 nx = *(float *)curPos;
338 curPos = curPos + sizeof(float);
339 ny = *(float *)curPos;
340 curPos = curPos + sizeof(float);
341 nz = *(float *)curPos;
342 curPos = curPos + sizeof(float);
343 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
347 ptSize = *(float *)curPos;
348 VTRACE(("ptSize=%f\n", ptSize));
349 curPos = curPos + sizeof(float);
353 diffuseColor = *(DWORD *)curPos;
354 VTRACE(("diffuseColor=%lx\n", diffuseColor));
355 curPos = curPos + sizeof(DWORD);
359 specularColor = *(DWORD *)curPos;
360 VTRACE(("specularColor=%lx\n", specularColor));
361 curPos = curPos + sizeof(DWORD);
364 /* ToDo: Texture coords */
365 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
368 if (!(This->isMultiTexture) && textureNo > 0) {
369 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
372 if (textureNo > This->TextureUnits) {
373 FIXME("Program using more concurrent textures than this opengl implementation support\n");
377 /* Query tex coords */
378 if (This->StateBlock->textures[textureNo] != NULL) {
379 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
380 case D3DRTYPE_TEXTURE:
381 s = *(float *)curPos;
382 curPos = curPos + sizeof(float);
383 t = *(float *)curPos;
384 curPos = curPos + sizeof(float);
385 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s,t));
387 if (TRUE == useVertexShaderFunction) {
390 if (This->isMultiTexture) {
391 #if defined(GL_VERSION_1_3)
392 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
394 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
402 case D3DRTYPE_VOLUMETEXTURE:
403 s = *(float *)curPos;
404 curPos = curPos + sizeof(float);
405 t = *(float *)curPos;
406 curPos = curPos + sizeof(float);
407 r = *(float *)curPos;
408 curPos = curPos + sizeof(float);
409 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r));
411 if (TRUE == useVertexShaderFunction) {
414 if (This->isMultiTexture) {
415 #if defined(GL_VERSION_1_3)
416 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
418 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
422 glTexCoord3f(s, t, r);
428 r = 0.0f; q = 0.0f; /* Avoid compiler warnings, need these vars later for other textures */
429 FIXME("Unhandled texture type\n");
432 /* Note I have seen a program actually do this, so just hide it and continue */
433 VTRACE(("Very odd - texture requested in FVF but not bound!\n"));
438 /** if vertex shader program specified ... using it */
439 if (TRUE == useVertexShaderFunction) {
442 * this code must become the really
443 * vs input params init
445 * because its possible to use input registers for anything
446 * and some samples use registers for other things than they are
451 * no really valid declaration, user defined input register use
452 * so fill input registers as described in vertex shader declaration
454 IDirect3DDeviceImpl_FillVertexShaderInput(This, vertex_shader, vertexBufData, StartVertexIndex,
455 (!isIndexed) ? (vx_index * skip) :
456 (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) :
457 ((pIdxBufL[StartIdx + vx_index]) * skip));
459 memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
460 IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
462 TRACE_VECTOR(vertex_shader->output.oPos);
463 TRACE_VECTOR(vertex_shader->output.oD[0]);
464 TRACE_VECTOR(vertex_shader->output.oD[1]);
465 TRACE_VECTOR(vertex_shader->output.oT[0]);
466 TRACE_VECTOR(vertex_shader->output.oT[1]);
467 TRACE_VECTOR(vertex_shader->input.V[0]);
468 TRACE_VECTOR(vertex_shader->data->C[0]);
469 TRACE_VECTOR(vertex_shader->data->C[1]);
470 TRACE_VECTOR(vertex_shader->data->C[2]);
471 TRACE_VECTOR(vertex_shader->data->C[3]);
472 TRACE_VECTOR(vertex_shader->data->C[4]);
473 TRACE_VECTOR(vertex_shader->data->C[5]);
474 TRACE_VECTOR(vertex_shader->data->C[6]);
475 TRACE_VECTOR(vertex_shader->data->C[7]);
477 x = vertex_shader->output.oPos.x;
478 y = vertex_shader->output.oPos.y;
479 z = vertex_shader->output.oPos.z;
481 if (1.0f != vertex_shader->output.oPos.w || isRHW) {
482 rhw = vertex_shader->output.oPos.w;
484 /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
485 glColor4fv((float*) &vertex_shader->output.oD[0]);
487 /* Requires secondary color extensions to compile... */
488 #if defined(GL_VERSION_1_4)
489 glSecondaryColor3fv((float*) &vertex_shader->output.oD[1]);
490 checkGLcall("glSecondaryColor3fv");
492 if (checkGLSupport(EXT_SECONDARY_COLOR)) {
493 /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/
494 /*GLExtCall(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]);*/
495 /*checkGLcall("glSecondaryColor3fvEXT");*/
498 /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
499 for (textureNo = 0; textureNo < 4; ++textureNo) {
502 if (!(This->isMultiTexture) && textureNo > 0) {
503 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
506 /* Query tex coords */
507 if (This->StateBlock->textures[textureNo] != NULL) {
508 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
509 case D3DRTYPE_TEXTURE:
510 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
511 s = vertex_shader->output.oT[textureNo].x;
512 t = vertex_shader->output.oT[textureNo].y;
513 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t));
514 if (This->isMultiTexture) {
515 #if defined(GL_VERSION_1_3)
516 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
518 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
520 /*checkGLcall("glMultiTexCoord2fARB");*/
523 /*checkGLcall("gTexCoord2f");*/
527 case D3DRTYPE_VOLUMETEXTURE:
528 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
529 s = vertex_shader->output.oT[textureNo].x;
530 t = vertex_shader->output.oT[textureNo].y;
531 r = vertex_shader->output.oT[textureNo].z;
532 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r));
533 if (This->isMultiTexture) {
534 #if defined(GL_VERSION_1_3)
535 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
537 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
539 /*checkGLcall("glMultiTexCoord2fARB");*/
541 glTexCoord3f(s, t, r);
542 /*checkGLcall("gTexCoord3f");*/
547 /* Avoid compiler warnings, need these vars later for other textures */
549 FIXME("Unhandled texture type\n");
554 if (1.0f == rhw || rhw < 0.01f) {
555 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
557 /*checkGLcall("glVertex3f");*/
559 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
560 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
561 /*checkGLcall("glVertex4f");*/
565 * FALSE == useVertexShaderFunction
569 /* Handle these vertexes */
571 glColor4ub((diffuseColor >> 16) & 0xFF,
572 (diffuseColor >> 8) & 0xFF,
573 (diffuseColor >> 0) & 0xFF,
574 (diffuseColor >> 24) & 0xFF);
575 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
576 ((diffuseColor >> 16) & 0xFF) / 255.0f,
577 ((diffuseColor >> 8) & 0xFF) / 255.0f,
578 ((diffuseColor >> 0) & 0xFF) / 255.0f,
579 ((diffuseColor >> 24) & 0xFF) / 255.0f));
583 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
584 glNormal3f(nx, ny, nz);
587 if (1.0f == rhw || rhw < 0.01f) {
588 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
591 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
592 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
598 curVtx = curVtx + skip;
603 checkGLcall("glEnd and previous calls");
606 TRACE("Using fast vertex array code\n");
608 /* Faster version, harder to debug */
609 /* Shuffle to the beginning of the vertexes to render and index from there */
610 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
613 /* Set up the vertex pointers */
615 glVertexPointer(4, GL_FLOAT, skip, curPos);
616 checkGLcall("glVertexPointer(4, ...)");
617 curPos += 4 * sizeof(float);
619 glVertexPointer(3, GL_FLOAT, skip, curPos);
620 checkGLcall("glVertexPointer(3, ...)");
621 curPos += 3 * sizeof(float);
623 glEnableClientState(GL_VERTEX_ARRAY);
624 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
627 /* no such functionality in the fixed function GL pipeline */
628 /* FIXME: Wont get here as will drop to slow method */
629 /* FIXME("Cannot handle blending data here in openGl\n");*/
630 if (checkGLSupport(ARB_VERTEX_BLEND)) {
632 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
635 GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
636 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
637 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
638 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
640 curPos += numBlends * sizeof(float);
642 FIXME("unsupported blending in openGl\n");
645 if (checkGLSupport(ARB_VERTEX_BLEND)) {
647 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
650 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
651 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
658 glNormalPointer(GL_FLOAT, skip, curPos);
659 checkGLcall("glNormalPointer");
660 glEnableClientState(GL_NORMAL_ARRAY);
661 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
662 curPos += 3 * sizeof(float);
664 glDisableClientState(GL_NORMAL_ARRAY);
665 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
667 checkGLcall("glNormal3f(0, 0, 1)");
671 /* no such functionality in the fixed function GL pipeline */
672 /* FIXME: Wont get here as will drop to slow method */
673 FIXME("Cannot change ptSize here in openGl\n");
674 curPos = curPos + sizeof(float);
678 glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
679 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
680 glEnableClientState(GL_COLOR_ARRAY);
681 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
682 curPos += sizeof(DWORD);
685 glDisableClientState(GL_COLOR_ARRAY);
686 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
687 glColor4f(1, 1, 1, 1);
688 checkGLcall("glColor4f(1, 1, 1, 1)");
691 /* Requires secondary color extensions to compile... */
693 #if defined(GL_VERSION_1_4)
694 glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
695 checkGLcall("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos)");
696 glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
697 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY)");
700 /* FIXME: check for GL_EXT_secondary_color */
701 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos);
702 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
703 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
704 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
707 curPos += sizeof(DWORD);
709 #if defined(GL_VERSION_1_4)
710 glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
711 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY)");
712 glSecondaryColor3f(0, 0, 0);
713 checkGLcall("glSecondaryColor3f(0, 0, 0)");
716 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
717 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
718 glSecondaryColor3fEXT(0, 0, 0);
719 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
725 /* ToDo: Texture coords */
726 for (textureNo = 0;textureNo<numTextures; textureNo++) {
728 /* Query tex coords */
729 #if defined(GL_VERSION_1_3)
730 glClientActiveTexture(GL_TEXTURE0 + textureNo);
732 glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
734 if (This->StateBlock->textures[textureNo] != NULL) {
735 enableTexture = TRUE;
736 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
737 case D3DRTYPE_TEXTURE:
738 glTexCoordPointer(2, GL_FLOAT, skip, curPos);
739 checkGLcall("glTexCoordPointer(2, ...)");
740 curPos += 2*sizeof(float);
741 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
742 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
745 case D3DRTYPE_VOLUMETEXTURE:
746 glTexCoordPointer(3, GL_FLOAT, skip, curPos);
747 checkGLcall("glTexCoordPointer(3, ...)");
748 curPos += 3*sizeof(float);
749 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
750 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
754 FIXME("Unhandled texture type\n");
755 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
756 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
761 /* Note I have seen a program actually do this, so just hide it and continue */
762 TRACE("Very odd - texture requested in FVF but not bound!\n");
763 #if defined(GL_VERSION_1_3)
764 glMultiTexCoord4f(GL_TEXTURE0 + textureNo, 0, 0, 0, 1);
765 checkGLcall("glMultiTexCoord4f(... , 0, 0, 0, 1)");
766 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
767 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
769 glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1);
770 checkGLcall("glMultiTexCoord4fARB(... , 0, 0, 0, 1)");
771 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
772 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
778 /* Finally do the drawing */
781 TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
783 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
784 glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT,
785 (char *)idxData+(2 * StartIdx));
787 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
788 GL_UNSIGNED_SHORT, (char *)idxData+(2 * StartIdx));
791 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
792 glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT,
793 (char *)idxData+(4 * StartIdx));
795 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
796 GL_UNSIGNED_INT, (char *)idxData+(2 * StartIdx));
799 checkGLcall("glDrawRangeElements");
803 /* Note first is now zero as we shuffled along earlier */
804 TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
805 glDrawArrays(primType, 0, NumVertexes);
806 checkGLcall("glDrawArrays");
811 /* If no normals, restore previous lighting state */
813 if (isLightingOn) glEnable(GL_LIGHTING);
814 else glDisable(GL_LIGHTING);
815 TRACE("Restored lighting to original state\n");
825 Simple utility routines used for dx -> gl mapping of byte formats
827 SHORT bytesPerPixel(D3DFORMAT fmt) {
832 case D3DFMT_A4R4G4B4: retVal = 2; break;
833 case D3DFMT_A8R8G8B8: retVal = 4; break;
834 case D3DFMT_X8R8G8B8: retVal = 4; break;
835 case D3DFMT_R8G8B8: retVal = 3; break;
836 case D3DFMT_R5G6B5: retVal = 2; break;
837 case D3DFMT_A1R5G5B5: retVal = 2; break;
838 /* depth/stencil buffer */
839 case D3DFMT_D16_LOCKABLE: retVal = 2; break;
840 case D3DFMT_D32: retVal = 4; break;
841 case D3DFMT_D15S1: retVal = 2; break;
842 case D3DFMT_D24S8: retVal = 4; break;
843 case D3DFMT_D16: retVal = 2; break;
844 case D3DFMT_D24X8: retVal = 4; break;
845 case D3DFMT_D24X4S4: retVal = 4; break;
848 /* Guess at the highest value of the above */
849 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt);
853 FIXME("Unhandled fmt %d\n", fmt);
856 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
860 GLint fmt2glintFmt(D3DFORMAT fmt) {
864 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
865 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
866 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
867 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
868 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
869 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
871 FIXME("Unhandled fmt %d\n", fmt);
874 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
877 GLenum fmt2glFmt(D3DFORMAT fmt) {
881 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
882 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
883 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
884 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
885 case D3DFMT_R5G6B5: retVal = GL_BGR; break;
886 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
888 FIXME("Unhandled fmt %d\n", fmt);
891 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
894 DWORD fmt2glType(D3DFORMAT fmt) {
898 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
899 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
900 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
901 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
902 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
903 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
905 FIXME("Unhandled fmt %d\n", fmt);
908 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
912 int SOURCEx_RGB_EXT(DWORD arg) {
914 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
915 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
916 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
917 case D3DTSS_ALPHAARG0:
918 case D3DTSS_ALPHAARG1:
919 case D3DTSS_ALPHAARG2:
921 FIXME("Invalid arg %ld\n", arg);
922 return GL_SOURCE0_RGB_EXT;
925 int OPERANDx_RGB_EXT(DWORD arg) {
927 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
928 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
929 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
930 case D3DTSS_ALPHAARG0:
931 case D3DTSS_ALPHAARG1:
932 case D3DTSS_ALPHAARG2:
934 FIXME("Invalid arg %ld\n", arg);
935 return GL_OPERAND0_RGB_EXT;
938 int SOURCEx_ALPHA_EXT(DWORD arg) {
940 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
941 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
942 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
943 case D3DTSS_COLORARG0:
944 case D3DTSS_COLORARG1:
945 case D3DTSS_COLORARG2:
947 FIXME("Invalid arg %ld\n", arg);
948 return GL_SOURCE0_ALPHA_EXT;
951 int OPERANDx_ALPHA_EXT(DWORD arg) {
953 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
954 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
955 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
956 case D3DTSS_COLORARG0:
957 case D3DTSS_COLORARG1:
958 case D3DTSS_COLORARG2:
960 FIXME("Invalid arg %ld\n", arg);
961 return GL_OPERAND0_ALPHA_EXT;
964 GLenum StencilOp(DWORD op) {
966 case D3DSTENCILOP_KEEP : return GL_KEEP;
967 case D3DSTENCILOP_ZERO : return GL_ZERO;
968 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
969 case D3DSTENCILOP_INCRSAT : return GL_INCR;
970 case D3DSTENCILOP_DECRSAT : return GL_DECR;
971 case D3DSTENCILOP_INVERT : return GL_INVERT;
972 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op %ld\n", op);
973 return GL_INCR; /* Fixme - needs to support wrap */
974 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op %ld\n", op);
975 return GL_DECR; /* Fixme - needs to support wrap */
977 FIXME("Invalid stencil op %ld\n", op);
982 /* Apply the current values to the specified texture stage */
983 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
984 ICOM_THIS(IDirect3DDevice8Impl,iface);
988 /* Make appropriate texture active */
989 if (This->isMultiTexture) {
990 #if defined(GL_VERSION_1_3)
991 glActiveTexture(GL_TEXTURE0 + Stage);
993 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
995 checkGLcall("glActiveTextureARB");
996 } else if (Stage > 0) {
997 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
1000 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
1001 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
1002 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
1005 /* Note the D3DRS value applies to all textures, but GL has one
1006 per texture, so apply it now ready to be used! */
1007 col[0] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
1008 col[1] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
1009 col[2] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
1010 col[3] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
1011 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1012 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1014 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
1017 /* IDirect3D IUnknown parts follow: */
1018 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
1020 ICOM_THIS(IDirect3DDevice8Impl,iface);
1022 if (IsEqualGUID(riid, &IID_IUnknown)
1023 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
1024 IDirect3DDevice8Impl_AddRef(iface);
1029 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
1030 return E_NOINTERFACE;
1033 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
1034 ICOM_THIS(IDirect3DDevice8Impl,iface);
1035 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
1036 return ++(This->ref);
1039 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
1040 ICOM_THIS(IDirect3DDevice8Impl,iface);
1041 ULONG ref = --This->ref;
1042 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
1044 HeapFree(GetProcessHeap(), 0, This);
1049 /* IDirect3DDevice Interface follow: */
1050 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
1051 ICOM_THIS(IDirect3DDevice8Impl,iface);
1052 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
1056 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
1057 ICOM_THIS(IDirect3DDevice8Impl,iface);
1058 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
1060 * pretend we have 32MB of any type of memory queried.
1062 return (1024*1024*32);
1065 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
1066 ICOM_THIS(IDirect3DDevice8Impl,iface);
1067 FIXME("(%p) : stub\n", This); return D3D_OK;
1069 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
1070 ICOM_THIS(IDirect3DDevice8Impl,iface);
1071 TRACE("(%p) : returning %p\n", This, This->direct3d8);
1074 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
1076 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
1079 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
1080 ICOM_THIS(IDirect3DDevice8Impl,iface);
1081 FIXME("(%p) : stub, calling idirect3d for now\n", This);
1082 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
1085 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
1090 ICOM_THIS(IDirect3DDevice8Impl,iface);
1091 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
1092 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
1093 pMode->RefreshRate = 85; /*FIXME: How to identify? */
1095 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1096 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1100 case 8: pMode->Format = D3DFMT_R8G8B8; break;
1101 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1102 case 24: pMode->Format = D3DFMT_R8G8B8; break;
1103 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1105 FIXME("Unrecognized display mode format\n");
1106 pMode->Format = D3DFMT_UNKNOWN;
1109 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
1112 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1113 ICOM_THIS(IDirect3DDevice8Impl,iface);
1114 TRACE("(%p) copying to %p\n", This, pParameters);
1115 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1118 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1119 ICOM_THIS(IDirect3DDevice8Impl,iface);
1120 FIXME("(%p) : stub\n", This); return D3D_OK;
1122 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1123 ICOM_THIS(IDirect3DDevice8Impl,iface);
1124 FIXME("(%p) : stub\n", This); return;
1126 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1127 ICOM_THIS(IDirect3DDevice8Impl,iface);
1128 FIXME("(%p) : stub\n", This); return D3D_OK;
1130 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1131 ICOM_THIS(IDirect3DDevice8Impl,iface);
1132 FIXME("(%p) : stub\n", This); return D3D_OK;
1134 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1135 ICOM_THIS(IDirect3DDevice8Impl,iface);
1136 FIXME("(%p) : stub\n", This); return D3D_OK;
1138 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1139 ICOM_THIS(IDirect3DDevice8Impl,iface);
1140 TRACE("(%p) : complete stub!\n", This);
1144 glXSwapBuffers(This->display, This->win);
1145 checkGLcall("glXSwapBuffers");
1151 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
1152 ICOM_THIS(IDirect3DDevice8Impl,iface);
1153 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1154 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1156 /* Note inc ref on returned surface */
1157 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1161 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1162 ICOM_THIS(IDirect3DDevice8Impl,iface);
1163 FIXME("(%p) : stub\n", This); return D3D_OK;
1165 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1166 ICOM_THIS(IDirect3DDevice8Impl,iface);
1167 FIXME("(%p) : stub\n", This); return;
1169 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1170 ICOM_THIS(IDirect3DDevice8Impl,iface);
1171 FIXME("(%p) : stub\n", This); return;
1173 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1174 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1175 IDirect3DTexture8Impl *object;
1180 ICOM_THIS(IDirect3DDevice8Impl,iface);
1182 /* Allocate the storage for the device */
1183 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
1184 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1185 object->lpVtbl = &Direct3DTexture8_Vtbl;
1186 object->Device = This; /* FIXME: AddRef(This) */
1187 object->ResourceType = D3DRTYPE_TEXTURE;
1189 object->width = Width;
1190 object->height = Height;
1191 object->levels = Levels;
1192 object->usage = Usage;
1193 object->format = Format;
1194 object->device = This;
1196 /* Calculate levels for mip mapping */
1201 while (tmpW > 1 && tmpH > 1) {
1202 tmpW = max(1,tmpW / 2);
1203 tmpH = max(1, tmpH / 2);
1206 TRACE("Calculated levels = %d\n", object->levels);
1209 /* Generate all the surfaces */
1212 for (i=0; i<object->levels; i++)
1214 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1215 object->surfaces[i]->Container = (IUnknown*) object; /* FIXME: AddRef(object) */
1216 object->surfaces[i]->myDesc.Usage = Usage;
1217 object->surfaces[i]->myDesc.Pool = Pool ;
1219 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1220 tmpW = max(1, tmpW / 2);
1221 tmpH = max(1, tmpH / 2);
1224 *ppTexture = (LPDIRECT3DTEXTURE8)object;
1227 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1229 IDirect3DVolumeTexture8Impl *object;
1235 ICOM_THIS(IDirect3DDevice8Impl,iface);
1237 /* Allocate the storage for it */
1238 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);
1239 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1240 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1241 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1245 object->width = Width;
1246 object->height = Height;
1247 object->depth = Depth;
1248 object->levels = Levels;
1249 object->usage = Usage;
1250 object->format = Format;
1251 object->device = This;
1253 /* Calculate levels for mip mapping */
1259 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1260 tmpW = max(1,tmpW / 2);
1261 tmpH = max(1, tmpH / 2);
1262 tmpD = max(1, tmpD / 2);
1265 TRACE("Calculated levels = %d\n", object->levels);
1268 /* Generate all the surfaces */
1273 for (i=0; i<object->levels; i++)
1275 IDirect3DVolume8Impl *volume;
1277 /* Create the volume - No entry point for this seperately?? */
1278 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1279 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1281 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1282 volume->Device = This; /* FIXME: AddRef(This) */
1283 volume->ResourceType = D3DRTYPE_VOLUME;
1284 volume->Container = object;
1287 volume->myDesc.Width = Width;
1288 volume->myDesc.Height= Height;
1289 volume->myDesc.Depth = Depth;
1290 volume->myDesc.Format= Format;
1291 volume->myDesc.Type = D3DRTYPE_VOLUME;
1292 volume->myDesc.Pool = Pool;
1293 volume->myDesc.Usage = Usage;
1294 volume->bytesPerPixel = bytesPerPixel(Format);
1295 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1296 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1298 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
1299 volume, volume->allocatedMemory, volume->myDesc.Size);
1301 tmpW = max(1,tmpW / 2);
1302 tmpH = max(1, tmpH / 2);
1303 tmpD = max(1, tmpD / 2);
1306 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
1309 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
1311 IDirect3DCubeTexture8Impl *object;
1312 ICOM_THIS(IDirect3DDevice8Impl,iface);
1316 /* Allocate the storage for it */
1317 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
1318 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1319 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1321 object->Device = This; /* FIXME: AddRef(This) */
1322 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1324 object->edgeLength = EdgeLength;
1325 object->levels = Levels;
1326 object->usage = Usage;
1327 object->format = Format;
1328 object->device = This;
1330 /* Calculate levels for mip mapping */
1335 tmpW = max(1,tmpW / 2);
1338 TRACE("Calculated levels = %d\n", object->levels);
1341 /* Generate all the surfaces */
1343 for (i=0; i<object->levels; i++)
1345 /* Create the 6 faces */
1347 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1348 object->surfaces[j][i]->Container = (IUnknown*) object;
1349 object->surfaces[j][i]->myDesc.Usage = Usage;
1350 object->surfaces[j][i]->myDesc.Pool = Pool ;
1352 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1353 tmpW = max(1,tmpW / 2);
1357 TRACE("(%p) : Iface@%p\n", This, object);
1358 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1361 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage,
1362 DWORD FVF,D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1363 IDirect3DVertexBuffer8Impl *object;
1365 ICOM_THIS(IDirect3DDevice8Impl,iface);
1367 /* Allocate the storage for the device */
1368 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1369 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1370 object->Device = This;
1371 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1373 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1374 object->currentDesc.Usage = Usage;
1375 object->currentDesc.Pool = Pool;
1376 object->currentDesc.FVF = FVF;
1377 object->currentDesc.Size = Size;
1379 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1381 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1385 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
1387 IDirect3DIndexBuffer8Impl *object;
1389 ICOM_THIS(IDirect3DDevice8Impl,iface);
1390 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
1392 /* Allocate the storage for the device */
1393 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1394 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1396 object->Device = This;
1397 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1399 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1400 object->currentDesc.Usage = Usage;
1401 object->currentDesc.Pool = Pool;
1402 object->currentDesc.Format = Format;
1403 object->currentDesc.Size = Length;
1405 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1407 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1409 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1413 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
1414 ICOM_THIS(IDirect3DDevice8Impl,iface);
1415 /* up ref count on surface, surface->container = This */
1416 FIXME("(%p) : stub\n", This); return D3D_OK;
1418 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
1419 ICOM_THIS(IDirect3DDevice8Impl,iface);
1420 /* surface->container = This */
1421 FIXME("(%p) : stub\n", This); return D3D_OK;
1423 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
1424 IDirect3DSurface8Impl *object;
1426 ICOM_THIS(IDirect3DDevice8Impl,iface);
1428 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1429 *ppSurface = (LPDIRECT3DSURFACE8) object;
1430 object->lpVtbl = &Direct3DSurface8_Vtbl;
1431 object->Device = This;
1432 object->ResourceType = D3DRTYPE_SURFACE;
1433 object->Container = (IUnknown*) This;
1436 object->myDesc.Width = Width;
1437 object->myDesc.Height= Height;
1438 object->myDesc.Format= Format;
1439 object->myDesc.Type = D3DRTYPE_SURFACE;
1440 /*object->myDesc.Usage */
1441 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
1442 object->bytesPerPixel = bytesPerPixel(Format);
1443 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1444 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1446 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);
1449 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1450 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1452 HRESULT rc = D3D_OK;
1453 IDirect3DBaseTexture8* texture = NULL;
1456 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
1457 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1459 ICOM_THIS(IDirect3DDevice8Impl,iface);
1460 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1461 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1463 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1464 a sample and doesnt seem to break anything as far as I can tell */
1465 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1466 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1467 rc = D3DERR_INVALIDCALL;
1469 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1470 TRACE("Converting dest to same format as source, since dest was unknown\n");
1471 dst->myDesc.Format = src->myDesc.Format;
1473 /* Convert container as well */
1474 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1475 if (texture != NULL) {
1477 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1478 case D3DRTYPE_TEXTURE:
1479 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1481 case D3DRTYPE_VOLUMETEXTURE:
1482 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1484 case D3DRTYPE_CUBETEXTURE:
1485 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1488 FIXME("Unhandled texture type\n");
1491 /** Releasing texture after GetContainer */
1492 IDirect3DBaseTexture8_Release(texture);
1496 /* Quick if complete copy ... */
1497 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1498 src->myDesc.Width == dst->myDesc.Width &&
1499 src->myDesc.Height == dst->myDesc.Height)) {
1500 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1501 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1505 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1506 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1507 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1509 char *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1510 char *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1512 /* Copy rect by rect */
1513 for (i=0; i<cRects; i++) {
1514 CONST RECT *r = &pSourceRectsArray[i];
1515 CONST POINT *p = &pDestPointsArray[i];
1518 int copyperline = (r->right - r->left) * bytesPerPixel;
1521 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top,
1522 r->right, r->bottom, p->x, p->y);
1524 /* Find where to start */
1525 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1526 to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel);
1528 /* Copy line by line */
1529 for (j=0; j<(r->bottom - r->top); j++) {
1530 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1537 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1538 if (texture != NULL) {
1540 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1541 case D3DRTYPE_TEXTURE:
1543 IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)texture;
1544 pTexture->Dirty = TRUE;
1547 case D3DRTYPE_VOLUMETEXTURE:
1549 IDirect3DVolumeTexture8Impl *pTexture = (IDirect3DVolumeTexture8Impl *)texture;
1550 pTexture->Dirty = TRUE;
1553 case D3DRTYPE_CUBETEXTURE:
1555 IDirect3DCubeTexture8Impl *pTexture = (IDirect3DCubeTexture8Impl *)texture;
1556 pTexture->Dirty = TRUE;
1560 FIXME("Unhandled texture type\n");
1563 /** Releasing texture after GetContainer */
1564 IDirect3DBaseTexture8_Release(texture);
1570 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1571 ICOM_THIS(IDirect3DDevice8Impl,iface);
1572 FIXME("(%p) : stub\n", This); return D3D_OK;
1574 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1575 ICOM_THIS(IDirect3DDevice8Impl,iface);
1576 FIXME("(%p) : stub\n", This); return D3D_OK;
1578 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1579 ICOM_THIS(IDirect3DDevice8Impl,iface);
1580 FIXME("(%p) : stub\n", This);
1584 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1585 ICOM_THIS(IDirect3DDevice8Impl,iface);
1586 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1587 FIXME("(%p) : stub\n", This);
1590 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1591 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1596 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1598 ICOM_THIS(IDirect3DDevice8Impl,iface);
1600 TRACE("(%p)->(%p)\n", This, ppZStencilSurface);
1602 /* Note inc ref on returned surface */
1603 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8)This->depthStencilBuffer);
1604 *ppZStencilSurface = (LPDIRECT3DSURFACE8)This->depthStencilBuffer;
1609 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1610 ICOM_THIS(IDirect3DDevice8Impl,iface);
1611 TRACE("(%p) : stub\n", This);
1614 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1615 ICOM_THIS(IDirect3DDevice8Impl,iface);
1616 TRACE("(%p)\n", This);
1621 checkGLcall("glFlush");
1623 /* Useful for debugging sometimes!
1624 printf("Hit Enter ...\n");
1630 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1631 ICOM_THIS(IDirect3DDevice8Impl,iface);
1633 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1634 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1635 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1636 GLbitfield glMask = 0;
1638 CONST D3DRECT *curRect;
1640 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1641 Count, pRects, Flags, Z, Stencil);
1644 if (Count > 0 && pRects) {
1645 glEnable(GL_SCISSOR_TEST);
1646 checkGLcall("glEnable GL_SCISSOR_TEST");
1652 for (i=0;i<Count || i==0; i++) {
1655 /* Note gl uses lower left, width/height */
1656 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1657 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1658 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1659 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1660 checkGLcall("glScissor");
1663 /* Clear the whole screen */
1664 if (Flags & D3DCLEAR_STENCIL) {
1665 glClearStencil(Stencil);
1666 checkGLcall("glClearStencil");
1667 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1670 if (Flags & D3DCLEAR_ZBUFFER) {
1672 checkGLcall("glClearDepth");
1673 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1676 if (Flags & D3DCLEAR_TARGET) {
1677 TRACE("Clearing screen with glClear to color %lx\n", Color);
1678 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1679 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1680 checkGLcall("glClearColor");
1681 glMask = glMask | GL_COLOR_BUFFER_BIT;
1685 checkGLcall("glClear");
1687 if (curRect) curRect = curRect + sizeof(D3DRECT);
1690 if (Count > 0 && pRects) {
1691 glDisable(GL_SCISSOR_TEST);
1692 checkGLcall("glDisable");
1698 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1699 ICOM_THIS(IDirect3DDevice8Impl,iface);
1704 /* Most of this routine, comments included copied from ddraw tree initially: */
1705 TRACE("(%p) : State=%d\n", This, d3dts);
1707 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1708 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1709 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1711 /* Handle recording of state blocks */
1712 if (This->isRecordingState) {
1713 TRACE("Recording... not performing anything\n");
1718 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1720 where ViewMat = Camera space, WorldMat = world space.
1722 In OpenGL, camera and world space is combined into GL_MODELVIEW
1723 matrix. The Projection matrix stay projection matrix. */
1725 /* After reading through both OpenGL and Direct3D documentations, I
1726 thought that D3D matrices were written in 'line major mode' transposed
1727 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1728 works fine to transfer one matrix format to the other (it did not work
1729 when transposing)....
1732 1) are the documentations wrong
1733 2) does the matrix work even if they are not read correctly
1734 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1735 loading using glLoadMatrix ?
1737 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1738 to the other so that if I ever find out that I need to transpose them, I
1739 will able to do it quickly, only by changing the macro conv_mat. */
1743 case D3DTS_WORLDMATRIX(0):
1744 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)]);
1748 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_VIEW]);
1751 case D3DTS_PROJECTION:
1752 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_PROJECTION]);
1755 case D3DTS_TEXTURE0:
1756 case D3DTS_TEXTURE1:
1757 case D3DTS_TEXTURE2:
1758 case D3DTS_TEXTURE3:
1759 case D3DTS_TEXTURE4:
1760 case D3DTS_TEXTURE5:
1761 case D3DTS_TEXTURE6:
1762 case D3DTS_TEXTURE7:
1763 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
1764 FIXME("Unhandled transform state for TEXTURE%d!!!\n", d3dts - D3DTS_TEXTURE0);
1765 FIXME("must use glMatrixMode(GL_TEXTURE) before texturing\n");
1769 FIXME("Unhandled transform state!!\n");
1774 * Indexed Vertex Blending Matrices 256 -> 511
1777 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
1778 if (checkGLSupport(ARB_VERTEX_BLEND)) {
1780 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
1786 * Move the GL operation to outside of switch to make it work
1787 * regardless of transform set order. Optimize later.
1790 glMatrixMode(GL_PROJECTION);
1791 checkGLcall("glMatrixMode");
1792 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
1793 checkGLcall("glLoadMatrixf");
1795 glMatrixMode(GL_MODELVIEW);
1796 checkGLcall("glMatrixMode");
1797 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
1798 checkGLcall("glLoadMatrixf");
1800 /* If we are changing the View matrix, reset the light and clipping planes to the new view */
1801 if (d3dts == D3DTS_VIEW) {
1803 /* NOTE: We have to reset the positions even if the light/plane is not currently
1804 enabled, since the call to enable it will not reset the position. */
1807 for (k = 0; k < This->maxLights; k++) {
1808 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1809 checkGLcall("glLightfv posn");
1810 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1811 checkGLcall("glLightfv dirn");
1814 /* Reset Clipping Planes if clipping is enabled */
1815 for (k = 0; k < This->clipPlanes; k++) {
1816 glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
1817 checkGLcall("glClipPlane");
1823 * Vertex Blending as described
1824 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/enums/d3dvertexblendflags.asp
1826 switch (This->UpdateStateBlock->vertex_blend) {
1827 case D3DVBF_DISABLE:
1829 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1830 checkGLcall("glMultMatrixf");
1833 case D3DVBF_1WEIGHTS:
1834 case D3DVBF_2WEIGHTS:
1835 case D3DVBF_3WEIGHTS:
1837 FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n");
1839 * doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*)
1840 * so waiting for the values before matrix work
1841 for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
1842 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
1843 checkGLcall("glMultMatrixf");
1848 case D3DVBF_TWEENING:
1850 FIXME("valid/correct D3DVBF_TWEENING\n");
1851 f = This->UpdateStateBlock->tween_factor;
1852 m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f;
1853 m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f;
1854 m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f;
1855 m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
1856 glMultMatrixf((float *) &m.u.m[0][0]);
1857 checkGLcall("glMultMatrixf");
1860 case D3DVBF_0WEIGHTS:
1862 FIXME("valid/correct D3DVBF_0WEIGHTS\n");
1863 /* single matrix of weight 1.0f */
1864 m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f;
1865 m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f;
1866 m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f;
1867 m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
1868 glMultMatrixf((float *) &m.u.m[0][0]);
1869 checkGLcall("glMultMatrixf");
1873 break; /* stupid compilator */
1881 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1882 ICOM_THIS(IDirect3DDevice8Impl,iface);
1883 TRACE("(%p) : for State %d\n", This, State);
1884 memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX));
1888 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1889 ICOM_THIS(IDirect3DDevice8Impl,iface);
1890 FIXME("(%p) : stub\n", This); return D3D_OK;
1892 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1893 ICOM_THIS(IDirect3DDevice8Impl,iface);
1895 TRACE("(%p)\n", This);
1896 This->UpdateStateBlock->Changed.viewport = TRUE;
1897 This->UpdateStateBlock->Set.viewport = TRUE;
1898 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1900 /* Handle recording of state blocks */
1901 if (This->isRecordingState) {
1902 TRACE("Recording... not performing anything\n");
1906 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1907 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1909 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1910 checkGLcall("glDepthRange");
1911 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1912 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1913 checkGLcall("glViewport");
1919 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1920 ICOM_THIS(IDirect3DDevice8Impl,iface);
1921 TRACE("(%p)\n", This);
1922 memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8));
1926 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1927 ICOM_THIS(IDirect3DDevice8Impl,iface);
1929 This->UpdateStateBlock->Changed.material = TRUE;
1930 This->UpdateStateBlock->Set.material = TRUE;
1931 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1933 /* Handle recording of state blocks */
1934 if (This->isRecordingState) {
1935 TRACE("Recording... not performing anything\n");
1940 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1941 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1942 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1943 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1944 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1946 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1947 checkGLcall("glMaterialfv");
1948 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1949 checkGLcall("glMaterialfv");
1951 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1952 checkGLcall("glMaterialfv");
1953 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1954 checkGLcall("glMaterialfv");
1955 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1956 checkGLcall("glMaterialf");
1961 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1962 ICOM_THIS(IDirect3DDevice8Impl,iface);
1963 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1964 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1965 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1966 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1967 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1968 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1972 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1973 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1977 ICOM_THIS(IDirect3DDevice8Impl,iface);
1978 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1980 if (Index > This->maxLights) {
1981 FIXME("Cannot handle more lights than device supports\n");
1982 return D3DERR_INVALIDCALL;
1985 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,
1986 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1987 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1988 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1989 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1990 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1991 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1993 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1994 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1995 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1997 /* Handle recording of state blocks */
1998 if (This->isRecordingState) {
1999 TRACE("Recording... not performing anything\n");
2004 colRGBA[0] = pLight->Diffuse.r;
2005 colRGBA[1] = pLight->Diffuse.g;
2006 colRGBA[2] = pLight->Diffuse.b;
2007 colRGBA[3] = pLight->Diffuse.a;
2008 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
2009 checkGLcall("glLightfv");
2012 colRGBA[0] = pLight->Specular.r;
2013 colRGBA[1] = pLight->Specular.g;
2014 colRGBA[2] = pLight->Specular.b;
2015 colRGBA[3] = pLight->Specular.a;
2016 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
2017 checkGLcall("glLightfv");
2020 colRGBA[0] = pLight->Ambient.r;
2021 colRGBA[1] = pLight->Ambient.g;
2022 colRGBA[2] = pLight->Ambient.b;
2023 colRGBA[3] = pLight->Ambient.a;
2024 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
2025 checkGLcall("glLightfv");
2027 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2028 glMatrixMode(GL_MODELVIEW);
2030 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2032 /* Attenuation - Are these right? guessing... */
2033 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
2034 checkGLcall("glLightf");
2035 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
2036 checkGLcall("glLightf");
2038 quad_att = 1.4/(pLight->Range*pLight->Range);
2039 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
2040 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
2041 checkGLcall("glLightf");
2043 switch (pLight->Type) {
2044 case D3DLIGHT_POINT:
2046 This->lightPosn[Index][0] = pLight->Position.x;
2047 This->lightPosn[Index][1] = pLight->Position.y;
2048 This->lightPosn[Index][2] = pLight->Position.z;
2049 This->lightPosn[Index][3] = 1.0;
2050 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2051 checkGLcall("glLightfv");
2053 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
2054 checkGLcall("glLightf");
2061 This->lightPosn[Index][0] = pLight->Position.x;
2062 This->lightPosn[Index][1] = pLight->Position.y;
2063 This->lightPosn[Index][2] = pLight->Position.z;
2064 This->lightPosn[Index][3] = 1.0;
2065 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2066 checkGLcall("glLightfv");
2069 This->lightDirn[Index][0] = pLight->Direction.x;
2070 This->lightDirn[Index][1] = pLight->Direction.y;
2071 This->lightDirn[Index][2] = pLight->Direction.z;
2072 This->lightDirn[Index][3] = 1.0;
2073 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
2074 checkGLcall("glLightfv");
2077 * opengl-ish and d3d-ish spot lights use too different models for the
2078 * light "intensity" as a function of the angle towards the main light direction,
2079 * so we only can approximate very roughly.
2080 * however spot lights are rather rarely used in games (if ever used at all).
2081 * furthermore if still used, probably nobody pays attention to such details.
2083 if (pLight->Falloff == 0) {
2086 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
2088 if (rho < 0.0001) rho = 0.0001f;
2089 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
2090 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
2094 case D3DLIGHT_DIRECTIONAL:
2096 This->lightPosn[Index][0] = -pLight->Direction.x;
2097 This->lightPosn[Index][1] = -pLight->Direction.y;
2098 This->lightPosn[Index][2] = -pLight->Direction.z;
2099 This->lightPosn[Index][3] = 0.0;
2100 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
2101 checkGLcall("glLightfv");
2103 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
2104 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
2109 FIXME("Unrecognized light type %d\n", pLight->Type);
2112 /* Restore the modelview matrix */
2117 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
2118 ICOM_THIS(IDirect3DDevice8Impl,iface);
2119 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2121 if (Index > This->maxLights) {
2122 FIXME("Cannot handle more lights than device supports\n");
2123 return D3DERR_INVALIDCALL;
2126 memcpy(pLight, &This->StateBlock->lights[Index], sizeof(D3DLIGHT8));
2129 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
2130 ICOM_THIS(IDirect3DDevice8Impl,iface);
2131 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
2133 if (Index > This->maxLights) {
2134 FIXME("Cannot handle more lights than device supports\n");
2135 return D3DERR_INVALIDCALL;
2138 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
2139 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
2140 This->UpdateStateBlock->lightEnable[Index] = Enable;
2142 /* Handle recording of state blocks */
2143 if (This->isRecordingState) {
2144 TRACE("Recording... not performing anything\n");
2149 glEnable(GL_LIGHT0+Index);
2150 checkGLcall("glEnable GL_LIGHT0+Index");
2152 glDisable(GL_LIGHT0+Index);
2153 checkGLcall("glDisable GL_LIGHT0+Index");
2157 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
2158 ICOM_THIS(IDirect3DDevice8Impl,iface);
2159 TRACE("(%p) : for idx(%ld)\n", This, Index);
2161 if (Index > This->maxLights) {
2162 FIXME("Cannot handle more lights than device supports\n");
2163 return D3DERR_INVALIDCALL;
2166 *pEnable = This->StateBlock->lightEnable[Index];
2169 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
2170 ICOM_THIS(IDirect3DDevice8Impl,iface);
2171 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
2173 /* Validate Index */
2174 if (Index >= This->clipPlanes ) {
2175 TRACE("Application has requested clipplane this device doesnt support\n");
2176 return D3DERR_INVALIDCALL;
2179 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
2180 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
2181 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
2182 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
2183 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
2184 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
2186 /* Handle recording of state blocks */
2187 if (This->isRecordingState) {
2188 TRACE("Recording... not performing anything\n");
2194 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2195 glMatrixMode(GL_MODELVIEW);
2197 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2199 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
2200 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
2201 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
2204 checkGLcall("glClipPlane");
2208 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
2209 ICOM_THIS(IDirect3DDevice8Impl,iface);
2210 TRACE("(%p) : for idx %ld\n", This, Index);
2212 /* Validate Index */
2213 if (Index >= This->clipPlanes ) {
2214 TRACE("Application has requested clipplane this device doesnt support\n");
2215 return D3DERR_INVALIDCALL;
2218 pPlane[0] = This->StateBlock->clipplane[Index][0];
2219 pPlane[1] = This->StateBlock->clipplane[Index][0];
2220 pPlane[2] = This->StateBlock->clipplane[Index][0];
2221 pPlane[3] = This->StateBlock->clipplane[Index][0];
2224 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
2225 ICOM_THIS(IDirect3DDevice8Impl,iface);
2226 DWORD OldValue = This->StateBlock->renderstate[State];
2228 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
2229 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2230 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2231 This->UpdateStateBlock->renderstate[State] = Value;
2233 /* Handle recording of state blocks */
2234 if (This->isRecordingState) {
2235 TRACE("Recording... not performing anything\n");
2240 case D3DRS_FILLMODE :
2241 switch ((D3DFILLMODE) Value) {
2242 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2243 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2244 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2246 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2248 checkGLcall("glPolygonMode (fillmode)");
2251 case D3DRS_LIGHTING :
2253 glEnable(GL_LIGHTING);
2254 checkGLcall("glEnable GL_LIGHTING");
2256 glDisable(GL_LIGHTING);
2257 checkGLcall("glDisable GL_LIGHTING");
2261 case D3DRS_ZENABLE :
2262 switch ((D3DZBUFFERTYPE) Value) {
2264 glDisable(GL_DEPTH_TEST);
2265 checkGLcall("glDisable GL_DEPTH_TEST");
2268 glEnable(GL_DEPTH_TEST);
2269 checkGLcall("glEnable GL_DEPTH_TEST");
2274 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2278 case D3DRS_CULLMODE :
2280 /* If we are culling "back faces with clockwise vertices" then
2281 set front faces to be counter clockwise and enable culling
2283 switch ((D3DCULL) Value) {
2285 glDisable(GL_CULL_FACE);
2286 checkGLcall("glDisable GL_CULL_FACE");
2289 glEnable(GL_CULL_FACE);
2290 checkGLcall("glEnable GL_CULL_FACE");
2291 glFrontFace(GL_CCW);
2292 checkGLcall("glFrontFace GL_CCW");
2293 glCullFace(GL_BACK);
2296 glEnable(GL_CULL_FACE);
2297 checkGLcall("glEnable GL_CULL_FACE");
2299 checkGLcall("glFrontFace GL_CW");
2300 glCullFace(GL_BACK);
2303 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2307 case D3DRS_SHADEMODE :
2308 switch ((D3DSHADEMODE) Value) {
2310 glShadeModel(GL_FLAT);
2311 checkGLcall("glShadeModel");
2313 case D3DSHADE_GOURAUD:
2314 glShadeModel(GL_SMOOTH);
2315 checkGLcall("glShadeModel");
2317 case D3DSHADE_PHONG:
2318 FIXME("D3DSHADE_PHONG isnt supported?\n");
2319 return D3DERR_INVALIDCALL;
2321 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
2325 case D3DRS_DITHERENABLE :
2327 glEnable(GL_DITHER);
2328 checkGLcall("glEnable GL_DITHER");
2330 glDisable(GL_DITHER);
2331 checkGLcall("glDisable GL_DITHER");
2335 case D3DRS_ZWRITEENABLE :
2338 checkGLcall("glDepthMask");
2341 checkGLcall("glDepthMask");
2347 int glParm = GL_LESS;
2349 switch ((D3DCMPFUNC) Value) {
2350 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2351 case D3DCMP_LESS: glParm=GL_LESS; break;
2352 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2353 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2354 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2355 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2356 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2357 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2359 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2361 glDepthFunc(glParm);
2362 checkGLcall("glDepthFunc");
2366 case D3DRS_AMBIENT :
2370 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2371 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2372 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2373 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2374 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
2375 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2376 checkGLcall("glLightModel for MODEL_AMBIENT");
2381 case D3DRS_ALPHABLENDENABLE :
2384 checkGLcall("glEnable GL_BLEND");
2386 glDisable(GL_BLEND);
2387 checkGLcall("glDisable GL_BLEND");
2391 case D3DRS_SRCBLEND :
2392 case D3DRS_DESTBLEND :
2394 int newVal = GL_ZERO;
2396 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2397 case D3DBLEND_ONE : newVal = GL_ONE; break;
2398 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2399 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2400 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2401 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2402 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2403 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2404 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2405 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2406 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2408 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2409 This->srcBlend = newVal;
2410 This->dstBlend = newVal;
2413 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2414 This->srcBlend = newVal;
2415 This->dstBlend = newVal;
2418 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
2421 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
2422 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
2423 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
2424 glBlendFunc(This->srcBlend, This->dstBlend);
2426 checkGLcall("glBlendFunc");
2430 case D3DRS_ALPHATESTENABLE :
2432 glEnable(GL_ALPHA_TEST);
2433 checkGLcall("glEnable GL_ALPHA_TEST");
2435 glDisable(GL_ALPHA_TEST);
2436 checkGLcall("glDisable GL_ALPHA_TEST");
2440 case D3DRS_ALPHAFUNC :
2442 int glParm = GL_LESS;
2445 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
2446 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
2448 switch ((D3DCMPFUNC) Value) {
2449 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2450 case D3DCMP_LESS: glParm=GL_LESS; break;
2451 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2452 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2453 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2454 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2455 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2456 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2458 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2460 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2461 glAlphaFunc(glParm, ref);
2462 checkGLcall("glAlphaFunc");
2466 case D3DRS_ALPHAREF :
2468 int glParm = GL_LESS;
2471 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
2472 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
2474 ref = ((float) Value) / 255.0;
2475 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2476 glAlphaFunc(glParm, ref);
2477 checkGLcall("glAlphaFunc");
2481 case D3DRS_CLIPPLANEENABLE :
2482 case D3DRS_CLIPPING :
2484 /* Ensure we only do the changed clip planes */
2485 DWORD enable = 0xFFFFFFFF;
2486 DWORD disable = 0x00000000;
2488 /* If enabling / disabling all */
2489 if (State == D3DRS_CLIPPING) {
2491 enable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2494 disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2498 enable = Value & ~OldValue;
2499 disable = ~Value & OldValue;
2502 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
2503 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
2504 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
2505 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
2506 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
2507 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
2509 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
2510 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
2511 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
2512 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
2513 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
2514 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
2518 case D3DRS_BLENDOP :
2520 int glParm = GL_FUNC_ADD;
2522 switch ((D3DBLENDOP) Value) {
2523 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
2524 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
2525 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
2526 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
2527 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
2529 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
2531 TRACE("glBlendEquation(%x)\n", glParm);
2532 glBlendEquation(glParm);
2533 checkGLcall("glBlendEquation");
2537 case D3DRS_TEXTUREFACTOR :
2541 /* Note the texture color applies to all textures whereas
2542 GL_TEXTURE_ENV_COLOR applies to active only */
2544 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2545 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2546 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2547 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2549 /* Set the default alpha blend color */
2550 glBlendColor(col[0], col[1], col[2], col[3]);
2551 checkGLcall("glBlendColor");
2553 /* And now the default texture color as well */
2554 for (i = 0; i < This->TextureUnits; i++) {
2556 /* Note the D3DRS value applies to all textures, but GL has one
2557 per texture, so apply it now ready to be used! */
2558 if (This->isMultiTexture) {
2559 #if defined(GL_VERSION_1_3)
2560 glActiveTexture(GL_TEXTURE0 + i);
2562 glActiveTextureARB(GL_TEXTURE0_ARB + i);
2564 checkGLcall("Activate texture.. to update const color");
2566 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2569 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
2570 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2575 case D3DRS_SPECULARENABLE :
2578 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
2579 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
2581 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
2582 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
2587 case D3DRS_STENCILENABLE :
2589 glEnable(GL_STENCIL_TEST);
2590 checkGLcall("glEnable GL_STENCIL_TEST");
2592 glDisable(GL_STENCIL_TEST);
2593 checkGLcall("glDisable GL_STENCIL_TEST");
2597 case D3DRS_STENCILFUNC :
2599 int glParm = GL_ALWAYS;
2601 GLuint mask = 0xFFFFFFFF;
2603 glGetIntegerv(GL_STENCIL_REF, &ref);
2604 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2605 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2606 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2608 switch ((D3DCMPFUNC) Value) {
2609 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2610 case D3DCMP_LESS: glParm=GL_LESS; break;
2611 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2612 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2613 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2614 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2615 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2616 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2618 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2620 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2621 glStencilFunc(glParm, ref, mask);
2622 checkGLcall("glStencilFunc");
2626 case D3DRS_STENCILREF :
2628 int glParm = GL_ALWAYS;
2630 GLuint mask = 0xFFFFFFFF;
2632 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2633 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2634 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2635 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2638 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2639 glStencilFunc(glParm, ref, mask);
2640 checkGLcall("glStencilFunc");
2644 case D3DRS_STENCILMASK :
2646 int glParm = GL_ALWAYS;
2648 GLuint mask = Value;
2650 glGetIntegerv(GL_STENCIL_REF, &ref);
2651 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2652 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2653 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2655 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2656 glStencilFunc(glParm, ref, mask);
2657 checkGLcall("glStencilFunc");
2661 case D3DRS_STENCILFAIL :
2667 fail = StencilOp(Value);
2668 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2669 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2670 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2671 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2673 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2674 glStencilOp(fail, zfail, zpass);
2675 checkGLcall("glStencilOp(fail, zfail, zpass);");
2678 case D3DRS_STENCILZFAIL :
2684 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2685 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2686 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2687 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2688 zfail = StencilOp(Value);
2690 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2691 glStencilOp(fail, zfail, zpass);
2692 checkGLcall("glStencilOp(fail, zfail, zpass);");
2695 case D3DRS_STENCILPASS :
2701 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2702 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2703 zpass = StencilOp(Value);
2704 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2705 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2707 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2708 glStencilOp(fail, zfail, zpass);
2709 checkGLcall("glStencilOp(fail, zfail, zpass);");
2713 case D3DRS_STENCILWRITEMASK :
2715 glStencilMask(Value);
2716 TRACE("glStencilMask(%lu)\n", Value);
2717 checkGLcall("glStencilMask");
2721 case D3DRS_FOGENABLE :
2723 if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
2725 checkGLcall("glEnable GL_FOG\n");
2728 checkGLcall("glDisable GL_FOG\n");
2733 case D3DRS_FOGCOLOR :
2736 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2737 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2738 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2739 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2741 /* Set the default alpha blend color */
2742 glFogfv(GL_FOG_COLOR, &col[0]);
2743 checkGLcall("glFog GL_FOG_COLOR");
2747 case D3DRS_FOGSTART :
2749 float *f = (float *)&Value;
2750 glFogfv(GL_FOG_START, f);
2751 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2752 TRACE("Fog Start == %f\n", *f);
2758 float *f = (float *)&Value;
2759 glFogfv(GL_FOG_END, f);
2760 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2761 TRACE("Fog End == %f\n", *f);
2765 case D3DRS_FOGDENSITY :
2767 glFogf(GL_FOG_DENSITY, (float) Value);
2768 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2772 case D3DRS_VERTEXBLEND :
2774 This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
2775 TRACE("Vertex Blending state to %ld\n", Value);
2779 case D3DRS_TWEENFACTOR :
2781 This->UpdateStateBlock->tween_factor = *((float*) &Value);
2782 TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
2786 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2788 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
2793 case D3DRS_COLORVERTEX :
2794 case D3DRS_DIFFUSEMATERIALSOURCE :
2795 case D3DRS_SPECULARMATERIALSOURCE :
2796 case D3DRS_AMBIENTMATERIALSOURCE :
2797 case D3DRS_EMISSIVEMATERIALSOURCE :
2799 GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
2801 if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
2802 glEnable(GL_COLOR_MATERIAL);
2803 checkGLcall("glEnable GL_GL_COLOR_MATERIAL\n");
2805 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
2806 This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
2807 This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
2808 This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE],
2809 This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]);
2811 if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
2812 if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
2813 Parm = GL_AMBIENT_AND_DIFFUSE;
2817 } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
2819 } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
2821 } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
2828 glDisable(GL_COLOR_MATERIAL);
2829 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
2831 TRACE("glColorMaterial Parm=%d\n", Parm);
2832 glColorMaterial(GL_FRONT_AND_BACK, Parm);
2833 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)\n");
2837 glDisable(GL_COLOR_MATERIAL);
2838 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
2843 /* Unhandled yet...! */
2844 case D3DRS_LINEPATTERN :
2845 case D3DRS_LASTPIXEL :
2846 case D3DRS_ZVISIBLE :
2847 case D3DRS_FOGTABLEMODE :
2848 case D3DRS_EDGEANTIALIAS :
2850 case D3DRS_RANGEFOGENABLE :
2859 case D3DRS_FOGVERTEXMODE :
2860 case D3DRS_LOCALVIEWER :
2861 case D3DRS_NORMALIZENORMALS :
2862 case D3DRS_SOFTWAREVERTEXPROCESSING :
2863 case D3DRS_POINTSIZE :
2864 case D3DRS_POINTSIZE_MIN :
2865 case D3DRS_POINTSPRITEENABLE :
2866 case D3DRS_POINTSCALEENABLE :
2867 case D3DRS_POINTSCALE_A :
2868 case D3DRS_POINTSCALE_B :
2869 case D3DRS_POINTSCALE_C :
2870 case D3DRS_MULTISAMPLEANTIALIAS :
2871 case D3DRS_MULTISAMPLEMASK :
2872 case D3DRS_PATCHEDGESTYLE :
2873 case D3DRS_PATCHSEGMENTS :
2874 case D3DRS_DEBUGMONITORTOKEN :
2875 case D3DRS_POINTSIZE_MAX :
2876 case D3DRS_COLORWRITEENABLE :
2877 case D3DRS_POSITIONORDER :
2878 case D3DRS_NORMALORDER :
2879 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2880 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2883 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2888 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2889 ICOM_THIS(IDirect3DDevice8Impl,iface);
2890 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2891 *pValue = This->StateBlock->renderstate[State];
2894 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2895 ICOM_THIS(IDirect3DDevice8Impl,iface);
2897 TRACE("(%p)\n", This);
2899 return IDirect3DDeviceImpl_BeginStateBlock(This);
2901 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2902 IDirect3DStateBlockImpl* pSB;
2903 ICOM_THIS(IDirect3DDevice8Impl,iface);
2906 TRACE("(%p)\n", This);
2908 res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB);
2909 *pToken = (DWORD) pSB;
2913 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2914 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2915 ICOM_THIS(IDirect3DDevice8Impl,iface);
2917 TRACE("(%p)\n", This);
2919 return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB);
2922 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2923 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2924 ICOM_THIS(IDirect3DDevice8Impl,iface);
2926 TRACE("(%p)\n", This);
2928 return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB);
2930 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2931 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2932 ICOM_THIS(IDirect3DDevice8Impl,iface);
2934 TRACE("(%p)\n", This);
2936 return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB);
2939 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
2940 IDirect3DStateBlockImpl* pSB;
2941 ICOM_THIS(IDirect3DDevice8Impl,iface);
2944 TRACE("(%p) : for type %d\n", This, Type);
2946 res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB);
2947 *pToken = (DWORD) pSB;
2951 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2952 ICOM_THIS(IDirect3DDevice8Impl,iface);
2953 FIXME("(%p) : stub\n", This); return D3D_OK;
2955 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2956 ICOM_THIS(IDirect3DDevice8Impl,iface);
2957 FIXME("(%p) : stub\n", This); return D3D_OK;
2959 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2960 ICOM_THIS(IDirect3DDevice8Impl,iface);
2961 TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage);
2962 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage];
2963 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2966 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2968 IDirect3DBaseTexture8 *oldTxt;
2970 ICOM_THIS(IDirect3DDevice8Impl,iface);
2971 D3DRESOURCETYPE textureType;
2973 oldTxt = This->UpdateStateBlock->textures[Stage];
2974 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2976 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2977 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2978 This->UpdateStateBlock->textures[Stage] = pTexture;
2980 /* Handle recording of state blocks */
2981 if (This->isRecordingState) {
2982 TRACE("Recording... not performing anything\n");
2986 /* Make appropriate texture active */
2987 if (This->isMultiTexture) {
2988 #if defined(GL_VERSION_1_3)
2989 glActiveTexture(GL_TEXTURE0 + Stage);
2991 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2993 checkGLcall("glActiveTextureARB");
2994 } else if (Stage>0) {
2995 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2998 /* Decrement the count of the previous texture */
2999 /* FIXME PERF: If old == new and not dirty then skip all this */
3000 if (oldTxt != NULL) {
3001 IDirect3DBaseTexture8Impl_Release(oldTxt);
3005 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]);
3007 /* Now setup the texture appropraitly */
3008 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
3010 if (textureType == D3DRTYPE_TEXTURE) {
3011 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
3014 /* Standard 2D texture */
3015 TRACE("Standard 2d texture\n");
3016 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D;
3018 for (i=0; i<pTexture2->levels; i++)
3021 if (i==0 && pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3022 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3023 checkGLcall("glBindTexture");
3024 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3025 /* No need to walk through all mip-map levels, since already all assigned */
3026 i = pTexture2->levels;
3031 if (pTexture2->surfaces[i]->textureName == 0) {
3032 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
3033 checkGLcall("glGenTextures");
3034 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3037 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3038 checkGLcall("glBindTexture");
3040 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", pTexture2->levels-1);
3041 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3042 checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels)");
3045 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3046 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
3047 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3048 pTexture2->surfaces[i]->allocatedMemory);
3049 glTexImage2D(GL_TEXTURE_2D, i,
3050 fmt2glintFmt(pTexture2->format),
3051 pTexture2->surfaces[i]->myDesc.Width,
3052 pTexture2->surfaces[i]->myDesc.Height,
3054 fmt2glFmt(pTexture2->format),
3055 fmt2glType(pTexture2->format),
3056 pTexture2->surfaces[i]->allocatedMemory
3058 checkGLcall("glTexImage2D");
3060 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3061 pTexture2->Dirty = FALSE;
3066 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3067 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3070 /* Standard 3D (volume) texture */
3071 TRACE("Standard 3d texture\n");
3072 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
3074 for (i=0; i<pTexture2->levels; i++)
3077 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3078 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3079 checkGLcall("glBindTexture");
3080 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3082 /* No need to walk through all mip-map levels, since already all assigned */
3083 i = pTexture2->levels;
3087 if (pTexture2->volumes[i]->textureName == 0) {
3088 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3089 checkGLcall("glGenTextures");
3090 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3093 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3094 checkGLcall("glBindTexture");
3096 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3097 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3100 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3101 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3102 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3103 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3104 pTexture2->volumes[i]->allocatedMemory);
3105 glTexImage3D(GL_TEXTURE_3D, i,
3106 fmt2glintFmt(pTexture2->format),
3107 pTexture2->volumes[i]->myDesc.Width,
3108 pTexture2->volumes[i]->myDesc.Height,
3109 pTexture2->volumes[i]->myDesc.Depth,
3111 fmt2glFmt(pTexture2->format),
3112 fmt2glType(pTexture2->format),
3113 pTexture2->volumes[i]->allocatedMemory
3115 checkGLcall("glTexImage3D");
3117 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3118 pTexture2->Dirty = FALSE;
3123 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
3126 TRACE("Setting to no texture (ie default texture)\n");
3127 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D;
3128 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3129 checkGLcall("glBindTexture");
3130 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3133 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3134 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3135 setupTextureStates (iface, Stage);
3140 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3141 ICOM_THIS(IDirect3DDevice8Impl,iface);
3142 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
3143 *pValue = This->UpdateStateBlock->texture_state[Stage][Type];
3147 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
3148 ICOM_THIS(IDirect3DDevice8Impl,iface);
3150 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3152 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
3154 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3155 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3156 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3158 /* Handle recording of state blocks */
3159 if (This->isRecordingState) {
3160 TRACE("Recording... not performing anything\n");
3164 /* Make appropriate texture active */
3165 TRACE("Activating appropriate texture state %ld\n", Stage);
3166 if (This->isMultiTexture) {
3167 #if defined(GL_VERSION_1_3)
3168 glActiveTexture(GL_TEXTURE0 + Stage);
3169 checkGLcall("glActiveTexture");
3171 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3172 checkGLcall("glActiveTextureARB");
3175 } else if (Stage>0) {
3176 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3181 case D3DTSS_MINFILTER :
3182 case D3DTSS_MIPFILTER :
3184 DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER];
3185 DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER];
3186 GLint realVal = GL_LINEAR;
3188 if (ValueMIN == D3DTEXF_POINT) {
3190 if (ValueMIP == D3DTEXF_POINT) {
3191 realVal = GL_NEAREST_MIPMAP_NEAREST;
3192 } else if (ValueMIP == D3DTEXF_LINEAR) {
3193 realVal = GL_NEAREST_MIPMAP_LINEAR;
3194 } else if (ValueMIP == D3DTEXF_NONE) {
3195 realVal = GL_NEAREST;
3197 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3198 realVal = GL_NEAREST_MIPMAP_LINEAR;
3200 } else if (ValueMIN == D3DTEXF_LINEAR) {
3202 if (ValueMIP == D3DTEXF_POINT) {
3203 realVal = GL_LINEAR_MIPMAP_NEAREST;
3204 } else if (ValueMIP == D3DTEXF_LINEAR) {
3205 realVal = GL_LINEAR_MIPMAP_LINEAR;
3206 } else if (ValueMIP == D3DTEXF_NONE) {
3207 realVal = GL_LINEAR;
3209 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3210 realVal = GL_LINEAR_MIPMAP_LINEAR;
3212 } else if (ValueMIN == D3DTEXF_NONE) {
3213 /* Doesnt really make sense - Windows just seems to disable
3214 mipmapping when this occurs */
3215 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3216 realVal = GL_LINEAR;
3219 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3220 realVal = GL_LINEAR_MIPMAP_LINEAR;
3223 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3224 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3225 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3230 case D3DTSS_MAGFILTER :
3231 if (Value == D3DTEXF_POINT) {
3232 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3233 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3234 } else if (Value == D3DTEXF_LINEAR) {
3235 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3236 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3238 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3242 case D3DTSS_COLORARG0 :
3243 case D3DTSS_ALPHAARG0 :
3244 /* FIXME: Mesa seems to struggle setting these at the moment */
3247 case D3DTSS_COLORARG1 :
3248 case D3DTSS_COLORARG2 :
3249 case D3DTSS_ALPHAARG1 :
3250 case D3DTSS_ALPHAARG2 :
3252 BOOL isAlphaReplicate = FALSE;
3253 BOOL isComplement = FALSE;
3254 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3255 int operand= GL_SRC_COLOR;
3256 int source = GL_TEXTURE;
3258 /* Catch alpha replicate */
3259 if (Value & D3DTA_ALPHAREPLICATE) {
3260 Value = Value & ~D3DTA_ALPHAREPLICATE;
3261 isAlphaReplicate = TRUE;
3264 /* Catch Complement */
3265 if (Value & D3DTA_COMPLEMENT) {
3266 Value = Value & ~D3DTA_COMPLEMENT;
3267 isComplement = TRUE;
3270 /* Calculate the operand */
3271 if (isAlphaReplicate && !isComplement) {
3272 operand = GL_SRC_ALPHA;
3273 } else if (isAlphaReplicate && isComplement) {
3274 operand = GL_ONE_MINUS_SRC_ALPHA;
3275 } else if (isComplement) {
3277 operand = GL_ONE_MINUS_SRC_ALPHA;
3279 operand = GL_ONE_MINUS_SRC_COLOR;
3283 operand = GL_SRC_ALPHA;
3285 operand = GL_SRC_COLOR;
3289 /* Calculate the source */
3291 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
3293 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
3295 case D3DTA_TEXTURE: source = GL_TEXTURE;
3297 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
3300 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
3301 isnt supported until base GL supports it
3302 There is no concept of temp registers as far as I can tell */
3305 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
3309 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3310 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3311 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3312 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3313 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3315 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3316 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3317 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3318 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3319 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3324 case D3DTSS_ALPHAOP :
3325 case D3DTSS_COLOROP :
3329 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3331 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3332 /* TODO: Disable by making this and all later levels disabled */
3333 glDisable(GL_TEXTURE_1D);
3334 checkGLcall("Disable GL_TEXTURE_1D");
3335 glDisable(GL_TEXTURE_2D);
3336 checkGLcall("Disable GL_TEXTURE_2D");
3337 glDisable(GL_TEXTURE_3D);
3338 checkGLcall("Disable GL_TEXTURE_3D");
3341 /* Enable only the appropriate texture dimension */
3342 if (Type==D3DTSS_COLOROP) {
3343 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
3344 glEnable(GL_TEXTURE_1D);
3345 checkGLcall("Enable GL_TEXTURE_1D");
3347 glDisable(GL_TEXTURE_1D);
3348 checkGLcall("Disable GL_TEXTURE_1D");
3350 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
3351 glEnable(GL_TEXTURE_2D);
3352 checkGLcall("Enable GL_TEXTURE_2D");
3354 glDisable(GL_TEXTURE_2D);
3355 checkGLcall("Disable GL_TEXTURE_2D");
3357 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
3358 glEnable(GL_TEXTURE_3D);
3359 checkGLcall("Enable GL_TEXTURE_3D");
3361 glDisable(GL_TEXTURE_3D);
3362 checkGLcall("Disable GL_TEXTURE_3D");
3366 /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
3367 if (Value != D3DTOP_DISABLE) {
3368 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
3371 /* Now set up the operand correctly */
3373 case D3DTOP_DISABLE :
3374 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3375 and it works, so ignore this op */
3376 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3379 case D3DTOP_SELECTARG1 :
3380 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3381 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3384 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3385 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3386 case D3DTOP_MODULATE :
3389 if (Type == D3DTSS_ALPHAOP) {
3390 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3391 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3393 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3394 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3396 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3397 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3401 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3402 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3405 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3406 case D3DTOP_ADDSIGNED :
3407 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3408 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3411 case D3DTOP_DOTPRODUCT3 :
3412 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3413 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3416 case D3DTOP_SUBTRACT :
3417 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3418 case D3DTOP_SELECTARG2 :
3419 /* GL_REPLACE, swap args 0 and 1? */
3420 case D3DTOP_ADDSMOOTH :
3421 case D3DTOP_BLENDDIFFUSEALPHA :
3422 case D3DTOP_BLENDTEXTUREALPHA :
3423 case D3DTOP_BLENDFACTORALPHA :
3424 case D3DTOP_BLENDTEXTUREALPHAPM :
3425 case D3DTOP_BLENDCURRENTALPHA :
3426 case D3DTOP_PREMODULATE :
3427 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3428 case D3DTOP_MODULATECOLOR_ADDALPHA :
3429 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3430 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3431 case D3DTOP_BUMPENVMAP :
3432 case D3DTOP_BUMPENVMAPLUMINANCE :
3433 case D3DTOP_MULTIPLYADD :
3436 FIXME("Unhandled texture operation %ld\n", Value);
3442 case D3DTSS_ADDRESSU :
3443 case D3DTSS_ADDRESSV :
3444 case D3DTSS_ADDRESSW :
3446 GLint wrapParm = GL_REPEAT;
3448 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3449 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP; break;
3450 case D3DTADDRESS_BORDER: wrapParm = GL_CLAMP_TO_EDGE; break;
3452 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL? */
3453 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL? */
3455 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3456 wrapParm = GL_REPEAT;
3460 case D3DTSS_ADDRESSU:
3461 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3462 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3463 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3465 case D3DTSS_ADDRESSV:
3466 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3467 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3468 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3470 case D3DTSS_ADDRESSW:
3471 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3472 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3473 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3476 break; /** stupic compilator */
3481 case D3DTSS_BORDERCOLOR :
3484 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3485 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3486 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3487 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3489 TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value);
3490 glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3491 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3496 case D3DTSS_BUMPENVMAT00 :
3497 case D3DTSS_BUMPENVMAT01 :
3498 case D3DTSS_BUMPENVMAT10 :
3499 case D3DTSS_BUMPENVMAT11 :
3500 case D3DTSS_TEXCOORDINDEX :
3501 case D3DTSS_MIPMAPLODBIAS :
3502 case D3DTSS_MAXMIPLEVEL :
3503 case D3DTSS_MAXANISOTROPY :
3504 case D3DTSS_BUMPENVLSCALE :
3505 case D3DTSS_BUMPENVLOFFSET :
3506 case D3DTSS_TEXTURETRANSFORMFLAGS :
3507 case D3DTSS_RESULTARG :
3509 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3510 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3514 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3515 ICOM_THIS(IDirect3DDevice8Impl,iface);
3516 FIXME("(%p) : stub\n", This); return D3D_OK;
3518 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3519 ICOM_THIS(IDirect3DDevice8Impl,iface);
3520 FIXME("(%p) : stub\n", This); return D3D_OK;
3522 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3523 ICOM_THIS(IDirect3DDevice8Impl,iface);
3524 FIXME("(%p) : stub\n", This); return D3D_OK;
3526 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3527 ICOM_THIS(IDirect3DDevice8Impl,iface);
3528 FIXME("(%p) : stub\n", This); return D3D_OK;
3530 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3531 ICOM_THIS(IDirect3DDevice8Impl,iface);
3532 FIXME("(%p) : stub\n", This); return D3D_OK;
3534 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3535 ICOM_THIS(IDirect3DDevice8Impl,iface);
3536 FIXME("(%p) : stub\n", This); return D3D_OK;
3538 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3540 IDirect3DVertexBuffer8 *pVB;
3542 ICOM_THIS(IDirect3DDevice8Impl,iface);
3543 pVB = This->StateBlock->stream_source[0];
3545 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3547 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3548 This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
3552 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3553 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3555 IDirect3DIndexBuffer8 *pIB;
3556 IDirect3DVertexBuffer8 *pVB;
3557 D3DINDEXBUFFER_DESC IdxBufDsc;
3559 ICOM_THIS(IDirect3DDevice8Impl,iface);
3560 pIB = This->StateBlock->pIndexData;
3561 pVB = This->StateBlock->stream_source[0];
3563 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3564 minIndex, NumVertices, startIndex, primCount);
3566 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3567 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3573 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3574 This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3579 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3580 ICOM_THIS(IDirect3DDevice8Impl,iface);
3582 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3584 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3586 This->StateBlock->stream_source[0] = NULL;
3587 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3588 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock->VertexShader, pVertexStreamZeroData,
3590 This->StateBlock->stream_stride[0] = 0;
3592 /*stream zero settings set to null at end */
3595 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3596 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3597 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3598 UINT VertexStreamZeroStride) {
3600 ICOM_THIS(IDirect3DDevice8Impl,iface);
3601 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3602 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3604 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3605 if (IndexDataFormat == D3DFMT_INDEX16) {
3611 This->StateBlock->stream_source[0] = NULL;
3612 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3613 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock->VertexShader, pVertexStreamZeroData,
3614 This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3616 /*stream zero settings set to null at end */
3617 This->StateBlock->stream_stride[0] = 0;
3618 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3622 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3623 ICOM_THIS(IDirect3DDevice8Impl,iface);
3624 FIXME("(%p) : stub\n", This); return D3D_OK;
3626 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3627 ICOM_THIS(IDirect3DDevice8Impl,iface);
3628 IDirect3DVertexShaderImpl* object;
3629 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3633 TRACE("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3634 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3635 return D3DERR_INVALIDCALL;
3637 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
3638 if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
3639 return D3DERR_OUTOFVIDEOMEMORY;
3642 /** Create the Vertex Shader */
3643 res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
3644 /** TODO: check FAILED(res) */
3646 /** Create and Bind the Vertex Shader Declaration */
3647 res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
3648 /** TODO: check FAILED(res) */
3650 VertexShaders[i] = object;
3651 VertexShaderDeclarations[i] = attached_decl;
3652 *pHandle = VS_HIGHESTFIXEDFXF + i;
3656 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3657 ICOM_THIS(IDirect3DDevice8Impl,iface);
3659 This->UpdateStateBlock->VertexShader = Handle;
3660 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3661 This->UpdateStateBlock->Set.vertexShader = TRUE;
3663 if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
3664 FIXME("(%p) : Created shader, Handle=%lx\n", This, Handle);
3665 This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
3666 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3667 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3668 } else { /* use a fvf, so desactivate the vshader decl */
3669 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3670 This->UpdateStateBlock->vertexShaderDecl = NULL;
3671 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3672 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3674 /* Handle recording of state blocks */
3675 if (This->isRecordingState) {
3676 TRACE("Recording... not performing anything\n");
3680 * TODO: merge HAL shaders context switching from prototype
3684 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3685 ICOM_THIS(IDirect3DDevice8Impl,iface);
3686 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
3687 *pHandle = This->StateBlock->VertexShader;
3691 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3692 ICOM_THIS(IDirect3DDevice8Impl,iface);
3693 IDirect3DVertexShaderImpl* object;
3694 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3696 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3697 return D3DERR_INVALIDCALL;
3701 * Delete Vertex Shader
3703 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3704 if (NULL == object) {
3705 return D3DERR_INVALIDCALL;
3707 FIXME("(%p) : freing VertexShader %p\n", This, object);
3708 /* TODO: check validity of object */
3709 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3710 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3711 HeapFree(GetProcessHeap(), 0, (void *)object);
3712 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3715 * Delete Vertex Shader Declaration
3717 attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
3718 if (NULL == attached_decl) {
3719 return D3DERR_INVALIDCALL;
3721 FIXME("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
3722 /* TODO: check validity of object */
3723 HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
3724 HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
3725 VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3730 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3731 ICOM_THIS(IDirect3DDevice8Impl,iface);
3733 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3734 /*ERR("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);*/
3735 return D3DERR_INVALIDCALL;
3737 if (NULL == pConstantData) {
3738 return D3DERR_INVALIDCALL;
3740 if (ConstantCount > 1) {
3741 FLOAT* f = (FLOAT*)pConstantData;
3743 FIXME("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
3744 for (i = 0; i < ConstantCount; ++i) {
3745 DPRINTF("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
3749 FLOAT* f = (FLOAT*)pConstantData;
3750 FIXME("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
3752 This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
3753 memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
3756 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3757 ICOM_THIS(IDirect3DDevice8Impl,iface);
3759 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3760 return D3DERR_INVALIDCALL;
3762 if (NULL == pConstantData) {
3763 return D3DERR_INVALIDCALL;
3765 memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
3768 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3769 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3770 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3772 attached_decl = VERTEX_SHADER_DECL(Handle);
3773 if (NULL == attached_decl) {
3774 return D3DERR_INVALIDCALL;
3776 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
3778 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3779 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3780 IDirect3DVertexShaderImpl* object;
3782 object = VERTEX_SHADER(Handle);
3783 if (NULL == object) {
3784 return D3DERR_INVALIDCALL;
3786 return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
3789 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
3790 ICOM_THIS(IDirect3DDevice8Impl,iface);
3791 IDirect3DIndexBuffer8 *oldIdxs;
3793 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3794 oldIdxs = This->StateBlock->pIndexData;
3796 This->UpdateStateBlock->Changed.Indices = TRUE;
3797 This->UpdateStateBlock->Set.Indices = TRUE;
3798 This->UpdateStateBlock->pIndexData = pIndexData;
3799 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3801 /* Handle recording of state blocks */
3802 if (This->isRecordingState) {
3803 TRACE("Recording... not performing anything\n");
3807 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3808 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
3811 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3812 ICOM_THIS(IDirect3DDevice8Impl,iface);
3813 FIXME("(%p) : stub\n", This);
3815 *ppIndexData = This->StateBlock->pIndexData;
3816 /* up ref count on ppindexdata */
3817 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3818 *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
3822 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3823 ICOM_THIS(IDirect3DDevice8Impl,iface);
3824 IDirect3DPixelShaderImpl* object;
3827 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3828 if (NULL == pFunction || NULL == pHandle) {
3829 return D3DERR_INVALIDCALL;
3831 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
3832 if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
3833 return D3DERR_OUTOFVIDEOMEMORY;
3835 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
3836 if (NULL == object) {
3837 return D3DERR_OUTOFVIDEOMEMORY;
3840 object->data = NULL; /* TODO */
3842 PixelShaders[i] = object;
3843 *pHandle = VS_HIGHESTFIXEDFXF + i;
3845 object->function = pFunction;
3846 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3847 object->functionLength = i + 1;
3851 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3852 ICOM_THIS(IDirect3DDevice8Impl,iface);
3854 This->UpdateStateBlock->PixelShader = Handle;
3855 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3856 This->UpdateStateBlock->Set.pixelShader = TRUE;
3858 /* Handle recording of state blocks */
3859 if (This->isRecordingState) {
3860 TRACE("Recording... not performing anything\n");
3864 /* FIXME: Quieten when not being used */
3866 FIXME("(%p) : stub %ld\n", This, Handle);
3868 TRACE("(%p) : stub %ld\n", This, Handle);
3873 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3874 ICOM_THIS(IDirect3DDevice8Impl,iface);
3875 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
3876 *pHandle = This->StateBlock->PixelShader;
3880 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3881 ICOM_THIS(IDirect3DDevice8Impl,iface);
3882 IDirect3DPixelShaderImpl* object;
3884 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3885 return D3DERR_INVALIDCALL;
3887 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3888 TRACE("(%p) : freeing PixelShader %p\n", This, object);
3889 /* TODO: check validity of object before free */
3890 HeapFree(GetProcessHeap(), 0, (void *)object);
3891 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3895 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
3896 ICOM_THIS(IDirect3DDevice8Impl,iface);
3897 FIXME("(%p) : stub\n", This);
3900 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
3901 ICOM_THIS(IDirect3DDevice8Impl,iface);
3902 FIXME("(%p) : stub\n", This);
3905 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3906 ICOM_THIS(IDirect3DDevice8Impl,iface);
3907 IDirect3DPixelShaderImpl* object;
3909 object = PIXEL_SHADER(Handle);
3910 if (NULL == object) {
3911 return D3DERR_INVALIDCALL;
3913 if (NULL == pData) {
3914 *pSizeOfData = object->functionLength;
3917 if (*pSizeOfData < object->functionLength) {
3918 *pSizeOfData = object->functionLength;
3919 return D3DERR_MOREDATA;
3921 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
3922 memcpy(pData, object->function, object->functionLength);
3925 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3926 ICOM_THIS(IDirect3DDevice8Impl,iface);
3927 FIXME("(%p) : stub\n", This); return D3D_OK;
3929 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3930 ICOM_THIS(IDirect3DDevice8Impl,iface);
3931 FIXME("(%p) : stub\n", This); return D3D_OK;
3933 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3934 ICOM_THIS(IDirect3DDevice8Impl,iface);
3935 FIXME("(%p) : stub\n", This); return D3D_OK;
3938 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3939 IDirect3DVertexBuffer8 *oldSrc;
3940 ICOM_THIS(IDirect3DDevice8Impl,iface);
3942 oldSrc = This->StateBlock->stream_source[StreamNumber];
3943 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3945 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3946 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3947 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3948 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3950 /* Handle recording of state blocks */
3951 if (This->isRecordingState) {
3952 TRACE("Recording... not performing anything\n");
3956 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3957 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3960 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3961 ICOM_THIS(IDirect3DDevice8Impl,iface);
3962 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
3963 *pStream = This->StateBlock->stream_source[StreamNumber];
3964 *pStride = This->StateBlock->stream_stride[StreamNumber];
3965 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3970 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3972 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3973 IDirect3DDevice8Impl_QueryInterface,
3974 IDirect3DDevice8Impl_AddRef,
3975 IDirect3DDevice8Impl_Release,
3976 IDirect3DDevice8Impl_TestCooperativeLevel,
3977 IDirect3DDevice8Impl_GetAvailableTextureMem,
3978 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3979 IDirect3DDevice8Impl_GetDirect3D,
3980 IDirect3DDevice8Impl_GetDeviceCaps,
3981 IDirect3DDevice8Impl_GetDisplayMode,
3982 IDirect3DDevice8Impl_GetCreationParameters,
3983 IDirect3DDevice8Impl_SetCursorProperties,
3984 IDirect3DDevice8Impl_SetCursorPosition,
3985 IDirect3DDevice8Impl_ShowCursor,
3986 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3987 IDirect3DDevice8Impl_Reset,
3988 IDirect3DDevice8Impl_Present,
3989 IDirect3DDevice8Impl_GetBackBuffer,
3990 IDirect3DDevice8Impl_GetRasterStatus,
3991 IDirect3DDevice8Impl_SetGammaRamp,
3992 IDirect3DDevice8Impl_GetGammaRamp,
3993 IDirect3DDevice8Impl_CreateTexture,
3994 IDirect3DDevice8Impl_CreateVolumeTexture,
3995 IDirect3DDevice8Impl_CreateCubeTexture,
3996 IDirect3DDevice8Impl_CreateVertexBuffer,
3997 IDirect3DDevice8Impl_CreateIndexBuffer,
3998 IDirect3DDevice8Impl_CreateRenderTarget,
3999 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4000 IDirect3DDevice8Impl_CreateImageSurface,
4001 IDirect3DDevice8Impl_CopyRects,
4002 IDirect3DDevice8Impl_UpdateTexture,
4003 IDirect3DDevice8Impl_GetFrontBuffer,
4004 IDirect3DDevice8Impl_SetRenderTarget,
4005 IDirect3DDevice8Impl_GetRenderTarget,
4006 IDirect3DDevice8Impl_GetDepthStencilSurface,
4007 IDirect3DDevice8Impl_BeginScene,
4008 IDirect3DDevice8Impl_EndScene,
4009 IDirect3DDevice8Impl_Clear,
4010 IDirect3DDevice8Impl_SetTransform,
4011 IDirect3DDevice8Impl_GetTransform,
4012 IDirect3DDevice8Impl_MultiplyTransform,
4013 IDirect3DDevice8Impl_SetViewport,
4014 IDirect3DDevice8Impl_GetViewport,
4015 IDirect3DDevice8Impl_SetMaterial,
4016 IDirect3DDevice8Impl_GetMaterial,
4017 IDirect3DDevice8Impl_SetLight,
4018 IDirect3DDevice8Impl_GetLight,
4019 IDirect3DDevice8Impl_LightEnable,
4020 IDirect3DDevice8Impl_GetLightEnable,
4021 IDirect3DDevice8Impl_SetClipPlane,
4022 IDirect3DDevice8Impl_GetClipPlane,
4023 IDirect3DDevice8Impl_SetRenderState,
4024 IDirect3DDevice8Impl_GetRenderState,
4025 IDirect3DDevice8Impl_BeginStateBlock,
4026 IDirect3DDevice8Impl_EndStateBlock,
4027 IDirect3DDevice8Impl_ApplyStateBlock,
4028 IDirect3DDevice8Impl_CaptureStateBlock,
4029 IDirect3DDevice8Impl_DeleteStateBlock,
4030 IDirect3DDevice8Impl_CreateStateBlock,
4031 IDirect3DDevice8Impl_SetClipStatus,
4032 IDirect3DDevice8Impl_GetClipStatus,
4033 IDirect3DDevice8Impl_GetTexture,
4034 IDirect3DDevice8Impl_SetTexture,
4035 IDirect3DDevice8Impl_GetTextureStageState,
4036 IDirect3DDevice8Impl_SetTextureStageState,
4037 IDirect3DDevice8Impl_ValidateDevice,
4038 IDirect3DDevice8Impl_GetInfo,
4039 IDirect3DDevice8Impl_SetPaletteEntries,
4040 IDirect3DDevice8Impl_GetPaletteEntries,
4041 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4042 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4043 IDirect3DDevice8Impl_DrawPrimitive,
4044 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4045 IDirect3DDevice8Impl_DrawPrimitiveUP,
4046 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4047 IDirect3DDevice8Impl_ProcessVertices,
4048 IDirect3DDevice8Impl_CreateVertexShader,
4049 IDirect3DDevice8Impl_SetVertexShader,
4050 IDirect3DDevice8Impl_GetVertexShader,
4051 IDirect3DDevice8Impl_DeleteVertexShader,
4052 IDirect3DDevice8Impl_SetVertexShaderConstant,
4053 IDirect3DDevice8Impl_GetVertexShaderConstant,
4054 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4055 IDirect3DDevice8Impl_GetVertexShaderFunction,
4056 IDirect3DDevice8Impl_SetStreamSource,
4057 IDirect3DDevice8Impl_GetStreamSource,
4058 IDirect3DDevice8Impl_SetIndices,
4059 IDirect3DDevice8Impl_GetIndices,
4060 IDirect3DDevice8Impl_CreatePixelShader,
4061 IDirect3DDevice8Impl_SetPixelShader,
4062 IDirect3DDevice8Impl_GetPixelShader,
4063 IDirect3DDevice8Impl_DeletePixelShader,
4064 IDirect3DDevice8Impl_SetPixelShaderConstant,
4065 IDirect3DDevice8Impl_GetPixelShaderConstant,
4066 IDirect3DDevice8Impl_GetPixelShaderFunction,
4067 IDirect3DDevice8Impl_DrawRectPatch,
4068 IDirect3DDevice8Impl_DrawTriPatch,
4069 IDirect3DDevice8Impl_DeletePatch