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) {
831 case D3DFMT_A4R4G4B4: retVal = 2; break;
832 case D3DFMT_A8R8G8B8: retVal = 4; break;
833 case D3DFMT_X8R8G8B8: retVal = 4; break;
834 case D3DFMT_R8G8B8: retVal = 3; break;
835 case D3DFMT_R5G6B5: retVal = 2; break;
836 case D3DFMT_A1R5G5B5: retVal = 2; break;
838 /* Guess at the highest value of the above */
839 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt);
843 FIXME("Unhandled fmt %d\n", fmt);
846 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
850 GLint fmt2glintFmt(D3DFORMAT fmt) {
854 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
855 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
856 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
857 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
858 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
859 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
861 FIXME("Unhandled fmt %d\n", fmt);
864 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
867 GLenum fmt2glFmt(D3DFORMAT fmt) {
871 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
872 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
873 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
874 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
875 case D3DFMT_R5G6B5: retVal = GL_BGR; break;
876 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
878 FIXME("Unhandled fmt %d\n", fmt);
881 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
884 DWORD fmt2glType(D3DFORMAT fmt) {
888 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
889 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
890 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
891 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
892 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
893 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
895 FIXME("Unhandled fmt %d\n", fmt);
898 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
902 int SOURCEx_RGB_EXT(DWORD arg) {
904 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
905 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
906 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
907 case D3DTSS_ALPHAARG0:
908 case D3DTSS_ALPHAARG1:
909 case D3DTSS_ALPHAARG2:
911 FIXME("Invalid arg %ld\n", arg);
912 return GL_SOURCE0_RGB_EXT;
915 int OPERANDx_RGB_EXT(DWORD arg) {
917 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
918 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
919 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
920 case D3DTSS_ALPHAARG0:
921 case D3DTSS_ALPHAARG1:
922 case D3DTSS_ALPHAARG2:
924 FIXME("Invalid arg %ld\n", arg);
925 return GL_OPERAND0_RGB_EXT;
928 int SOURCEx_ALPHA_EXT(DWORD arg) {
930 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
931 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
932 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
933 case D3DTSS_COLORARG0:
934 case D3DTSS_COLORARG1:
935 case D3DTSS_COLORARG2:
937 FIXME("Invalid arg %ld\n", arg);
938 return GL_SOURCE0_ALPHA_EXT;
941 int OPERANDx_ALPHA_EXT(DWORD arg) {
943 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
944 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
945 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
946 case D3DTSS_COLORARG0:
947 case D3DTSS_COLORARG1:
948 case D3DTSS_COLORARG2:
950 FIXME("Invalid arg %ld\n", arg);
951 return GL_OPERAND0_ALPHA_EXT;
954 GLenum StencilOp(DWORD op) {
956 case D3DSTENCILOP_KEEP : return GL_KEEP;
957 case D3DSTENCILOP_ZERO : return GL_ZERO;
958 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
959 case D3DSTENCILOP_INCRSAT : return GL_INCR;
960 case D3DSTENCILOP_DECRSAT : return GL_DECR;
961 case D3DSTENCILOP_INVERT : return GL_INVERT;
962 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op %ld\n", op);
963 return GL_INCR; /* Fixme - needs to support wrap */
964 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op %ld\n", op);
965 return GL_DECR; /* Fixme - needs to support wrap */
967 FIXME("Invalid stencil op %ld\n", op);
972 /* Apply the current values to the specified texture stage */
973 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
974 ICOM_THIS(IDirect3DDevice8Impl,iface);
978 /* Make appropriate texture active */
979 if (This->isMultiTexture) {
980 #if defined(GL_VERSION_1_3)
981 glActiveTexture(GL_TEXTURE0 + Stage);
983 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
985 checkGLcall("glActiveTextureARB");
986 } else if (Stage > 0) {
987 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
990 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
991 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
992 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
995 /* Note the D3DRS value applies to all textures, but GL has one
996 per texture, so apply it now ready to be used! */
997 col[0] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
998 col[1] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
999 col[2] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
1000 col[3] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
1001 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1002 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1004 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
1007 /* IDirect3D IUnknown parts follow: */
1008 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
1010 ICOM_THIS(IDirect3DDevice8Impl,iface);
1012 if (IsEqualGUID(riid, &IID_IUnknown)
1013 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
1014 IDirect3DDevice8Impl_AddRef(iface);
1019 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
1020 return E_NOINTERFACE;
1023 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
1024 ICOM_THIS(IDirect3DDevice8Impl,iface);
1025 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
1026 return ++(This->ref);
1029 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
1030 ICOM_THIS(IDirect3DDevice8Impl,iface);
1031 ULONG ref = --This->ref;
1032 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
1034 HeapFree(GetProcessHeap(), 0, This);
1039 /* IDirect3DDevice Interface follow: */
1040 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
1041 ICOM_THIS(IDirect3DDevice8Impl,iface);
1042 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
1046 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
1047 ICOM_THIS(IDirect3DDevice8Impl,iface);
1048 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
1050 * pretend we have 32MB of any type of memory queried.
1052 return (1024*1024*32);
1055 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
1056 ICOM_THIS(IDirect3DDevice8Impl,iface);
1057 FIXME("(%p) : stub\n", This); return D3D_OK;
1059 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
1060 ICOM_THIS(IDirect3DDevice8Impl,iface);
1061 TRACE("(%p) : returning %p\n", This, This->direct3d8);
1064 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
1066 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
1069 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
1070 ICOM_THIS(IDirect3DDevice8Impl,iface);
1071 FIXME("(%p) : stub, calling idirect3d for now\n", This);
1072 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
1075 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
1080 ICOM_THIS(IDirect3DDevice8Impl,iface);
1081 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
1082 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
1083 pMode->RefreshRate = 85; /*FIXME: How to identify? */
1085 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1086 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1090 case 8: pMode->Format = D3DFMT_R8G8B8; break;
1091 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1092 case 24: pMode->Format = D3DFMT_R8G8B8; break;
1093 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1095 FIXME("Unrecognized display mode format\n");
1096 pMode->Format = D3DFMT_UNKNOWN;
1099 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
1102 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1103 ICOM_THIS(IDirect3DDevice8Impl,iface);
1104 TRACE("(%p) copying to %p\n", This, pParameters);
1105 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1108 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1109 ICOM_THIS(IDirect3DDevice8Impl,iface);
1110 FIXME("(%p) : stub\n", This); return D3D_OK;
1112 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1113 ICOM_THIS(IDirect3DDevice8Impl,iface);
1114 FIXME("(%p) : stub\n", This); return;
1116 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1117 ICOM_THIS(IDirect3DDevice8Impl,iface);
1118 FIXME("(%p) : stub\n", This); return D3D_OK;
1120 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1121 ICOM_THIS(IDirect3DDevice8Impl,iface);
1122 FIXME("(%p) : stub\n", This); return D3D_OK;
1124 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1125 ICOM_THIS(IDirect3DDevice8Impl,iface);
1126 FIXME("(%p) : stub\n", This); return D3D_OK;
1128 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1129 ICOM_THIS(IDirect3DDevice8Impl,iface);
1130 TRACE("(%p) : complete stub!\n", This);
1134 glXSwapBuffers(This->display, This->win);
1135 checkGLcall("glXSwapBuffers");
1141 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) {
1142 ICOM_THIS(IDirect3DDevice8Impl,iface);
1143 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1144 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1146 /* Note inc ref on returned surface */
1147 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1151 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1152 ICOM_THIS(IDirect3DDevice8Impl,iface);
1153 FIXME("(%p) : stub\n", This); return D3D_OK;
1155 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1156 ICOM_THIS(IDirect3DDevice8Impl,iface);
1157 FIXME("(%p) : stub\n", This); return;
1159 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1160 ICOM_THIS(IDirect3DDevice8Impl,iface);
1161 FIXME("(%p) : stub\n", This); return;
1163 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1164 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1165 IDirect3DTexture8Impl *object;
1170 ICOM_THIS(IDirect3DDevice8Impl,iface);
1172 /* Allocate the storage for the device */
1173 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
1174 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1175 object->lpVtbl = &Direct3DTexture8_Vtbl;
1176 object->Device = This; /* FIXME: AddRef(This) */
1177 object->ResourceType = D3DRTYPE_TEXTURE;
1179 object->width = Width;
1180 object->height = Height;
1181 object->levels = Levels;
1182 object->usage = Usage;
1183 object->format = Format;
1184 object->device = This;
1186 /* Calculate levels for mip mapping */
1191 while (tmpW > 1 && tmpH > 1) {
1192 tmpW = max(1,tmpW / 2);
1193 tmpH = max(1, tmpH / 2);
1196 TRACE("Calculated levels = %d\n", object->levels);
1199 /* Generate all the surfaces */
1202 for (i=0; i<object->levels; i++)
1204 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1205 object->surfaces[i]->Container = (IUnknown*) object; /* FIXME: AddRef(object) */
1206 object->surfaces[i]->myDesc.Usage = Usage;
1207 object->surfaces[i]->myDesc.Pool = Pool ;
1209 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1210 tmpW = max(1, tmpW / 2);
1211 tmpH = max(1, tmpH / 2);
1214 *ppTexture = (LPDIRECT3DTEXTURE8)object;
1217 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1219 IDirect3DVolumeTexture8Impl *object;
1225 ICOM_THIS(IDirect3DDevice8Impl,iface);
1227 /* Allocate the storage for it */
1228 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);
1229 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1230 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1231 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1235 object->width = Width;
1236 object->height = Height;
1237 object->depth = Depth;
1238 object->levels = Levels;
1239 object->usage = Usage;
1240 object->format = Format;
1241 object->device = This;
1243 /* Calculate levels for mip mapping */
1249 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1250 tmpW = max(1,tmpW / 2);
1251 tmpH = max(1, tmpH / 2);
1252 tmpD = max(1, tmpD / 2);
1255 TRACE("Calculated levels = %d\n", object->levels);
1258 /* Generate all the surfaces */
1263 for (i=0; i<object->levels; i++)
1265 IDirect3DVolume8Impl *volume;
1267 /* Create the volume - No entry point for this seperately?? */
1268 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1269 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1271 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1272 volume->Device = This; /* FIXME: AddRef(This) */
1273 volume->ResourceType = D3DRTYPE_VOLUME;
1274 volume->Container = object;
1277 volume->myDesc.Width = Width;
1278 volume->myDesc.Height= Height;
1279 volume->myDesc.Depth = Depth;
1280 volume->myDesc.Format= Format;
1281 volume->myDesc.Type = D3DRTYPE_VOLUME;
1282 volume->myDesc.Pool = Pool;
1283 volume->myDesc.Usage = Usage;
1284 volume->bytesPerPixel = bytesPerPixel(Format);
1285 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1286 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1288 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
1289 volume, volume->allocatedMemory, volume->myDesc.Size);
1291 tmpW = max(1,tmpW / 2);
1292 tmpH = max(1, tmpH / 2);
1293 tmpD = max(1, tmpD / 2);
1296 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8)object;
1299 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) {
1301 IDirect3DCubeTexture8Impl *object;
1302 ICOM_THIS(IDirect3DDevice8Impl,iface);
1306 /* Allocate the storage for it */
1307 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
1308 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1309 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1311 object->Device = This; /* FIXME: AddRef(This) */
1312 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1314 object->edgeLength = EdgeLength;
1315 object->levels = Levels;
1316 object->usage = Usage;
1317 object->format = Format;
1318 object->device = This;
1320 /* Calculate levels for mip mapping */
1325 tmpW = max(1,tmpW / 2);
1328 TRACE("Calculated levels = %d\n", object->levels);
1331 /* Generate all the surfaces */
1333 for (i=0; i<object->levels; i++)
1335 /* Create the 6 faces */
1337 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1338 object->surfaces[j][i]->Container = (IUnknown*) object;
1339 object->surfaces[j][i]->myDesc.Usage = Usage;
1340 object->surfaces[j][i]->myDesc.Pool = Pool ;
1342 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1343 tmpW = max(1,tmpW / 2);
1347 TRACE("(%p) : Iface@%p\n", This, object);
1348 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1351 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage,
1352 DWORD FVF,D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1353 IDirect3DVertexBuffer8Impl *object;
1355 ICOM_THIS(IDirect3DDevice8Impl,iface);
1357 /* Allocate the storage for the device */
1358 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1359 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1360 object->Device = This;
1361 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1363 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1364 object->currentDesc.Usage = Usage;
1365 object->currentDesc.Pool = Pool;
1366 object->currentDesc.FVF = FVF;
1367 object->currentDesc.Size = Size;
1369 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1371 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1375 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) {
1377 IDirect3DIndexBuffer8Impl *object;
1379 ICOM_THIS(IDirect3DDevice8Impl,iface);
1380 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
1382 /* Allocate the storage for the device */
1383 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1384 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1386 object->Device = This;
1387 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1389 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1390 object->currentDesc.Usage = Usage;
1391 object->currentDesc.Pool = Pool;
1392 object->currentDesc.Format = Format;
1393 object->currentDesc.Size = Length;
1395 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1397 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1399 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1403 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) {
1404 ICOM_THIS(IDirect3DDevice8Impl,iface);
1405 /* up ref count on surface, surface->container = This */
1406 FIXME("(%p) : stub\n", This); return D3D_OK;
1408 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) {
1409 ICOM_THIS(IDirect3DDevice8Impl,iface);
1410 /* surface->container = This */
1411 FIXME("(%p) : stub\n", This); return D3D_OK;
1413 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) {
1414 IDirect3DSurface8Impl *object;
1416 ICOM_THIS(IDirect3DDevice8Impl,iface);
1418 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1419 *ppSurface = (LPDIRECT3DSURFACE8) object;
1420 object->lpVtbl = &Direct3DSurface8_Vtbl;
1421 object->Device = This;
1422 object->ResourceType = D3DRTYPE_SURFACE;
1423 object->Container = (IUnknown*) This;
1426 object->myDesc.Width = Width;
1427 object->myDesc.Height= Height;
1428 object->myDesc.Format= Format;
1429 object->myDesc.Type = D3DRTYPE_SURFACE;
1430 /*object->myDesc.Usage */
1431 object->myDesc.Pool = D3DPOOL_SYSTEMMEM ;
1432 object->bytesPerPixel = bytesPerPixel(Format);
1433 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1434 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1436 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);
1439 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1440 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1442 HRESULT rc = D3D_OK;
1443 IDirect3DBaseTexture8* texture = NULL;
1446 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
1447 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1449 ICOM_THIS(IDirect3DDevice8Impl,iface);
1450 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1451 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1453 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1454 a sample and doesnt seem to break anything as far as I can tell */
1455 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1456 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1457 rc = D3DERR_INVALIDCALL;
1459 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1460 TRACE("Converting dest to same format as source, since dest was unknown\n");
1461 dst->myDesc.Format = src->myDesc.Format;
1463 /* Convert container as well */
1464 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1465 if (texture != NULL) {
1467 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1468 case D3DRTYPE_TEXTURE:
1469 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1471 case D3DRTYPE_VOLUMETEXTURE:
1472 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1474 case D3DRTYPE_CUBETEXTURE:
1475 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1478 FIXME("Unhandled texture type\n");
1481 /** Releasing texture after GetContainer */
1482 IDirect3DBaseTexture8_Release(texture);
1486 /* Quick if complete copy ... */
1487 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1488 src->myDesc.Width == dst->myDesc.Width &&
1489 src->myDesc.Height == dst->myDesc.Height)) {
1490 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1491 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1495 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1496 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1497 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1499 char *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1500 char *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1502 /* Copy rect by rect */
1503 for (i=0; i<cRects; i++) {
1504 CONST RECT *r = &pSourceRectsArray[i];
1505 CONST POINT *p = &pDestPointsArray[i];
1508 int copyperline = (r->right - r->left) * bytesPerPixel;
1511 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top,
1512 r->right, r->bottom, p->x, p->y);
1514 /* Find where to start */
1515 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1516 to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel);
1518 /* Copy line by line */
1519 for (j=0; j<(r->bottom - r->top); j++) {
1520 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1527 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1528 if (texture != NULL) {
1530 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1531 case D3DRTYPE_TEXTURE:
1533 IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)texture;
1534 pTexture->Dirty = TRUE;
1537 case D3DRTYPE_VOLUMETEXTURE:
1539 IDirect3DVolumeTexture8Impl *pTexture = (IDirect3DVolumeTexture8Impl *)texture;
1540 pTexture->Dirty = TRUE;
1543 case D3DRTYPE_CUBETEXTURE:
1545 IDirect3DCubeTexture8Impl *pTexture = (IDirect3DCubeTexture8Impl *)texture;
1546 pTexture->Dirty = TRUE;
1550 FIXME("Unhandled texture type\n");
1553 /** Releasing texture after GetContainer */
1554 IDirect3DBaseTexture8_Release(texture);
1560 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) {
1561 ICOM_THIS(IDirect3DDevice8Impl,iface);
1562 FIXME("(%p) : stub\n", This); return D3D_OK;
1564 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1565 ICOM_THIS(IDirect3DDevice8Impl,iface);
1566 FIXME("(%p) : stub\n", This); return D3D_OK;
1568 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) {
1569 ICOM_THIS(IDirect3DDevice8Impl,iface);
1570 FIXME("(%p) : stub\n", This);
1574 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1575 ICOM_THIS(IDirect3DDevice8Impl,iface);
1576 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1577 FIXME("(%p) : stub\n", This);
1580 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1581 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1586 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1588 ICOM_THIS(IDirect3DDevice8Impl,iface);
1590 /* Note inc ref on returned surface *
1591 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1593 FIXME("(%p) : stub\n", This);
1597 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1598 ICOM_THIS(IDirect3DDevice8Impl,iface);
1599 TRACE("(%p) : stub\n", This);
1602 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1603 ICOM_THIS(IDirect3DDevice8Impl,iface);
1604 TRACE("(%p)\n", This);
1609 checkGLcall("glFlush");
1611 /* Useful for debugging sometimes!
1612 printf("Hit Enter ...\n");
1618 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1619 ICOM_THIS(IDirect3DDevice8Impl,iface);
1621 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1622 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1623 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1624 GLbitfield glMask = 0;
1626 CONST D3DRECT *curRect;
1628 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1629 Count, pRects, Flags, Z, Stencil);
1632 if (Count > 0 && pRects) {
1633 glEnable(GL_SCISSOR_TEST);
1634 checkGLcall("glEnable GL_SCISSOR_TEST");
1640 for (i=0;i<Count || i==0; i++) {
1643 /* Note gl uses lower left, width/height */
1644 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1645 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1646 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1647 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1648 checkGLcall("glScissor");
1651 /* Clear the whole screen */
1652 if (Flags & D3DCLEAR_STENCIL) {
1653 glClearStencil(Stencil);
1654 checkGLcall("glClearStencil");
1655 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1658 if (Flags & D3DCLEAR_ZBUFFER) {
1660 checkGLcall("glClearDepth");
1661 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1664 if (Flags & D3DCLEAR_TARGET) {
1665 TRACE("Clearing screen with glClear to color %lx\n", Color);
1666 glClearColor(((Color >> 16) & 0xFF) / 255.0, ((Color >> 8) & 0xFF) / 255.0,
1667 ((Color >> 0) & 0xFF) / 255.0, ((Color >> 24) & 0xFF) / 255.0);
1668 checkGLcall("glClearColor");
1669 glMask = glMask | GL_COLOR_BUFFER_BIT;
1673 checkGLcall("glClear");
1675 if (curRect) curRect = curRect + sizeof(D3DRECT);
1678 if (Count > 0 && pRects) {
1679 glDisable(GL_SCISSOR_TEST);
1680 checkGLcall("glDisable");
1686 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
1687 ICOM_THIS(IDirect3DDevice8Impl,iface);
1692 /* Most of this routine, comments included copied from ddraw tree initially: */
1693 TRACE("(%p) : State=%d\n", This, d3dts);
1695 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1696 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1697 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1699 /* Handle recording of state blocks */
1700 if (This->isRecordingState) {
1701 TRACE("Recording... not performing anything\n");
1706 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1708 where ViewMat = Camera space, WorldMat = world space.
1710 In OpenGL, camera and world space is combined into GL_MODELVIEW
1711 matrix. The Projection matrix stay projection matrix. */
1713 /* After reading through both OpenGL and Direct3D documentations, I
1714 thought that D3D matrices were written in 'line major mode' transposed
1715 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1716 works fine to transfer one matrix format to the other (it did not work
1717 when transposing)....
1720 1) are the documentations wrong
1721 2) does the matrix work even if they are not read correctly
1722 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1723 loading using glLoadMatrix ?
1725 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1726 to the other so that if I ever find out that I need to transpose them, I
1727 will able to do it quickly, only by changing the macro conv_mat. */
1731 case D3DTS_WORLDMATRIX(0):
1732 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)]);
1736 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_VIEW]);
1739 case D3DTS_PROJECTION:
1740 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_PROJECTION]);
1743 case D3DTS_TEXTURE0:
1744 case D3DTS_TEXTURE1:
1745 case D3DTS_TEXTURE2:
1746 case D3DTS_TEXTURE3:
1747 case D3DTS_TEXTURE4:
1748 case D3DTS_TEXTURE5:
1749 case D3DTS_TEXTURE6:
1750 case D3DTS_TEXTURE7:
1751 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
1752 FIXME("Unhandled transform state for TEXTURE%d!!!\n", d3dts - D3DTS_TEXTURE0);
1753 FIXME("must use glMatrixMode(GL_TEXTURE) before texturing\n");
1757 FIXME("Unhandled transform state!!\n");
1762 * Indexed Vertex Blending Matrices 256 -> 511
1765 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
1766 if (checkGLSupport(ARB_VERTEX_BLEND)) {
1768 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
1774 * Move the GL operation to outside of switch to make it work
1775 * regardless of transform set order. Optimize later.
1778 glMatrixMode(GL_PROJECTION);
1779 checkGLcall("glMatrixMode");
1780 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
1781 checkGLcall("glLoadMatrixf");
1783 glMatrixMode(GL_MODELVIEW);
1784 checkGLcall("glMatrixMode");
1785 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
1786 checkGLcall("glLoadMatrixf");
1788 /* If we are changing the View matrix, reset the light and clipping planes to the new view */
1789 if (d3dts == D3DTS_VIEW) {
1791 /* NOTE: We have to reset the positions even if the light/plane is not currently
1792 enabled, since the call to enable it will not reset the position. */
1795 for (k = 0; k < This->maxLights; k++) {
1796 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
1797 checkGLcall("glLightfv posn");
1798 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
1799 checkGLcall("glLightfv dirn");
1802 /* Reset Clipping Planes if clipping is enabled */
1803 for (k = 0; k < This->clipPlanes; k++) {
1804 glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
1805 checkGLcall("glClipPlane");
1811 * Vertex Blending as described
1812 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/enums/d3dvertexblendflags.asp
1814 switch (This->UpdateStateBlock->vertex_blend) {
1815 case D3DVBF_DISABLE:
1817 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
1818 checkGLcall("glMultMatrixf");
1821 case D3DVBF_1WEIGHTS:
1822 case D3DVBF_2WEIGHTS:
1823 case D3DVBF_3WEIGHTS:
1825 FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n");
1827 * doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*)
1828 * so waiting for the values before matrix work
1829 for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
1830 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
1831 checkGLcall("glMultMatrixf");
1836 case D3DVBF_TWEENING:
1838 FIXME("valid/correct D3DVBF_TWEENING\n");
1839 f = This->UpdateStateBlock->tween_factor;
1840 m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f;
1841 m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f;
1842 m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f;
1843 m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
1844 glMultMatrixf((float *) &m.u.m[0][0]);
1845 checkGLcall("glMultMatrixf");
1848 case D3DVBF_0WEIGHTS:
1850 FIXME("valid/correct D3DVBF_0WEIGHTS\n");
1851 /* single matrix of weight 1.0f */
1852 m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f;
1853 m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f;
1854 m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f;
1855 m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
1856 glMultMatrixf((float *) &m.u.m[0][0]);
1857 checkGLcall("glMultMatrixf");
1861 break; /* stupid compilator */
1869 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1870 ICOM_THIS(IDirect3DDevice8Impl,iface);
1871 TRACE("(%p) : for State %d\n", This, State);
1872 memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX));
1876 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1877 ICOM_THIS(IDirect3DDevice8Impl,iface);
1878 FIXME("(%p) : stub\n", This); return D3D_OK;
1880 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1881 ICOM_THIS(IDirect3DDevice8Impl,iface);
1883 TRACE("(%p)\n", This);
1884 This->UpdateStateBlock->Changed.viewport = TRUE;
1885 This->UpdateStateBlock->Set.viewport = TRUE;
1886 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1888 /* Handle recording of state blocks */
1889 if (This->isRecordingState) {
1890 TRACE("Recording... not performing anything\n");
1894 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1895 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1897 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1898 checkGLcall("glDepthRange");
1899 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1900 glViewport(pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height);
1901 checkGLcall("glViewport");
1907 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1908 ICOM_THIS(IDirect3DDevice8Impl,iface);
1909 TRACE("(%p)\n", This);
1910 memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8));
1914 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1915 ICOM_THIS(IDirect3DDevice8Impl,iface);
1917 This->UpdateStateBlock->Changed.material = TRUE;
1918 This->UpdateStateBlock->Set.material = TRUE;
1919 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1921 /* Handle recording of state blocks */
1922 if (This->isRecordingState) {
1923 TRACE("Recording... not performing anything\n");
1928 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1929 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1930 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1931 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1932 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1934 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
1935 checkGLcall("glMaterialfv");
1936 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
1937 checkGLcall("glMaterialfv");
1939 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
1940 checkGLcall("glMaterialfv");
1941 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
1942 checkGLcall("glMaterialfv");
1943 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1944 checkGLcall("glMaterialf");
1949 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1950 ICOM_THIS(IDirect3DDevice8Impl,iface);
1951 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1952 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1953 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1954 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1955 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1956 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1960 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
1961 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1965 ICOM_THIS(IDirect3DDevice8Impl,iface);
1966 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1968 if (Index > This->maxLights) {
1969 FIXME("Cannot handle more lights than device supports\n");
1970 return D3DERR_INVALIDCALL;
1973 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,
1974 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1975 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1976 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1977 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1978 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1979 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1981 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1982 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1983 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1985 /* Handle recording of state blocks */
1986 if (This->isRecordingState) {
1987 TRACE("Recording... not performing anything\n");
1992 colRGBA[0] = pLight->Diffuse.r;
1993 colRGBA[1] = pLight->Diffuse.g;
1994 colRGBA[2] = pLight->Diffuse.b;
1995 colRGBA[3] = pLight->Diffuse.a;
1996 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1997 checkGLcall("glLightfv");
2000 colRGBA[0] = pLight->Specular.r;
2001 colRGBA[1] = pLight->Specular.g;
2002 colRGBA[2] = pLight->Specular.b;
2003 colRGBA[3] = pLight->Specular.a;
2004 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
2005 checkGLcall("glLightfv");
2008 colRGBA[0] = pLight->Ambient.r;
2009 colRGBA[1] = pLight->Ambient.g;
2010 colRGBA[2] = pLight->Ambient.b;
2011 colRGBA[3] = pLight->Ambient.a;
2012 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
2013 checkGLcall("glLightfv");
2015 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2016 glMatrixMode(GL_MODELVIEW);
2018 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2020 /* Attenuation - Are these right? guessing... */
2021 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
2022 checkGLcall("glLightf");
2023 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
2024 checkGLcall("glLightf");
2026 quad_att = 1.4/(pLight->Range*pLight->Range);
2027 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
2028 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
2029 checkGLcall("glLightf");
2031 switch (pLight->Type) {
2032 case D3DLIGHT_POINT:
2034 This->lightPosn[Index][0] = pLight->Position.x;
2035 This->lightPosn[Index][1] = pLight->Position.y;
2036 This->lightPosn[Index][2] = pLight->Position.z;
2037 This->lightPosn[Index][3] = 1.0;
2038 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2039 checkGLcall("glLightfv");
2041 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
2042 checkGLcall("glLightf");
2049 This->lightPosn[Index][0] = pLight->Position.x;
2050 This->lightPosn[Index][1] = pLight->Position.y;
2051 This->lightPosn[Index][2] = pLight->Position.z;
2052 This->lightPosn[Index][3] = 1.0;
2053 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2054 checkGLcall("glLightfv");
2057 This->lightDirn[Index][0] = pLight->Direction.x;
2058 This->lightDirn[Index][1] = pLight->Direction.y;
2059 This->lightDirn[Index][2] = pLight->Direction.z;
2060 This->lightDirn[Index][3] = 1.0;
2061 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
2062 checkGLcall("glLightfv");
2065 * opengl-ish and d3d-ish spot lights use too different models for the
2066 * light "intensity" as a function of the angle towards the main light direction,
2067 * so we only can approximate very roughly.
2068 * however spot lights are rather rarely used in games (if ever used at all).
2069 * furthermore if still used, probably nobody pays attention to such details.
2071 if (pLight->Falloff == 0) {
2074 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
2076 if (rho < 0.0001) rho = 0.0001f;
2077 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
2078 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
2082 case D3DLIGHT_DIRECTIONAL:
2084 This->lightPosn[Index][0] = -pLight->Direction.x;
2085 This->lightPosn[Index][1] = -pLight->Direction.y;
2086 This->lightPosn[Index][2] = -pLight->Direction.z;
2087 This->lightPosn[Index][3] = 0.0;
2088 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
2089 checkGLcall("glLightfv");
2091 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
2092 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
2097 FIXME("Unrecognized light type %d\n", pLight->Type);
2100 /* Restore the modelview matrix */
2105 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
2106 ICOM_THIS(IDirect3DDevice8Impl,iface);
2107 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2109 if (Index > This->maxLights) {
2110 FIXME("Cannot handle more lights than device supports\n");
2111 return D3DERR_INVALIDCALL;
2114 memcpy(pLight, &This->StateBlock->lights[Index], sizeof(D3DLIGHT8));
2117 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
2118 ICOM_THIS(IDirect3DDevice8Impl,iface);
2119 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
2121 if (Index > This->maxLights) {
2122 FIXME("Cannot handle more lights than device supports\n");
2123 return D3DERR_INVALIDCALL;
2126 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
2127 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
2128 This->UpdateStateBlock->lightEnable[Index] = Enable;
2130 /* Handle recording of state blocks */
2131 if (This->isRecordingState) {
2132 TRACE("Recording... not performing anything\n");
2137 glEnable(GL_LIGHT0+Index);
2138 checkGLcall("glEnable GL_LIGHT0+Index");
2140 glDisable(GL_LIGHT0+Index);
2141 checkGLcall("glDisable GL_LIGHT0+Index");
2145 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
2146 ICOM_THIS(IDirect3DDevice8Impl,iface);
2147 TRACE("(%p) : for idx(%ld)\n", This, Index);
2149 if (Index > This->maxLights) {
2150 FIXME("Cannot handle more lights than device supports\n");
2151 return D3DERR_INVALIDCALL;
2154 *pEnable = This->StateBlock->lightEnable[Index];
2157 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
2158 ICOM_THIS(IDirect3DDevice8Impl,iface);
2159 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
2161 /* Validate Index */
2162 if (Index >= This->clipPlanes ) {
2163 TRACE("Application has requested clipplane this device doesnt support\n");
2164 return D3DERR_INVALIDCALL;
2167 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
2168 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
2169 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
2170 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
2171 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
2172 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
2174 /* Handle recording of state blocks */
2175 if (This->isRecordingState) {
2176 TRACE("Recording... not performing anything\n");
2182 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2183 glMatrixMode(GL_MODELVIEW);
2185 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2187 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
2188 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
2189 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
2192 checkGLcall("glClipPlane");
2196 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
2197 ICOM_THIS(IDirect3DDevice8Impl,iface);
2198 TRACE("(%p) : for idx %ld\n", This, Index);
2200 /* Validate Index */
2201 if (Index >= This->clipPlanes ) {
2202 TRACE("Application has requested clipplane this device doesnt support\n");
2203 return D3DERR_INVALIDCALL;
2206 pPlane[0] = This->StateBlock->clipplane[Index][0];
2207 pPlane[1] = This->StateBlock->clipplane[Index][0];
2208 pPlane[2] = This->StateBlock->clipplane[Index][0];
2209 pPlane[3] = This->StateBlock->clipplane[Index][0];
2212 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
2213 ICOM_THIS(IDirect3DDevice8Impl,iface);
2214 DWORD OldValue = This->StateBlock->renderstate[State];
2216 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
2217 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2218 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2219 This->UpdateStateBlock->renderstate[State] = Value;
2221 /* Handle recording of state blocks */
2222 if (This->isRecordingState) {
2223 TRACE("Recording... not performing anything\n");
2228 case D3DRS_FILLMODE :
2229 switch ((D3DFILLMODE) Value) {
2230 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2231 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2232 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2234 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2236 checkGLcall("glPolygonMode (fillmode)");
2239 case D3DRS_LIGHTING :
2241 glEnable(GL_LIGHTING);
2242 checkGLcall("glEnable GL_LIGHTING");
2244 glDisable(GL_LIGHTING);
2245 checkGLcall("glDisable GL_LIGHTING");
2249 case D3DRS_ZENABLE :
2250 switch ((D3DZBUFFERTYPE) Value) {
2252 glDisable(GL_DEPTH_TEST);
2253 checkGLcall("glDisable GL_DEPTH_TEST");
2256 glEnable(GL_DEPTH_TEST);
2257 checkGLcall("glEnable GL_DEPTH_TEST");
2262 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2266 case D3DRS_CULLMODE :
2268 /* If we are culling "back faces with clockwise vertices" then
2269 set front faces to be counter clockwise and enable culling
2271 switch ((D3DCULL) Value) {
2273 glDisable(GL_CULL_FACE);
2274 checkGLcall("glDisable GL_CULL_FACE");
2277 glEnable(GL_CULL_FACE);
2278 checkGLcall("glEnable GL_CULL_FACE");
2279 glFrontFace(GL_CCW);
2280 checkGLcall("glFrontFace GL_CCW");
2281 glCullFace(GL_BACK);
2284 glEnable(GL_CULL_FACE);
2285 checkGLcall("glEnable GL_CULL_FACE");
2287 checkGLcall("glFrontFace GL_CW");
2288 glCullFace(GL_BACK);
2291 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2295 case D3DRS_SHADEMODE :
2296 switch ((D3DSHADEMODE) Value) {
2298 glShadeModel(GL_FLAT);
2299 checkGLcall("glShadeModel");
2301 case D3DSHADE_GOURAUD:
2302 glShadeModel(GL_SMOOTH);
2303 checkGLcall("glShadeModel");
2305 case D3DSHADE_PHONG:
2306 FIXME("D3DSHADE_PHONG isnt supported?\n");
2307 return D3DERR_INVALIDCALL;
2309 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
2313 case D3DRS_DITHERENABLE :
2315 glEnable(GL_DITHER);
2316 checkGLcall("glEnable GL_DITHER");
2318 glDisable(GL_DITHER);
2319 checkGLcall("glDisable GL_DITHER");
2323 case D3DRS_ZWRITEENABLE :
2326 checkGLcall("glDepthMask");
2329 checkGLcall("glDepthMask");
2335 int glParm = GL_LESS;
2337 switch ((D3DCMPFUNC) Value) {
2338 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2339 case D3DCMP_LESS: glParm=GL_LESS; break;
2340 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2341 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2342 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2343 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2344 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2345 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2347 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2349 glDepthFunc(glParm);
2350 checkGLcall("glDepthFunc");
2354 case D3DRS_AMBIENT :
2358 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2359 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2360 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2361 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2362 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
2363 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2364 checkGLcall("glLightModel for MODEL_AMBIENT");
2369 case D3DRS_ALPHABLENDENABLE :
2372 checkGLcall("glEnable GL_BLEND");
2374 glDisable(GL_BLEND);
2375 checkGLcall("glDisable GL_BLEND");
2379 case D3DRS_SRCBLEND :
2380 case D3DRS_DESTBLEND :
2382 int newVal = GL_ZERO;
2384 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2385 case D3DBLEND_ONE : newVal = GL_ONE; break;
2386 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2387 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2388 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2389 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2390 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2391 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2392 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2393 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2394 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2396 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2397 This->srcBlend = newVal;
2398 This->dstBlend = newVal;
2401 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2402 This->srcBlend = newVal;
2403 This->dstBlend = newVal;
2406 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
2409 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
2410 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
2411 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
2412 glBlendFunc(This->srcBlend, This->dstBlend);
2414 checkGLcall("glBlendFunc");
2418 case D3DRS_ALPHATESTENABLE :
2420 glEnable(GL_ALPHA_TEST);
2421 checkGLcall("glEnable GL_ALPHA_TEST");
2423 glDisable(GL_ALPHA_TEST);
2424 checkGLcall("glDisable GL_ALPHA_TEST");
2428 case D3DRS_ALPHAFUNC :
2430 int glParm = GL_LESS;
2433 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
2434 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
2436 switch ((D3DCMPFUNC) Value) {
2437 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2438 case D3DCMP_LESS: glParm=GL_LESS; break;
2439 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2440 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2441 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2442 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2443 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2444 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2446 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2448 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2449 glAlphaFunc(glParm, ref);
2450 checkGLcall("glAlphaFunc");
2454 case D3DRS_ALPHAREF :
2456 int glParm = GL_LESS;
2459 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
2460 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
2462 ref = ((float) Value) / 255.0;
2463 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2464 glAlphaFunc(glParm, ref);
2465 checkGLcall("glAlphaFunc");
2469 case D3DRS_CLIPPLANEENABLE :
2470 case D3DRS_CLIPPING :
2472 /* Ensure we only do the changed clip planes */
2473 DWORD enable = 0xFFFFFFFF;
2474 DWORD disable = 0x00000000;
2476 /* If enabling / disabling all */
2477 if (State == D3DRS_CLIPPING) {
2479 enable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2482 disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2486 enable = Value & ~OldValue;
2487 disable = ~Value & OldValue;
2490 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
2491 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
2492 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
2493 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
2494 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
2495 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
2497 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
2498 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
2499 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
2500 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
2501 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
2502 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
2506 case D3DRS_BLENDOP :
2508 int glParm = GL_FUNC_ADD;
2510 switch ((D3DBLENDOP) Value) {
2511 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
2512 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
2513 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
2514 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
2515 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
2517 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
2519 TRACE("glBlendEquation(%x)\n", glParm);
2520 glBlendEquation(glParm);
2521 checkGLcall("glBlendEquation");
2525 case D3DRS_TEXTUREFACTOR :
2529 /* Note the texture color applies to all textures whereas
2530 GL_TEXTURE_ENV_COLOR applies to active only */
2532 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2533 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2534 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2535 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2537 /* Set the default alpha blend color */
2538 glBlendColor(col[0], col[1], col[2], col[3]);
2539 checkGLcall("glBlendColor");
2541 /* And now the default texture color as well */
2542 for (i = 0; i < This->TextureUnits; i++) {
2544 /* Note the D3DRS value applies to all textures, but GL has one
2545 per texture, so apply it now ready to be used! */
2546 if (This->isMultiTexture) {
2547 #if defined(GL_VERSION_1_3)
2548 glActiveTexture(GL_TEXTURE0 + i);
2550 glActiveTextureARB(GL_TEXTURE0_ARB + i);
2552 checkGLcall("Activate texture.. to update const color");
2554 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2557 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
2558 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2563 case D3DRS_SPECULARENABLE :
2566 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
2567 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
2569 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
2570 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
2575 case D3DRS_STENCILENABLE :
2577 glEnable(GL_STENCIL_TEST);
2578 checkGLcall("glEnable GL_STENCIL_TEST");
2580 glDisable(GL_STENCIL_TEST);
2581 checkGLcall("glDisable GL_STENCIL_TEST");
2585 case D3DRS_STENCILFUNC :
2587 int glParm = GL_ALWAYS;
2589 GLuint mask = 0xFFFFFFFF;
2591 glGetIntegerv(GL_STENCIL_REF, &ref);
2592 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2593 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2594 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2596 switch ((D3DCMPFUNC) Value) {
2597 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2598 case D3DCMP_LESS: glParm=GL_LESS; break;
2599 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2600 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2601 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2602 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2603 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2604 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2606 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2608 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2609 glStencilFunc(glParm, ref, mask);
2610 checkGLcall("glStencilFunc");
2614 case D3DRS_STENCILREF :
2616 int glParm = GL_ALWAYS;
2618 GLuint mask = 0xFFFFFFFF;
2620 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2621 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2622 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
2623 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2626 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2627 glStencilFunc(glParm, ref, mask);
2628 checkGLcall("glStencilFunc");
2632 case D3DRS_STENCILMASK :
2634 int glParm = GL_ALWAYS;
2636 GLuint mask = Value;
2638 glGetIntegerv(GL_STENCIL_REF, &ref);
2639 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2640 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
2641 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2643 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2644 glStencilFunc(glParm, ref, mask);
2645 checkGLcall("glStencilFunc");
2649 case D3DRS_STENCILFAIL :
2655 fail = StencilOp(Value);
2656 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2657 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2658 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2659 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2661 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2662 glStencilOp(fail, zfail, zpass);
2663 checkGLcall("glStencilOp(fail, zfail, zpass);");
2666 case D3DRS_STENCILZFAIL :
2672 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2673 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2674 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2675 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2676 zfail = StencilOp(Value);
2678 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2679 glStencilOp(fail, zfail, zpass);
2680 checkGLcall("glStencilOp(fail, zfail, zpass);");
2683 case D3DRS_STENCILPASS :
2689 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2690 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2691 zpass = StencilOp(Value);
2692 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2693 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2695 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2696 glStencilOp(fail, zfail, zpass);
2697 checkGLcall("glStencilOp(fail, zfail, zpass);");
2701 case D3DRS_STENCILWRITEMASK :
2703 glStencilMask(Value);
2704 TRACE("glStencilMask(%lu)\n", Value);
2705 checkGLcall("glStencilMask");
2709 case D3DRS_FOGENABLE :
2711 if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
2713 checkGLcall("glEnable GL_FOG\n");
2716 checkGLcall("glDisable GL_FOG\n");
2721 case D3DRS_FOGCOLOR :
2724 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2725 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2726 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2727 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2729 /* Set the default alpha blend color */
2730 glFogfv(GL_FOG_COLOR, &col[0]);
2731 checkGLcall("glFog GL_FOG_COLOR");
2735 case D3DRS_FOGSTART :
2737 float *f = (float *)&Value;
2738 glFogfv(GL_FOG_START, f);
2739 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2740 TRACE("Fog Start == %f\n", *f);
2746 float *f = (float *)&Value;
2747 glFogfv(GL_FOG_END, f);
2748 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2749 TRACE("Fog End == %f\n", *f);
2753 case D3DRS_FOGDENSITY :
2755 glFogf(GL_FOG_DENSITY, (float) Value);
2756 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2760 case D3DRS_VERTEXBLEND :
2762 This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
2763 TRACE("Vertex Blending state to %ld\n", Value);
2767 case D3DRS_TWEENFACTOR :
2769 This->UpdateStateBlock->tween_factor = *((float*) &Value);
2770 TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
2774 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2776 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
2781 case D3DRS_COLORVERTEX :
2782 case D3DRS_DIFFUSEMATERIALSOURCE :
2783 case D3DRS_SPECULARMATERIALSOURCE :
2784 case D3DRS_AMBIENTMATERIALSOURCE :
2785 case D3DRS_EMISSIVEMATERIALSOURCE :
2787 GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
2789 if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
2790 glEnable(GL_COLOR_MATERIAL);
2791 checkGLcall("glEnable GL_GL_COLOR_MATERIAL\n");
2793 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
2794 This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
2795 This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
2796 This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE],
2797 This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]);
2799 if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
2800 if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
2801 Parm = GL_AMBIENT_AND_DIFFUSE;
2805 } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
2807 } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
2809 } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
2816 glDisable(GL_COLOR_MATERIAL);
2817 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
2819 TRACE("glColorMaterial Parm=%d\n", Parm);
2820 glColorMaterial(GL_FRONT_AND_BACK, Parm);
2821 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)\n");
2825 glDisable(GL_COLOR_MATERIAL);
2826 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
2831 /* Unhandled yet...! */
2832 case D3DRS_LINEPATTERN :
2833 case D3DRS_LASTPIXEL :
2834 case D3DRS_ZVISIBLE :
2835 case D3DRS_FOGTABLEMODE :
2836 case D3DRS_EDGEANTIALIAS :
2838 case D3DRS_RANGEFOGENABLE :
2847 case D3DRS_FOGVERTEXMODE :
2848 case D3DRS_LOCALVIEWER :
2849 case D3DRS_NORMALIZENORMALS :
2850 case D3DRS_SOFTWAREVERTEXPROCESSING :
2851 case D3DRS_POINTSIZE :
2852 case D3DRS_POINTSIZE_MIN :
2853 case D3DRS_POINTSPRITEENABLE :
2854 case D3DRS_POINTSCALEENABLE :
2855 case D3DRS_POINTSCALE_A :
2856 case D3DRS_POINTSCALE_B :
2857 case D3DRS_POINTSCALE_C :
2858 case D3DRS_MULTISAMPLEANTIALIAS :
2859 case D3DRS_MULTISAMPLEMASK :
2860 case D3DRS_PATCHEDGESTYLE :
2861 case D3DRS_PATCHSEGMENTS :
2862 case D3DRS_DEBUGMONITORTOKEN :
2863 case D3DRS_POINTSIZE_MAX :
2864 case D3DRS_COLORWRITEENABLE :
2865 case D3DRS_POSITIONORDER :
2866 case D3DRS_NORMALORDER :
2867 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2868 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2871 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2876 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2877 ICOM_THIS(IDirect3DDevice8Impl,iface);
2878 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2879 *pValue = This->StateBlock->renderstate[State];
2882 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2883 ICOM_THIS(IDirect3DDevice8Impl,iface);
2885 TRACE("(%p)\n", This);
2887 return IDirect3DDeviceImpl_BeginStateBlock(This);
2889 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2890 IDirect3DStateBlockImpl* pSB;
2891 ICOM_THIS(IDirect3DDevice8Impl,iface);
2894 TRACE("(%p)\n", This);
2896 res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB);
2897 *pToken = (DWORD) pSB;
2901 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2902 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2903 ICOM_THIS(IDirect3DDevice8Impl,iface);
2905 TRACE("(%p)\n", This);
2907 return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB);
2910 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2911 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2912 ICOM_THIS(IDirect3DDevice8Impl,iface);
2914 TRACE("(%p)\n", This);
2916 return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB);
2918 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2919 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2920 ICOM_THIS(IDirect3DDevice8Impl,iface);
2922 TRACE("(%p)\n", This);
2924 return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB);
2927 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
2928 IDirect3DStateBlockImpl* pSB;
2929 ICOM_THIS(IDirect3DDevice8Impl,iface);
2932 TRACE("(%p) : for type %d\n", This, Type);
2934 res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB);
2935 *pToken = (DWORD) pSB;
2939 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2940 ICOM_THIS(IDirect3DDevice8Impl,iface);
2941 FIXME("(%p) : stub\n", This); return D3D_OK;
2943 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2944 ICOM_THIS(IDirect3DDevice8Impl,iface);
2945 FIXME("(%p) : stub\n", This); return D3D_OK;
2947 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2948 ICOM_THIS(IDirect3DDevice8Impl,iface);
2949 TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage);
2950 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage];
2951 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2954 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
2956 IDirect3DBaseTexture8 *oldTxt;
2958 ICOM_THIS(IDirect3DDevice8Impl,iface);
2959 D3DRESOURCETYPE textureType;
2961 oldTxt = This->UpdateStateBlock->textures[Stage];
2962 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2964 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2965 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2966 This->UpdateStateBlock->textures[Stage] = pTexture;
2968 /* Handle recording of state blocks */
2969 if (This->isRecordingState) {
2970 TRACE("Recording... not performing anything\n");
2974 /* Make appropriate texture active */
2975 if (This->isMultiTexture) {
2976 #if defined(GL_VERSION_1_3)
2977 glActiveTexture(GL_TEXTURE0 + Stage);
2979 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2981 checkGLcall("glActiveTextureARB");
2982 } else if (Stage>0) {
2983 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2986 /* Decrement the count of the previous texture */
2987 /* FIXME PERF: If old == new and not dirty then skip all this */
2988 if (oldTxt != NULL) {
2989 IDirect3DBaseTexture8Impl_Release(oldTxt);
2993 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]);
2995 /* Now setup the texture appropraitly */
2996 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2998 if (textureType == D3DRTYPE_TEXTURE) {
2999 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
3002 /* Standard 2D texture */
3003 TRACE("Standard 2d texture\n");
3004 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D;
3006 for (i=0; i<pTexture2->levels; i++)
3009 if (i==0 && pTexture2->surfaces[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3010 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3011 checkGLcall("glBindTexture");
3012 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3013 /* No need to walk through all mip-map levels, since already all assigned */
3014 i = pTexture2->levels;
3019 if (pTexture2->surfaces[i]->textureName == 0) {
3020 glGenTextures(1, &pTexture2->surfaces[i]->textureName);
3021 checkGLcall("glGenTextures");
3022 TRACE("Texture %p (level %d) given name %d\n", pTexture2->surfaces[i], i, pTexture2->surfaces[i]->textureName);
3025 glBindTexture(GL_TEXTURE_2D, pTexture2->surfaces[i]->textureName);
3026 checkGLcall("glBindTexture");
3028 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", pTexture2->levels-1);
3029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3030 checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels)");
3033 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3034 GL_TEXTURE_2D, i, fmt2glintFmt(pTexture2->format), pTexture2->surfaces[i]->myDesc.Width,
3035 pTexture2->surfaces[i]->myDesc.Height, 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3036 pTexture2->surfaces[i]->allocatedMemory);
3037 glTexImage2D(GL_TEXTURE_2D, i,
3038 fmt2glintFmt(pTexture2->format),
3039 pTexture2->surfaces[i]->myDesc.Width,
3040 pTexture2->surfaces[i]->myDesc.Height,
3042 fmt2glFmt(pTexture2->format),
3043 fmt2glType(pTexture2->format),
3044 pTexture2->surfaces[i]->allocatedMemory
3046 checkGLcall("glTexImage2D");
3048 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3049 pTexture2->Dirty = FALSE;
3054 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3055 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3058 /* Standard 3D (volume) texture */
3059 TRACE("Standard 3d texture\n");
3060 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
3062 for (i=0; i<pTexture2->levels; i++)
3065 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3066 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3067 checkGLcall("glBindTexture");
3068 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3070 /* No need to walk through all mip-map levels, since already all assigned */
3071 i = pTexture2->levels;
3075 if (pTexture2->volumes[i]->textureName == 0) {
3076 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3077 checkGLcall("glGenTextures");
3078 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3081 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3082 checkGLcall("glBindTexture");
3084 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3085 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3088 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3089 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3090 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3091 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3092 pTexture2->volumes[i]->allocatedMemory);
3093 glTexImage3D(GL_TEXTURE_3D, i,
3094 fmt2glintFmt(pTexture2->format),
3095 pTexture2->volumes[i]->myDesc.Width,
3096 pTexture2->volumes[i]->myDesc.Height,
3097 pTexture2->volumes[i]->myDesc.Depth,
3099 fmt2glFmt(pTexture2->format),
3100 fmt2glType(pTexture2->format),
3101 pTexture2->volumes[i]->allocatedMemory
3103 checkGLcall("glTexImage3D");
3105 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3106 pTexture2->Dirty = FALSE;
3111 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
3114 TRACE("Setting to no texture (ie default texture)\n");
3115 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D;
3116 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3117 checkGLcall("glBindTexture");
3118 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3121 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3122 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3123 setupTextureStates (iface, Stage);
3128 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3129 ICOM_THIS(IDirect3DDevice8Impl,iface);
3130 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
3131 *pValue = This->UpdateStateBlock->texture_state[Stage][Type];
3135 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
3136 ICOM_THIS(IDirect3DDevice8Impl,iface);
3138 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3140 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
3142 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3143 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3144 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3146 /* Handle recording of state blocks */
3147 if (This->isRecordingState) {
3148 TRACE("Recording... not performing anything\n");
3152 /* Make appropriate texture active */
3153 TRACE("Activating appropriate texture state %ld\n", Stage);
3154 if (This->isMultiTexture) {
3155 #if defined(GL_VERSION_1_3)
3156 glActiveTexture(GL_TEXTURE0 + Stage);
3157 checkGLcall("glActiveTexture");
3159 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3160 checkGLcall("glActiveTextureARB");
3163 } else if (Stage>0) {
3164 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3169 case D3DTSS_MINFILTER :
3170 case D3DTSS_MIPFILTER :
3172 DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER];
3173 DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER];
3174 GLint realVal = GL_LINEAR;
3176 if (ValueMIN == D3DTEXF_POINT) {
3178 if (ValueMIP == D3DTEXF_POINT) {
3179 realVal = GL_NEAREST_MIPMAP_NEAREST;
3180 } else if (ValueMIP == D3DTEXF_LINEAR) {
3181 realVal = GL_NEAREST_MIPMAP_LINEAR;
3182 } else if (ValueMIP == D3DTEXF_NONE) {
3183 realVal = GL_NEAREST;
3185 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3186 realVal = GL_NEAREST_MIPMAP_LINEAR;
3188 } else if (ValueMIN == D3DTEXF_LINEAR) {
3190 if (ValueMIP == D3DTEXF_POINT) {
3191 realVal = GL_LINEAR_MIPMAP_NEAREST;
3192 } else if (ValueMIP == D3DTEXF_LINEAR) {
3193 realVal = GL_LINEAR_MIPMAP_LINEAR;
3194 } else if (ValueMIP == D3DTEXF_NONE) {
3195 realVal = GL_LINEAR;
3197 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3198 realVal = GL_LINEAR_MIPMAP_LINEAR;
3200 } else if (ValueMIN == D3DTEXF_NONE) {
3201 /* Doesnt really make sense - Windows just seems to disable
3202 mipmapping when this occurs */
3203 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3204 realVal = GL_LINEAR;
3207 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3208 realVal = GL_LINEAR_MIPMAP_LINEAR;
3211 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3212 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3213 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3218 case D3DTSS_MAGFILTER :
3219 if (Value == D3DTEXF_POINT) {
3220 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3221 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3222 } else if (Value == D3DTEXF_LINEAR) {
3223 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3224 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3226 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3230 case D3DTSS_COLORARG0 :
3231 case D3DTSS_ALPHAARG0 :
3232 /* FIXME: Mesa seems to struggle setting these at the moment */
3235 case D3DTSS_COLORARG1 :
3236 case D3DTSS_COLORARG2 :
3237 case D3DTSS_ALPHAARG1 :
3238 case D3DTSS_ALPHAARG2 :
3240 BOOL isAlphaReplicate = FALSE;
3241 BOOL isComplement = FALSE;
3242 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3243 int operand= GL_SRC_COLOR;
3244 int source = GL_TEXTURE;
3246 /* Catch alpha replicate */
3247 if (Value & D3DTA_ALPHAREPLICATE) {
3248 Value = Value & ~D3DTA_ALPHAREPLICATE;
3249 isAlphaReplicate = TRUE;
3252 /* Catch Complement */
3253 if (Value & D3DTA_COMPLEMENT) {
3254 Value = Value & ~D3DTA_COMPLEMENT;
3255 isComplement = TRUE;
3258 /* Calculate the operand */
3259 if (isAlphaReplicate && !isComplement) {
3260 operand = GL_SRC_ALPHA;
3261 } else if (isAlphaReplicate && isComplement) {
3262 operand = GL_ONE_MINUS_SRC_ALPHA;
3263 } else if (isComplement) {
3265 operand = GL_ONE_MINUS_SRC_ALPHA;
3267 operand = GL_ONE_MINUS_SRC_COLOR;
3271 operand = GL_SRC_ALPHA;
3273 operand = GL_SRC_COLOR;
3277 /* Calculate the source */
3279 case D3DTA_CURRENT: source = GL_PREVIOUS_EXT;
3281 case D3DTA_DIFFUSE: source = GL_PRIMARY_COLOR_EXT;
3283 case D3DTA_TEXTURE: source = GL_TEXTURE;
3285 case D3DTA_TFACTOR: source = GL_CONSTANT_EXT;
3288 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
3289 isnt supported until base GL supports it
3290 There is no concept of temp registers as far as I can tell */
3293 FIXME("Unrecognized or unhandled texture arg %ld\n", Value);
3297 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3298 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3299 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3300 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3301 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3303 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3304 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3305 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3306 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3307 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3312 case D3DTSS_ALPHAOP :
3313 case D3DTSS_COLOROP :
3317 int Parm = (Type == D3DTSS_ALPHAOP)? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3319 if (Type==D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3320 /* TODO: Disable by making this and all later levels disabled */
3321 glDisable(GL_TEXTURE_1D);
3322 checkGLcall("Disable GL_TEXTURE_1D");
3323 glDisable(GL_TEXTURE_2D);
3324 checkGLcall("Disable GL_TEXTURE_2D");
3325 glDisable(GL_TEXTURE_3D);
3326 checkGLcall("Disable GL_TEXTURE_3D");
3329 /* Enable only the appropriate texture dimension */
3330 if (Type==D3DTSS_COLOROP) {
3331 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
3332 glEnable(GL_TEXTURE_1D);
3333 checkGLcall("Enable GL_TEXTURE_1D");
3335 glDisable(GL_TEXTURE_1D);
3336 checkGLcall("Disable GL_TEXTURE_1D");
3338 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
3339 glEnable(GL_TEXTURE_2D);
3340 checkGLcall("Enable GL_TEXTURE_2D");
3342 glDisable(GL_TEXTURE_2D);
3343 checkGLcall("Disable GL_TEXTURE_2D");
3345 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
3346 glEnable(GL_TEXTURE_3D);
3347 checkGLcall("Enable GL_TEXTURE_3D");
3349 glDisable(GL_TEXTURE_3D);
3350 checkGLcall("Disable GL_TEXTURE_3D");
3354 /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
3355 if (Value != D3DTOP_DISABLE) {
3356 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
3359 /* Now set up the operand correctly */
3361 case D3DTOP_DISABLE :
3362 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3363 and it works, so ignore this op */
3364 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3367 case D3DTOP_SELECTARG1 :
3368 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3369 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3372 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3373 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3374 case D3DTOP_MODULATE :
3377 if (Type == D3DTSS_ALPHAOP) {
3378 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3379 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3381 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3382 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3384 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3385 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3389 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3390 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3393 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3394 case D3DTOP_ADDSIGNED :
3395 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3396 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3399 case D3DTOP_DOTPRODUCT3 :
3400 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3401 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3404 case D3DTOP_SUBTRACT :
3405 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3406 case D3DTOP_SELECTARG2 :
3407 /* GL_REPLACE, swap args 0 and 1? */
3408 case D3DTOP_ADDSMOOTH :
3409 case D3DTOP_BLENDDIFFUSEALPHA :
3410 case D3DTOP_BLENDTEXTUREALPHA :
3411 case D3DTOP_BLENDFACTORALPHA :
3412 case D3DTOP_BLENDTEXTUREALPHAPM :
3413 case D3DTOP_BLENDCURRENTALPHA :
3414 case D3DTOP_PREMODULATE :
3415 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3416 case D3DTOP_MODULATECOLOR_ADDALPHA :
3417 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3418 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3419 case D3DTOP_BUMPENVMAP :
3420 case D3DTOP_BUMPENVMAPLUMINANCE :
3421 case D3DTOP_MULTIPLYADD :
3424 FIXME("Unhandled texture operation %ld\n", Value);
3430 case D3DTSS_ADDRESSU :
3431 case D3DTSS_ADDRESSV :
3432 case D3DTSS_ADDRESSW :
3434 GLint wrapParm = GL_REPEAT;
3436 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3437 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP; break;
3438 case D3DTADDRESS_BORDER: wrapParm = GL_CLAMP_TO_EDGE; break;
3440 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL? */
3441 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL? */
3443 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3444 wrapParm = GL_REPEAT;
3448 case D3DTSS_ADDRESSU:
3449 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3450 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3451 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3453 case D3DTSS_ADDRESSV:
3454 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3455 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3456 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3458 case D3DTSS_ADDRESSW:
3459 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3460 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3461 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3464 break; /** stupic compilator */
3469 case D3DTSS_BORDERCOLOR :
3472 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3473 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3474 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3475 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3477 TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value);
3478 glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3479 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3484 case D3DTSS_BUMPENVMAT00 :
3485 case D3DTSS_BUMPENVMAT01 :
3486 case D3DTSS_BUMPENVMAT10 :
3487 case D3DTSS_BUMPENVMAT11 :
3488 case D3DTSS_TEXCOORDINDEX :
3489 case D3DTSS_MIPMAPLODBIAS :
3490 case D3DTSS_MAXMIPLEVEL :
3491 case D3DTSS_MAXANISOTROPY :
3492 case D3DTSS_BUMPENVLSCALE :
3493 case D3DTSS_BUMPENVLOFFSET :
3494 case D3DTSS_TEXTURETRANSFORMFLAGS :
3495 case D3DTSS_RESULTARG :
3497 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3498 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3502 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3503 ICOM_THIS(IDirect3DDevice8Impl,iface);
3504 FIXME("(%p) : stub\n", This); return D3D_OK;
3506 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
3507 ICOM_THIS(IDirect3DDevice8Impl,iface);
3508 FIXME("(%p) : stub\n", This); return D3D_OK;
3510 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
3511 ICOM_THIS(IDirect3DDevice8Impl,iface);
3512 FIXME("(%p) : stub\n", This); return D3D_OK;
3514 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
3515 ICOM_THIS(IDirect3DDevice8Impl,iface);
3516 FIXME("(%p) : stub\n", This); return D3D_OK;
3518 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3519 ICOM_THIS(IDirect3DDevice8Impl,iface);
3520 FIXME("(%p) : stub\n", This); return D3D_OK;
3522 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3523 ICOM_THIS(IDirect3DDevice8Impl,iface);
3524 FIXME("(%p) : stub\n", This); return D3D_OK;
3526 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
3528 IDirect3DVertexBuffer8 *pVB;
3530 ICOM_THIS(IDirect3DDevice8Impl,iface);
3531 pVB = This->StateBlock->stream_source[0];
3533 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
3535 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
3536 This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
3540 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3541 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3543 IDirect3DIndexBuffer8 *pIB;
3544 IDirect3DVertexBuffer8 *pVB;
3545 D3DINDEXBUFFER_DESC IdxBufDsc;
3547 ICOM_THIS(IDirect3DDevice8Impl,iface);
3548 pIB = This->StateBlock->pIndexData;
3549 pVB = This->StateBlock->stream_source[0];
3551 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
3552 minIndex, NumVertices, startIndex, primCount);
3554 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3555 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3561 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
3562 This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3567 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3568 ICOM_THIS(IDirect3DDevice8Impl,iface);
3570 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3572 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3574 This->StateBlock->stream_source[0] = NULL;
3575 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3576 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock->VertexShader, pVertexStreamZeroData,
3578 This->StateBlock->stream_stride[0] = 0;
3580 /*stream zero settings set to null at end */
3583 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3584 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3585 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3586 UINT VertexStreamZeroStride) {
3588 ICOM_THIS(IDirect3DDevice8Impl,iface);
3589 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
3590 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3592 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3593 if (IndexDataFormat == D3DFMT_INDEX16) {
3599 This->StateBlock->stream_source[0] = NULL;
3600 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3601 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock->VertexShader, pVertexStreamZeroData,
3602 This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3604 /*stream zero settings set to null at end */
3605 This->StateBlock->stream_stride[0] = 0;
3606 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3610 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3611 ICOM_THIS(IDirect3DDevice8Impl,iface);
3612 FIXME("(%p) : stub\n", This); return D3D_OK;
3614 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3615 ICOM_THIS(IDirect3DDevice8Impl,iface);
3616 IDirect3DVertexShaderImpl* object;
3617 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3621 TRACE("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
3622 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3623 return D3DERR_INVALIDCALL;
3625 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
3626 if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
3627 return D3DERR_OUTOFVIDEOMEMORY;
3630 /** Create the Vertex Shader */
3631 res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
3632 /** TODO: check FAILED(res) */
3634 /** Create and Bind the Vertex Shader Declaration */
3635 res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
3636 /** TODO: check FAILED(res) */
3638 VertexShaders[i] = object;
3639 VertexShaderDeclarations[i] = attached_decl;
3640 *pHandle = VS_HIGHESTFIXEDFXF + i;
3644 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3645 ICOM_THIS(IDirect3DDevice8Impl,iface);
3647 This->UpdateStateBlock->VertexShader = Handle;
3648 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3649 This->UpdateStateBlock->Set.vertexShader = TRUE;
3651 if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
3652 FIXME("(%p) : Created shader, Handle=%lx\n", This, Handle);
3653 This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
3654 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3655 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3656 } else { /* use a fvf, so desactivate the vshader decl */
3657 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3658 This->UpdateStateBlock->vertexShaderDecl = NULL;
3659 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3660 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3662 /* Handle recording of state blocks */
3663 if (This->isRecordingState) {
3664 TRACE("Recording... not performing anything\n");
3668 * TODO: merge HAL shaders context switching from prototype
3672 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3673 ICOM_THIS(IDirect3DDevice8Impl,iface);
3674 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
3675 *pHandle = This->StateBlock->VertexShader;
3679 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3680 ICOM_THIS(IDirect3DDevice8Impl,iface);
3681 IDirect3DVertexShaderImpl* object;
3682 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3684 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3685 return D3DERR_INVALIDCALL;
3689 * Delete Vertex Shader
3691 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3692 if (NULL == object) {
3693 return D3DERR_INVALIDCALL;
3695 FIXME("(%p) : freing VertexShader %p\n", This, object);
3696 /* TODO: check validity of object */
3697 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3698 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3699 HeapFree(GetProcessHeap(), 0, (void *)object);
3700 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3703 * Delete Vertex Shader Declaration
3705 attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
3706 if (NULL == attached_decl) {
3707 return D3DERR_INVALIDCALL;
3709 FIXME("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
3710 /* TODO: check validity of object */
3711 HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
3712 HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
3713 VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3718 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3719 ICOM_THIS(IDirect3DDevice8Impl,iface);
3721 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3722 /*ERR("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);*/
3723 return D3DERR_INVALIDCALL;
3725 if (NULL == pConstantData) {
3726 return D3DERR_INVALIDCALL;
3728 if (ConstantCount > 1) {
3729 FLOAT* f = (FLOAT*)pConstantData;
3731 FIXME("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
3732 for (i = 0; i < ConstantCount; ++i) {
3733 DPRINTF("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
3737 FLOAT* f = (FLOAT*)pConstantData;
3738 FIXME("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
3740 This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
3741 memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
3744 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3745 ICOM_THIS(IDirect3DDevice8Impl,iface);
3747 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3748 return D3DERR_INVALIDCALL;
3750 if (NULL == pConstantData) {
3751 return D3DERR_INVALIDCALL;
3753 memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
3756 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3757 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3758 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3760 attached_decl = VERTEX_SHADER_DECL(Handle);
3761 if (NULL == attached_decl) {
3762 return D3DERR_INVALIDCALL;
3764 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
3766 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3767 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3768 IDirect3DVertexShaderImpl* object;
3770 object = VERTEX_SHADER(Handle);
3771 if (NULL == object) {
3772 return D3DERR_INVALIDCALL;
3774 return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
3777 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
3778 ICOM_THIS(IDirect3DDevice8Impl,iface);
3779 IDirect3DIndexBuffer8 *oldIdxs;
3781 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3782 oldIdxs = This->StateBlock->pIndexData;
3784 This->UpdateStateBlock->Changed.Indices = TRUE;
3785 This->UpdateStateBlock->Set.Indices = TRUE;
3786 This->UpdateStateBlock->pIndexData = pIndexData;
3787 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3789 /* Handle recording of state blocks */
3790 if (This->isRecordingState) {
3791 TRACE("Recording... not performing anything\n");
3795 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3796 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
3799 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3800 ICOM_THIS(IDirect3DDevice8Impl,iface);
3801 FIXME("(%p) : stub\n", This);
3803 *ppIndexData = This->StateBlock->pIndexData;
3804 /* up ref count on ppindexdata */
3805 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3806 *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
3810 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3811 ICOM_THIS(IDirect3DDevice8Impl,iface);
3812 IDirect3DPixelShaderImpl* object;
3815 FIXME("(%p) : PixelShader not fully supported yet\n", This);
3816 if (NULL == pFunction || NULL == pHandle) {
3817 return D3DERR_INVALIDCALL;
3819 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
3820 if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
3821 return D3DERR_OUTOFVIDEOMEMORY;
3823 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
3824 if (NULL == object) {
3825 return D3DERR_OUTOFVIDEOMEMORY;
3828 object->data = NULL; /* TODO */
3830 PixelShaders[i] = object;
3831 *pHandle = VS_HIGHESTFIXEDFXF + i;
3833 object->function = pFunction;
3834 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
3835 object->functionLength = i + 1;
3839 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3840 ICOM_THIS(IDirect3DDevice8Impl,iface);
3842 This->UpdateStateBlock->PixelShader = Handle;
3843 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3844 This->UpdateStateBlock->Set.pixelShader = TRUE;
3846 /* Handle recording of state blocks */
3847 if (This->isRecordingState) {
3848 TRACE("Recording... not performing anything\n");
3852 /* FIXME: Quieten when not being used */
3854 FIXME("(%p) : stub %ld\n", This, Handle);
3856 TRACE("(%p) : stub %ld\n", This, Handle);
3861 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3862 ICOM_THIS(IDirect3DDevice8Impl,iface);
3863 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
3864 *pHandle = This->StateBlock->PixelShader;
3868 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3869 ICOM_THIS(IDirect3DDevice8Impl,iface);
3870 IDirect3DPixelShaderImpl* object;
3872 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3873 return D3DERR_INVALIDCALL;
3875 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3876 TRACE("(%p) : freeing PixelShader %p\n", This, object);
3877 /* TODO: check validity of object before free */
3878 HeapFree(GetProcessHeap(), 0, (void *)object);
3879 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
3883 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
3884 ICOM_THIS(IDirect3DDevice8Impl,iface);
3885 FIXME("(%p) : stub\n", This);
3888 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
3889 ICOM_THIS(IDirect3DDevice8Impl,iface);
3890 FIXME("(%p) : stub\n", This);
3893 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3894 ICOM_THIS(IDirect3DDevice8Impl,iface);
3895 IDirect3DPixelShaderImpl* object;
3897 object = PIXEL_SHADER(Handle);
3898 if (NULL == object) {
3899 return D3DERR_INVALIDCALL;
3901 if (NULL == pData) {
3902 *pSizeOfData = object->functionLength;
3905 if (*pSizeOfData < object->functionLength) {
3906 *pSizeOfData = object->functionLength;
3907 return D3DERR_MOREDATA;
3909 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
3910 memcpy(pData, object->function, object->functionLength);
3913 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3914 ICOM_THIS(IDirect3DDevice8Impl,iface);
3915 FIXME("(%p) : stub\n", This); return D3D_OK;
3917 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3918 ICOM_THIS(IDirect3DDevice8Impl,iface);
3919 FIXME("(%p) : stub\n", This); return D3D_OK;
3921 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3922 ICOM_THIS(IDirect3DDevice8Impl,iface);
3923 FIXME("(%p) : stub\n", This); return D3D_OK;
3926 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3927 IDirect3DVertexBuffer8 *oldSrc;
3928 ICOM_THIS(IDirect3DDevice8Impl,iface);
3930 oldSrc = This->StateBlock->stream_source[StreamNumber];
3931 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3933 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3934 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3935 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3936 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3938 /* Handle recording of state blocks */
3939 if (This->isRecordingState) {
3940 TRACE("Recording... not performing anything\n");
3944 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3945 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3948 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3949 ICOM_THIS(IDirect3DDevice8Impl,iface);
3950 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
3951 *pStream = This->StateBlock->stream_source[StreamNumber];
3952 *pStride = This->StateBlock->stream_stride[StreamNumber];
3953 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3958 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3960 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3961 IDirect3DDevice8Impl_QueryInterface,
3962 IDirect3DDevice8Impl_AddRef,
3963 IDirect3DDevice8Impl_Release,
3964 IDirect3DDevice8Impl_TestCooperativeLevel,
3965 IDirect3DDevice8Impl_GetAvailableTextureMem,
3966 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3967 IDirect3DDevice8Impl_GetDirect3D,
3968 IDirect3DDevice8Impl_GetDeviceCaps,
3969 IDirect3DDevice8Impl_GetDisplayMode,
3970 IDirect3DDevice8Impl_GetCreationParameters,
3971 IDirect3DDevice8Impl_SetCursorProperties,
3972 IDirect3DDevice8Impl_SetCursorPosition,
3973 IDirect3DDevice8Impl_ShowCursor,
3974 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3975 IDirect3DDevice8Impl_Reset,
3976 IDirect3DDevice8Impl_Present,
3977 IDirect3DDevice8Impl_GetBackBuffer,
3978 IDirect3DDevice8Impl_GetRasterStatus,
3979 IDirect3DDevice8Impl_SetGammaRamp,
3980 IDirect3DDevice8Impl_GetGammaRamp,
3981 IDirect3DDevice8Impl_CreateTexture,
3982 IDirect3DDevice8Impl_CreateVolumeTexture,
3983 IDirect3DDevice8Impl_CreateCubeTexture,
3984 IDirect3DDevice8Impl_CreateVertexBuffer,
3985 IDirect3DDevice8Impl_CreateIndexBuffer,
3986 IDirect3DDevice8Impl_CreateRenderTarget,
3987 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3988 IDirect3DDevice8Impl_CreateImageSurface,
3989 IDirect3DDevice8Impl_CopyRects,
3990 IDirect3DDevice8Impl_UpdateTexture,
3991 IDirect3DDevice8Impl_GetFrontBuffer,
3992 IDirect3DDevice8Impl_SetRenderTarget,
3993 IDirect3DDevice8Impl_GetRenderTarget,
3994 IDirect3DDevice8Impl_GetDepthStencilSurface,
3995 IDirect3DDevice8Impl_BeginScene,
3996 IDirect3DDevice8Impl_EndScene,
3997 IDirect3DDevice8Impl_Clear,
3998 IDirect3DDevice8Impl_SetTransform,
3999 IDirect3DDevice8Impl_GetTransform,
4000 IDirect3DDevice8Impl_MultiplyTransform,
4001 IDirect3DDevice8Impl_SetViewport,
4002 IDirect3DDevice8Impl_GetViewport,
4003 IDirect3DDevice8Impl_SetMaterial,
4004 IDirect3DDevice8Impl_GetMaterial,
4005 IDirect3DDevice8Impl_SetLight,
4006 IDirect3DDevice8Impl_GetLight,
4007 IDirect3DDevice8Impl_LightEnable,
4008 IDirect3DDevice8Impl_GetLightEnable,
4009 IDirect3DDevice8Impl_SetClipPlane,
4010 IDirect3DDevice8Impl_GetClipPlane,
4011 IDirect3DDevice8Impl_SetRenderState,
4012 IDirect3DDevice8Impl_GetRenderState,
4013 IDirect3DDevice8Impl_BeginStateBlock,
4014 IDirect3DDevice8Impl_EndStateBlock,
4015 IDirect3DDevice8Impl_ApplyStateBlock,
4016 IDirect3DDevice8Impl_CaptureStateBlock,
4017 IDirect3DDevice8Impl_DeleteStateBlock,
4018 IDirect3DDevice8Impl_CreateStateBlock,
4019 IDirect3DDevice8Impl_SetClipStatus,
4020 IDirect3DDevice8Impl_GetClipStatus,
4021 IDirect3DDevice8Impl_GetTexture,
4022 IDirect3DDevice8Impl_SetTexture,
4023 IDirect3DDevice8Impl_GetTextureStageState,
4024 IDirect3DDevice8Impl_SetTextureStageState,
4025 IDirect3DDevice8Impl_ValidateDevice,
4026 IDirect3DDevice8Impl_GetInfo,
4027 IDirect3DDevice8Impl_SetPaletteEntries,
4028 IDirect3DDevice8Impl_GetPaletteEntries,
4029 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4030 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4031 IDirect3DDevice8Impl_DrawPrimitive,
4032 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4033 IDirect3DDevice8Impl_DrawPrimitiveUP,
4034 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4035 IDirect3DDevice8Impl_ProcessVertices,
4036 IDirect3DDevice8Impl_CreateVertexShader,
4037 IDirect3DDevice8Impl_SetVertexShader,
4038 IDirect3DDevice8Impl_GetVertexShader,
4039 IDirect3DDevice8Impl_DeleteVertexShader,
4040 IDirect3DDevice8Impl_SetVertexShaderConstant,
4041 IDirect3DDevice8Impl_GetVertexShaderConstant,
4042 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4043 IDirect3DDevice8Impl_GetVertexShaderFunction,
4044 IDirect3DDevice8Impl_SetStreamSource,
4045 IDirect3DDevice8Impl_GetStreamSource,
4046 IDirect3DDevice8Impl_SetIndices,
4047 IDirect3DDevice8Impl_GetIndices,
4048 IDirect3DDevice8Impl_CreatePixelShader,
4049 IDirect3DDevice8Impl_SetPixelShader,
4050 IDirect3DDevice8Impl_GetPixelShader,
4051 IDirect3DDevice8Impl_DeletePixelShader,
4052 IDirect3DDevice8Impl_SetPixelShaderConstant,
4053 IDirect3DDevice8Impl_GetPixelShaderConstant,
4054 IDirect3DDevice8Impl_GetPixelShaderFunction,
4055 IDirect3DDevice8Impl_DrawRectPatch,
4056 IDirect3DDevice8Impl_DrawTriPatch,
4057 IDirect3DDevice8Impl_DeletePatch