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 #if defined(GL_VERSION_1_3)
3414 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3415 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3419 FIXME("DotProduct3 extension requested but not supported via this version of opengl\n");
3422 case D3DTOP_SUBTRACT :
3423 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3424 case D3DTOP_SELECTARG2 :
3425 /* GL_REPLACE, swap args 0 and 1? */
3426 case D3DTOP_ADDSMOOTH :
3427 case D3DTOP_BLENDDIFFUSEALPHA :
3428 case D3DTOP_BLENDTEXTUREALPHA :
3429 case D3DTOP_BLENDFACTORALPHA :
3430 case D3DTOP_BLENDTEXTUREALPHAPM :
3431 case D3DTOP_BLENDCURRENTALPHA :
3432 case D3DTOP_PREMODULATE :
3433 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3434 case D3DTOP_MODULATECOLOR_ADDALPHA :
3435 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3436 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3437 case D3DTOP_BUMPENVMAP :
3438 case D3DTOP_BUMPENVMAPLUMINANCE :
3439 case D3DTOP_MULTIPLYADD :
3442 FIXME("Unhandled texture operation %ld\n", Value);
3448 case D3DTSS_ADDRESSU :
3449 case D3DTSS_ADDRESSV :
3450 case D3DTSS_ADDRESSW :
3452 GLint wrapParm = GL_REPEAT;
3454 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3455 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break;
3456 case D3DTADDRESS_BORDER: wrapParm = GL_REPEAT; break; /* FIXME: Not right, but better */
3457 #if defined(GL_VERSION_1_3)
3458 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT_ARB; break;
3459 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL but pretent mirror */
3461 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL pre-1.4 */
3462 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL */
3465 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3466 wrapParm = GL_REPEAT;
3470 case D3DTSS_ADDRESSU:
3471 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3472 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3473 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3475 case D3DTSS_ADDRESSV:
3476 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3477 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3478 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3480 case D3DTSS_ADDRESSW:
3481 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3482 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3483 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3486 break; /** stupic compilator */
3491 case D3DTSS_BORDERCOLOR :
3494 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3495 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3496 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3497 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3499 TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value);
3500 glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3501 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3506 case D3DTSS_BUMPENVMAT00 :
3507 case D3DTSS_BUMPENVMAT01 :
3508 case D3DTSS_BUMPENVMAT10 :
3509 case D3DTSS_BUMPENVMAT11 :
3510 case D3DTSS_TEXCOORDINDEX :
3511 case D3DTSS_MIPMAPLODBIAS :
3512 case D3DTSS_MAXMIPLEVEL :
3513 case D3DTSS_MAXANISOTROPY :
3514 case D3DTSS_BUMPENVLSCALE :
3515 case D3DTSS_BUMPENVLOFFSET :
3516 case D3DTSS_TEXTURETRANSFORMFLAGS :
3517 case D3DTSS_RESULTARG :
3519 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3520 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3524 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3525 ICOM_THIS(IDirect3DDevice8Impl,iface);
3526 FIXME("(%p) : stub\n", This); return D3D_OK;
3528 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3529 ICOM_THIS(IDirect3DDevice8Impl,iface);
3530 FIXME("(%p) : stub\n", This); return D3D_OK;
3532 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3533 ICOM_THIS(IDirect3DDevice8Impl,iface);
3534 FIXME("(%p) : stub\n", This); return D3D_OK;
3536 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3537 ICOM_THIS(IDirect3DDevice8Impl,iface);
3538 FIXME("(%p) : stub\n", This); return D3D_OK;
3540 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3541 ICOM_THIS(IDirect3DDevice8Impl,iface);
3542 FIXME("(%p) : stub\n", This); return D3D_OK;
3544 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3545 ICOM_THIS(IDirect3DDevice8Impl,iface);
3546 FIXME("(%p) : stub\n", This); return D3D_OK;
3548 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3550 IDirect3DVertexBuffer8 *pVB;
3552 ICOM_THIS(IDirect3DDevice8Impl,iface);
3553 pVB = This->StateBlock->stream_source[0];
3555 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3557 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3558 This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
3562 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3563 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3565 IDirect3DIndexBuffer8 *pIB;
3566 IDirect3DVertexBuffer8 *pVB;
3567 D3DINDEXBUFFER_DESC IdxBufDsc;
3569 ICOM_THIS(IDirect3DDevice8Impl,iface);
3570 pIB = This->StateBlock->pIndexData;
3571 pVB = This->StateBlock->stream_source[0];
3573 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3574 minIndex, NumVertices, startIndex, primCount);
3576 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3577 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3583 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3584 This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3589 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3590 ICOM_THIS(IDirect3DDevice8Impl,iface);
3592 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3594 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3596 This->StateBlock->stream_source[0] = NULL;
3597 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3598 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock->VertexShader, pVertexStreamZeroData,
3600 This->StateBlock->stream_stride[0] = 0;
3602 /*stream zero settings set to null at end */
3605 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3606 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3607 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3608 UINT VertexStreamZeroStride) {
3610 ICOM_THIS(IDirect3DDevice8Impl,iface);
3611 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3612 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3614 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3615 if (IndexDataFormat == D3DFMT_INDEX16) {
3621 This->StateBlock->stream_source[0] = NULL;
3622 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3623 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock->VertexShader, pVertexStreamZeroData,
3624 This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3626 /*stream zero settings set to null at end */
3627 This->StateBlock->stream_stride[0] = 0;
3628 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3632 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3633 ICOM_THIS(IDirect3DDevice8Impl,iface);
3634 FIXME("(%p) : stub\n", This); return D3D_OK;
3636 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3637 ICOM_THIS(IDirect3DDevice8Impl,iface);
3638 IDirect3DVertexShaderImpl* object;
3639 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3643 TRACE("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3644 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3645 return D3DERR_INVALIDCALL;
3647 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
3648 if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
3649 return D3DERR_OUTOFVIDEOMEMORY;
3652 /** Create the Vertex Shader */
3653 res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
3654 /** TODO: check FAILED(res) */
3656 /** Create and Bind the Vertex Shader Declaration */
3657 res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
3658 /** TODO: check FAILED(res) */
3660 VertexShaders[i] = object;
3661 VertexShaderDeclarations[i] = attached_decl;
3662 *pHandle = VS_HIGHESTFIXEDFXF + i;
3666 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3667 ICOM_THIS(IDirect3DDevice8Impl,iface);
3669 This->UpdateStateBlock->VertexShader = Handle;
3670 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3671 This->UpdateStateBlock->Set.vertexShader = TRUE;
3673 if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
3674 FIXME("(%p) : Created shader, Handle=%lx\n", This, Handle);
3675 This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
3676 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3677 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3678 } else { /* use a fvf, so desactivate the vshader decl */
3679 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3680 This->UpdateStateBlock->vertexShaderDecl = NULL;
3681 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3682 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3684 /* Handle recording of state blocks */
3685 if (This->isRecordingState) {
3686 TRACE("Recording... not performing anything\n");
3690 * TODO: merge HAL shaders context switching from prototype
3694 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3695 ICOM_THIS(IDirect3DDevice8Impl,iface);
3696 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
3697 *pHandle = This->StateBlock->VertexShader;
3701 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3702 ICOM_THIS(IDirect3DDevice8Impl,iface);
3703 IDirect3DVertexShaderImpl* object;
3704 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3706 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3707 return D3DERR_INVALIDCALL;
3711 * Delete Vertex Shader
3713 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3714 if (NULL == object) {
3715 return D3DERR_INVALIDCALL;
3717 FIXME("(%p) : freing VertexShader %p\n", This, object);
3718 /* TODO: check validity of object */
3719 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3720 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3721 HeapFree(GetProcessHeap(), 0, (void *)object);
3722 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3725 * Delete Vertex Shader Declaration
3727 attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
3728 if (NULL == attached_decl) {
3729 return D3DERR_INVALIDCALL;
3731 FIXME("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
3732 /* TODO: check validity of object */
3733 HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
3734 HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
3735 VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3740 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3741 ICOM_THIS(IDirect3DDevice8Impl,iface);
3743 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3744 /*ERR("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);*/
3745 return D3DERR_INVALIDCALL;
3747 if (NULL == pConstantData) {
3748 return D3DERR_INVALIDCALL;
3750 if (ConstantCount > 1) {
3751 FLOAT* f = (FLOAT*)pConstantData;
3753 FIXME("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
3754 for (i = 0; i < ConstantCount; ++i) {
3755 DPRINTF("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
3759 FLOAT* f = (FLOAT*)pConstantData;
3760 FIXME("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
3762 This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
3763 memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
3766 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3767 ICOM_THIS(IDirect3DDevice8Impl,iface);
3769 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3770 return D3DERR_INVALIDCALL;
3772 if (NULL == pConstantData) {
3773 return D3DERR_INVALIDCALL;
3775 memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
3778 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3779 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3780 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3782 attached_decl = VERTEX_SHADER_DECL(Handle);
3783 if (NULL == attached_decl) {
3784 return D3DERR_INVALIDCALL;
3786 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
3788 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3789 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3790 IDirect3DVertexShaderImpl* object;
3792 object = VERTEX_SHADER(Handle);
3793 if (NULL == object) {
3794 return D3DERR_INVALIDCALL;
3796 return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
3799 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
3800 ICOM_THIS(IDirect3DDevice8Impl,iface);
3801 IDirect3DIndexBuffer8 *oldIdxs;
3803 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3804 oldIdxs = This->StateBlock->pIndexData;
3806 This->UpdateStateBlock->Changed.Indices = TRUE;
3807 This->UpdateStateBlock->Set.Indices = TRUE;
3808 This->UpdateStateBlock->pIndexData = pIndexData;
3809 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3811 /* Handle recording of state blocks */
3812 if (This->isRecordingState) {
3813 TRACE("Recording... not performing anything\n");
3817 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3818 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
3821 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3822 ICOM_THIS(IDirect3DDevice8Impl,iface);
3823 FIXME("(%p) : stub\n", This);
3825 *ppIndexData = This->StateBlock->pIndexData;
3826 /* up ref count on ppindexdata */
3827 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3828 *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
3832 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3833 ICOM_THIS(IDirect3DDevice8Impl,iface);
3834 IDirect3DPixelShaderImpl* object;
3837 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3838 if (NULL == pFunction || NULL == pHandle) {
3839 return D3DERR_INVALIDCALL;
3841 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
3842 if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
3843 return D3DERR_OUTOFVIDEOMEMORY;
3845 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
3846 if (NULL == object) {
3847 return D3DERR_OUTOFVIDEOMEMORY;
3850 object->data = NULL; /* TODO */
3852 PixelShaders[i] = object;
3853 *pHandle = VS_HIGHESTFIXEDFXF + i;
3855 object->function = pFunction;
3856 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3857 object->functionLength = i + 1;
3861 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3862 ICOM_THIS(IDirect3DDevice8Impl,iface);
3864 This->UpdateStateBlock->PixelShader = Handle;
3865 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3866 This->UpdateStateBlock->Set.pixelShader = TRUE;
3868 /* Handle recording of state blocks */
3869 if (This->isRecordingState) {
3870 TRACE("Recording... not performing anything\n");
3874 /* FIXME: Quieten when not being used */
3876 FIXME("(%p) : stub %ld\n", This, Handle);
3878 TRACE("(%p) : stub %ld\n", This, Handle);
3883 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3884 ICOM_THIS(IDirect3DDevice8Impl,iface);
3885 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
3886 *pHandle = This->StateBlock->PixelShader;
3890 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3891 ICOM_THIS(IDirect3DDevice8Impl,iface);
3892 IDirect3DPixelShaderImpl* object;
3894 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3895 return D3DERR_INVALIDCALL;
3897 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3898 TRACE("(%p) : freeing PixelShader %p\n", This, object);
3899 /* TODO: check validity of object before free */
3900 HeapFree(GetProcessHeap(), 0, (void *)object);
3901 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3905 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
3906 ICOM_THIS(IDirect3DDevice8Impl,iface);
3907 FIXME("(%p) : stub\n", This);
3910 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
3911 ICOM_THIS(IDirect3DDevice8Impl,iface);
3912 FIXME("(%p) : stub\n", This);
3915 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3916 ICOM_THIS(IDirect3DDevice8Impl,iface);
3917 IDirect3DPixelShaderImpl* object;
3919 object = PIXEL_SHADER(Handle);
3920 if (NULL == object) {
3921 return D3DERR_INVALIDCALL;
3923 if (NULL == pData) {
3924 *pSizeOfData = object->functionLength;
3927 if (*pSizeOfData < object->functionLength) {
3928 *pSizeOfData = object->functionLength;
3929 return D3DERR_MOREDATA;
3931 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
3932 memcpy(pData, object->function, object->functionLength);
3935 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3936 ICOM_THIS(IDirect3DDevice8Impl,iface);
3937 FIXME("(%p) : stub\n", This); return D3D_OK;
3939 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3940 ICOM_THIS(IDirect3DDevice8Impl,iface);
3941 FIXME("(%p) : stub\n", This); return D3D_OK;
3943 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3944 ICOM_THIS(IDirect3DDevice8Impl,iface);
3945 FIXME("(%p) : stub\n", This); return D3D_OK;
3948 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3949 IDirect3DVertexBuffer8 *oldSrc;
3950 ICOM_THIS(IDirect3DDevice8Impl,iface);
3952 oldSrc = This->StateBlock->stream_source[StreamNumber];
3953 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3955 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3956 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3957 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3958 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3960 /* Handle recording of state blocks */
3961 if (This->isRecordingState) {
3962 TRACE("Recording... not performing anything\n");
3966 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3967 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3970 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3971 ICOM_THIS(IDirect3DDevice8Impl,iface);
3972 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
3973 *pStream = This->StateBlock->stream_source[StreamNumber];
3974 *pStride = This->StateBlock->stream_stride[StreamNumber];
3975 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3980 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3982 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3983 IDirect3DDevice8Impl_QueryInterface,
3984 IDirect3DDevice8Impl_AddRef,
3985 IDirect3DDevice8Impl_Release,
3986 IDirect3DDevice8Impl_TestCooperativeLevel,
3987 IDirect3DDevice8Impl_GetAvailableTextureMem,
3988 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3989 IDirect3DDevice8Impl_GetDirect3D,
3990 IDirect3DDevice8Impl_GetDeviceCaps,
3991 IDirect3DDevice8Impl_GetDisplayMode,
3992 IDirect3DDevice8Impl_GetCreationParameters,
3993 IDirect3DDevice8Impl_SetCursorProperties,
3994 IDirect3DDevice8Impl_SetCursorPosition,
3995 IDirect3DDevice8Impl_ShowCursor,
3996 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3997 IDirect3DDevice8Impl_Reset,
3998 IDirect3DDevice8Impl_Present,
3999 IDirect3DDevice8Impl_GetBackBuffer,
4000 IDirect3DDevice8Impl_GetRasterStatus,
4001 IDirect3DDevice8Impl_SetGammaRamp,
4002 IDirect3DDevice8Impl_GetGammaRamp,
4003 IDirect3DDevice8Impl_CreateTexture,
4004 IDirect3DDevice8Impl_CreateVolumeTexture,
4005 IDirect3DDevice8Impl_CreateCubeTexture,
4006 IDirect3DDevice8Impl_CreateVertexBuffer,
4007 IDirect3DDevice8Impl_CreateIndexBuffer,
4008 IDirect3DDevice8Impl_CreateRenderTarget,
4009 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4010 IDirect3DDevice8Impl_CreateImageSurface,
4011 IDirect3DDevice8Impl_CopyRects,
4012 IDirect3DDevice8Impl_UpdateTexture,
4013 IDirect3DDevice8Impl_GetFrontBuffer,
4014 IDirect3DDevice8Impl_SetRenderTarget,
4015 IDirect3DDevice8Impl_GetRenderTarget,
4016 IDirect3DDevice8Impl_GetDepthStencilSurface,
4017 IDirect3DDevice8Impl_BeginScene,
4018 IDirect3DDevice8Impl_EndScene,
4019 IDirect3DDevice8Impl_Clear,
4020 IDirect3DDevice8Impl_SetTransform,
4021 IDirect3DDevice8Impl_GetTransform,
4022 IDirect3DDevice8Impl_MultiplyTransform,
4023 IDirect3DDevice8Impl_SetViewport,
4024 IDirect3DDevice8Impl_GetViewport,
4025 IDirect3DDevice8Impl_SetMaterial,
4026 IDirect3DDevice8Impl_GetMaterial,
4027 IDirect3DDevice8Impl_SetLight,
4028 IDirect3DDevice8Impl_GetLight,
4029 IDirect3DDevice8Impl_LightEnable,
4030 IDirect3DDevice8Impl_GetLightEnable,
4031 IDirect3DDevice8Impl_SetClipPlane,
4032 IDirect3DDevice8Impl_GetClipPlane,
4033 IDirect3DDevice8Impl_SetRenderState,
4034 IDirect3DDevice8Impl_GetRenderState,
4035 IDirect3DDevice8Impl_BeginStateBlock,
4036 IDirect3DDevice8Impl_EndStateBlock,
4037 IDirect3DDevice8Impl_ApplyStateBlock,
4038 IDirect3DDevice8Impl_CaptureStateBlock,
4039 IDirect3DDevice8Impl_DeleteStateBlock,
4040 IDirect3DDevice8Impl_CreateStateBlock,
4041 IDirect3DDevice8Impl_SetClipStatus,
4042 IDirect3DDevice8Impl_GetClipStatus,
4043 IDirect3DDevice8Impl_GetTexture,
4044 IDirect3DDevice8Impl_SetTexture,
4045 IDirect3DDevice8Impl_GetTextureStageState,
4046 IDirect3DDevice8Impl_SetTextureStageState,
4047 IDirect3DDevice8Impl_ValidateDevice,
4048 IDirect3DDevice8Impl_GetInfo,
4049 IDirect3DDevice8Impl_SetPaletteEntries,
4050 IDirect3DDevice8Impl_GetPaletteEntries,
4051 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4052 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4053 IDirect3DDevice8Impl_DrawPrimitive,
4054 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4055 IDirect3DDevice8Impl_DrawPrimitiveUP,
4056 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4057 IDirect3DDevice8Impl_ProcessVertices,
4058 IDirect3DDevice8Impl_CreateVertexShader,
4059 IDirect3DDevice8Impl_SetVertexShader,
4060 IDirect3DDevice8Impl_GetVertexShader,
4061 IDirect3DDevice8Impl_DeleteVertexShader,
4062 IDirect3DDevice8Impl_SetVertexShaderConstant,
4063 IDirect3DDevice8Impl_GetVertexShaderConstant,
4064 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4065 IDirect3DDevice8Impl_GetVertexShaderFunction,
4066 IDirect3DDevice8Impl_SetStreamSource,
4067 IDirect3DDevice8Impl_GetStreamSource,
4068 IDirect3DDevice8Impl_SetIndices,
4069 IDirect3DDevice8Impl_GetIndices,
4070 IDirect3DDevice8Impl_CreatePixelShader,
4071 IDirect3DDevice8Impl_SetPixelShader,
4072 IDirect3DDevice8Impl_GetPixelShader,
4073 IDirect3DDevice8Impl_DeletePixelShader,
4074 IDirect3DDevice8Impl_SetPixelShaderConstant,
4075 IDirect3DDevice8Impl_GetPixelShaderConstant,
4076 IDirect3DDevice8Impl_GetPixelShaderFunction,
4077 IDirect3DDevice8Impl_DrawRectPatch,
4078 IDirect3DDevice8Impl_DrawTriPatch,
4079 IDirect3DDevice8Impl_DeletePatch