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;
149 int coordIdxInfo = 0x00; /* Information on number of coords supplied */
150 float s[8], t[8], r[8], q[8]; /* Holding place for tex coords */
151 const char *coordPtr[8]; /* Holding place for the ptr to tex coords */
152 int numCoords[8]; /* Holding place for D3DFVF_TEXTUREFORMATx */
157 z = 0.0f; /* x,y,z coordinates */
160 nz = 0.0f; /* normal x,y,z coordinates */
161 float rhw = 0.0f; /* rhw */
162 float ptSize = 0.0f; /* Point size */
163 DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
164 DWORD specularColor = 0; /* Specular Color */
169 if (idxBytes == 2) pIdxBufS = (short *) idxData;
170 else pIdxBufL = (long *) idxData;
173 /* Check vertex formats expected ? */
175 * FVF parser as seen it
176 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/Reference/CPP/D3D/FlexibleVertexFormatFlags.asp
178 normal = fvf & D3DFVF_NORMAL;
179 isRHW = fvf & D3DFVF_XYZRHW;
180 isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
181 numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2 + ((FALSE == isLastUByte4) ? 0 : -1); /* WARNING can be < 0 because -2 */
182 isPtSize = fvf & D3DFVF_PSIZE;
183 isDiffuse = fvf & D3DFVF_DIFFUSE;
184 isSpecular = fvf & D3DFVF_SPECULAR;
185 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
186 coordIdxInfo = (fvf & 0x00FF0000) >> 16; /* 16 is from definition of D3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */
188 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d, coordIdxInfo=%x)\n",
189 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends, coordIdxInfo);
191 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
192 set by the appropriate render state */
194 isLightingOn = glIsEnabled(GL_LIGHTING);
195 glDisable(GL_LIGHTING);
196 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
200 double height, width, minZ, maxZ;
202 * Already transformed vertex do not need transform
203 * matrices. Reset all matrices to identity.
204 * Leave the default matrix in world mode.
206 glMatrixMode(GL_PROJECTION);
207 checkGLcall("glMatrixMode");
209 checkGLcall("glLoadIdentity");
210 glMatrixMode(GL_MODELVIEW);
211 checkGLcall("glMatrixMode");
213 checkGLcall("glLoadIdentity");
214 height = This->StateBlock->viewport.Height;
215 width = This->StateBlock->viewport.Width;
216 minZ = This->StateBlock->viewport.MinZ;
217 maxZ = This->StateBlock->viewport.MaxZ;
218 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
219 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
220 checkGLcall("glOrtho");
222 glMatrixMode(GL_PROJECTION);
223 checkGLcall("glMatrixMode");
224 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
225 checkGLcall("glLoadMatrixf");
226 glMatrixMode(GL_MODELVIEW);
227 checkGLcall("glMatrixMode");
228 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
229 checkGLcall("glLoadMatrixf");
230 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
231 checkGLcall("glMultMatrixf");
234 /* Set OpenGL to the appropriate Primitive Type */
235 switch (PrimitiveType) {
236 case D3DPT_POINTLIST:
238 primType = GL_POINTS;
239 NumVertexes = NumPrimitives;
245 NumVertexes = NumPrimitives * 2;
248 case D3DPT_LINESTRIP:
249 TRACE("LINE_STRIP\n");
250 primType = GL_LINE_STRIP;
251 NumVertexes = NumPrimitives + 1;
254 case D3DPT_TRIANGLELIST:
255 TRACE("TRIANGLES\n");
256 primType = GL_TRIANGLES;
257 NumVertexes = NumPrimitives * 3;
260 case D3DPT_TRIANGLESTRIP:
261 TRACE("TRIANGLE_STRIP\n");
262 primType = GL_TRIANGLE_STRIP;
263 NumVertexes = NumPrimitives + 2;
266 case D3DPT_TRIANGLEFAN:
267 TRACE("TRIANGLE_FAN\n");
268 primType = GL_TRIANGLE_FAN;
269 NumVertexes = NumPrimitives + 2;
273 FIXME("Unhandled primitive\n");
277 /* Fixme, Ideally, only use this per-vertex code for software HAL
278 but until opengl supports all the functions returned to setup
279 vertex arrays, we need to drop down to the slow mechanism for
282 if (isPtSize || isDiffuse || useVertexShaderFunction==TRUE || (numBlends > 0)) {
283 TRACE("Using slow per-vertex code\n");
285 /* Enable this one to be able to debug what is going on, but it is slower
286 than the pointer/array version */
287 VTRACE(("glBegin(%x)\n", primType));
290 /* Draw the primitives */
291 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
293 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
299 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
300 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
302 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
303 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
307 /* Work through the vertex buffer */
308 x = *(float *)curPos;
309 curPos = curPos + sizeof(float);
310 y = *(float *)curPos;
311 curPos = curPos + sizeof(float);
312 z = *(float *)curPos;
313 curPos = curPos + sizeof(float);
314 VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
316 /* RHW follows, only if transformed */
318 rhw = *(float *)curPos;
319 curPos = curPos + sizeof(float);
320 VTRACE(("rhw=%f\n", rhw));
326 D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
327 DWORD skippedBlendLastUByte4 = 0;
329 for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
330 ((float*)&skippedBlend)[i] = *(float *)curPos;
331 curPos = curPos + sizeof(float);
335 skippedBlendLastUByte4 = *(DWORD*)curPos;
336 curPos = curPos + sizeof(DWORD);
340 /* Vertex Normal Data (untransformed only) */
342 nx = *(float *)curPos;
343 curPos = curPos + sizeof(float);
344 ny = *(float *)curPos;
345 curPos = curPos + sizeof(float);
346 nz = *(float *)curPos;
347 curPos = curPos + sizeof(float);
348 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
352 ptSize = *(float *)curPos;
353 VTRACE(("ptSize=%f\n", ptSize));
354 curPos = curPos + sizeof(float);
358 diffuseColor = *(DWORD *)curPos;
359 VTRACE(("diffuseColor=%lx\n", diffuseColor));
360 curPos = curPos + sizeof(DWORD);
364 specularColor = *(DWORD *)curPos;
365 VTRACE(("specularColor=%lx\n", specularColor));
366 curPos = curPos + sizeof(DWORD);
370 /* numTextures indicates the number of texture coordinates supplied */
371 /* However, the first set may not be for stage 0 texture - it all */
372 /* depends on D3DTSS_TEXCOORDINDEX. */
373 /* The number of bytes for each coordinate set is based off */
374 /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
376 /* Initialize unused coords to unsupplied so we can check later */
377 for (textureNo = numTextures; textureNo < 7; textureNo++) numCoords[textureNo] = -1;
379 /* So, for each supplied texture extract the coords */
380 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
382 numCoords[textureNo] = coordIdxInfo & 0x03;
385 s[textureNo] = *(float *)curPos;
386 curPos = curPos + sizeof(float);
387 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
388 t[textureNo] = *(float *)curPos;
389 curPos = curPos + sizeof(float);
390 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
391 r[textureNo] = *(float *)curPos;
392 curPos = curPos + sizeof(float);
393 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
394 q[textureNo] = *(float *)curPos;
395 curPos = curPos + sizeof(float);
400 coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
403 /* Now use the appropriate set of texture indexes */
404 for (textureNo = 0; textureNo < This->TextureUnits; ++textureNo) {
406 if (!(This->isMultiTexture) && textureNo > 0) {
407 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
411 /* Query tex coords */
412 if ((This->StateBlock->textures[textureNo] != NULL) &&
413 (useVertexShaderFunction == FALSE)) {
415 int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
418 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
419 } else if (coordIdx >= numTextures) {
420 VTRACE(("tex: %d - Skip tex coords, as requested higher than supplied\n", textureNo));
422 switch (numCoords[coordIdx]) { /* Supply the provided texture coords */
423 case D3DFVF_TEXTUREFORMAT1:
424 VTRACE(("tex:%d, s=%f\n", textureNo, s[coordIdx]));
425 if (This->isMultiTexture) {
426 #if defined(GL_VERSION_1_3)
427 glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s[coordIdx]);
429 glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx]);
432 glTexCoord1f(s[coordIdx]);
435 case D3DFVF_TEXTUREFORMAT2:
436 VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s[coordIdx], t[coordIdx]));
437 if (This->isMultiTexture) {
438 #if defined(GL_VERSION_1_3)
439 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx]);
441 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx]);
444 glTexCoord2f(s[coordIdx], t[coordIdx]);
447 case D3DFVF_TEXTUREFORMAT3:
448 VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx]));
449 if (This->isMultiTexture) {
450 #if defined(GL_VERSION_1_3)
451 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
453 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
456 glTexCoord3f(s[coordIdx], t[coordIdx], r[coordIdx]);
459 case D3DFVF_TEXTUREFORMAT4:
460 VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]));
461 if (This->isMultiTexture) {
462 #if defined(GL_VERSION_1_3)
463 glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
465 glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
468 glTexCoord4f(s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
472 FIXME("Should not get here as numCoords is two bits only (%x)!\n", numCoords[coordIdx]);
479 /** if vertex shader program specified ... using it */
480 if (TRUE == useVertexShaderFunction) {
483 * this code must become the really
484 * vs input params init
486 * because its possible to use input registers for anything
487 * and some samples use registers for other things than they are
492 * no really valid declaration, user defined input register use
493 * so fill input registers as described in vertex shader declaration
495 IDirect3DDeviceImpl_FillVertexShaderInput(This, vertex_shader, vertexBufData, StartVertexIndex,
496 (!isIndexed) ? (vx_index * skip) :
497 (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) :
498 ((pIdxBufL[StartIdx + vx_index]) * skip));
500 memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
501 IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
503 TRACE_VECTOR(vertex_shader->output.oPos);
504 TRACE_VECTOR(vertex_shader->output.oD[0]);
505 TRACE_VECTOR(vertex_shader->output.oD[1]);
506 TRACE_VECTOR(vertex_shader->output.oT[0]);
507 TRACE_VECTOR(vertex_shader->output.oT[1]);
508 TRACE_VECTOR(vertex_shader->input.V[0]);
509 TRACE_VECTOR(vertex_shader->data->C[0]);
510 TRACE_VECTOR(vertex_shader->data->C[1]);
511 TRACE_VECTOR(vertex_shader->data->C[2]);
512 TRACE_VECTOR(vertex_shader->data->C[3]);
513 TRACE_VECTOR(vertex_shader->data->C[4]);
514 TRACE_VECTOR(vertex_shader->data->C[5]);
515 TRACE_VECTOR(vertex_shader->data->C[6]);
516 TRACE_VECTOR(vertex_shader->data->C[7]);
518 x = vertex_shader->output.oPos.x;
519 y = vertex_shader->output.oPos.y;
520 z = vertex_shader->output.oPos.z;
522 if (1.0f != vertex_shader->output.oPos.w || isRHW) {
523 rhw = vertex_shader->output.oPos.w;
525 /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
526 glColor4fv((float*) &vertex_shader->output.oD[0]);
528 /* Requires secondary color extensions to compile... */
529 #if defined(GL_VERSION_1_4)
530 glSecondaryColor3fv((float*) &vertex_shader->output.oD[1]);
531 checkGLcall("glSecondaryColor3fv");
533 if (checkGLSupport(EXT_SECONDARY_COLOR)) {
534 /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/
535 /*GLExtCall(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]);*/
536 /*checkGLcall("glSecondaryColor3fvEXT");*/
539 /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
540 for (textureNo = 0; textureNo < 4; ++textureNo) {
543 if (!(This->isMultiTexture) && textureNo > 0) {
544 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
547 /* Query tex coords */
548 if (This->StateBlock->textures[textureNo] != NULL) {
549 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
550 case D3DRTYPE_TEXTURE:
551 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
552 s = vertex_shader->output.oT[textureNo].x;
553 t = vertex_shader->output.oT[textureNo].y;
554 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t));
555 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
556 VTRACE(("Skip tex coords, as being system generated\n"));
558 if (This->isMultiTexture) {
559 #if defined(GL_VERSION_1_3)
560 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
562 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
564 /*checkGLcall("glMultiTexCoord2fARB");*/
567 /*checkGLcall("gTexCoord2f");*/
572 case D3DRTYPE_VOLUMETEXTURE:
573 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
574 s = vertex_shader->output.oT[textureNo].x;
575 t = vertex_shader->output.oT[textureNo].y;
576 r = vertex_shader->output.oT[textureNo].z;
577 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r));
578 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
579 VTRACE(("Skip tex coords, as being system generated\n"));
581 if (This->isMultiTexture) {
582 #if defined(GL_VERSION_1_3)
583 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
585 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
587 /*checkGLcall("glMultiTexCoord2fARB");*/
589 glTexCoord3f(s, t, r);
590 /*checkGLcall("gTexCoord3f");*/
596 /* Avoid compiler warnings, need these vars later for other textures */
598 FIXME("Unhandled texture type\n");
603 if (1.0f == rhw || rhw < 0.01f) {
604 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
606 /*checkGLcall("glVertex3f");*/
608 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
609 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
610 /*checkGLcall("glVertex4f");*/
614 * FALSE == useVertexShaderFunction
618 /* Handle these vertexes */
620 glColor4ub((diffuseColor >> 16) & 0xFF,
621 (diffuseColor >> 8) & 0xFF,
622 (diffuseColor >> 0) & 0xFF,
623 (diffuseColor >> 24) & 0xFF);
624 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
625 ((diffuseColor >> 16) & 0xFF) / 255.0f,
626 ((diffuseColor >> 8) & 0xFF) / 255.0f,
627 ((diffuseColor >> 0) & 0xFF) / 255.0f,
628 ((diffuseColor >> 24) & 0xFF) / 255.0f));
632 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
633 glNormal3f(nx, ny, nz);
636 if (1.0f == rhw || rhw < 0.01f) {
637 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
640 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
641 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
647 curVtx = curVtx + skip;
652 checkGLcall("glEnd and previous calls");
655 TRACE("Using fast vertex array code\n");
657 /* Faster version, harder to debug */
658 /* Shuffle to the beginning of the vertexes to render and index from there */
659 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
662 /* Set up the vertex pointers */
664 glVertexPointer(4, GL_FLOAT, skip, curPos);
665 checkGLcall("glVertexPointer(4, ...)");
666 curPos += 4 * sizeof(float);
668 glVertexPointer(3, GL_FLOAT, skip, curPos);
669 checkGLcall("glVertexPointer(3, ...)");
670 curPos += 3 * sizeof(float);
672 glEnableClientState(GL_VERTEX_ARRAY);
673 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
676 /* no such functionality in the fixed function GL pipeline */
677 /* FIXME: Wont get here as will drop to slow method */
678 /* FIXME("Cannot handle blending data here in openGl\n");*/
679 if (checkGLSupport(ARB_VERTEX_BLEND)) {
681 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
684 GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
685 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
686 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
687 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
689 curPos += numBlends * sizeof(float);
691 FIXME("unsupported blending in openGl\n");
694 if (checkGLSupport(ARB_VERTEX_BLEND)) {
696 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
699 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
700 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
707 glNormalPointer(GL_FLOAT, skip, curPos);
708 checkGLcall("glNormalPointer");
709 glEnableClientState(GL_NORMAL_ARRAY);
710 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
711 curPos += 3 * sizeof(float);
713 glDisableClientState(GL_NORMAL_ARRAY);
714 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
716 checkGLcall("glNormal3f(0, 0, 1)");
720 /* no such functionality in the fixed function GL pipeline */
721 /* FIXME: Wont get here as will drop to slow method */
722 FIXME("Cannot change ptSize here in openGl\n");
723 curPos = curPos + sizeof(float);
727 glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
728 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
729 glEnableClientState(GL_COLOR_ARRAY);
730 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
731 curPos += sizeof(DWORD);
734 glDisableClientState(GL_COLOR_ARRAY);
735 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
736 glColor4f(1, 1, 1, 1);
737 checkGLcall("glColor4f(1, 1, 1, 1)");
740 /* Requires secondary color extensions to compile... */
742 #if defined(GL_VERSION_1_4)
743 glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
744 checkGLcall("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos)");
745 glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
746 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY)");
749 /* FIXME: check for GL_EXT_secondary_color */
750 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos);
751 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
752 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
753 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
756 curPos += sizeof(DWORD);
758 #if defined(GL_VERSION_1_4)
759 glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
760 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY)");
761 glSecondaryColor3f(0, 0, 0);
762 checkGLcall("glSecondaryColor3f(0, 0, 0)");
765 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
766 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
767 glSecondaryColor3fEXT(0, 0, 0);
768 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
774 /* numTextures indicates the number of texture coordinates supplied */
775 /* However, the first set may not be for stage 0 texture - it all */
776 /* depends on D3DTSS_TEXCOORDINDEX. */
777 /* The number of bytes for each coordinate set is based off */
778 /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
780 /* Initialize unused coords to unsupplied so we can check later */
781 for (textureNo = numTextures; textureNo < 7; textureNo++) coordPtr[textureNo] = NULL;
783 /* So, for each supplied texture extract the coords */
784 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
786 numCoords[textureNo] = coordIdxInfo & 0x03;
787 coordPtr[textureNo] = curPos;
790 curPos = curPos + sizeof(float);
791 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
792 curPos = curPos + sizeof(float);
793 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
794 curPos = curPos + sizeof(float);
795 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
796 curPos = curPos + sizeof(float);
800 coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
803 /* Now use the appropriate set of texture indexes */
804 for (textureNo = 0; textureNo < This->TextureUnits; ++textureNo) {
806 if (!(This->isMultiTexture) && textureNo > 0) {
807 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
811 /* Query tex coords */
812 if ((This->StateBlock->textures[textureNo] != NULL) && (useVertexShaderFunction == FALSE)) {
813 int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
816 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
819 #if defined(GL_VERSION_1_3)
820 glClientActiveTexture(GL_TEXTURE0 + textureNo);
822 glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
824 switch (numCoords[coordIdx]) { /* Supply the provided texture coords */
825 case D3DFVF_TEXTUREFORMAT1: numFloats = 1; break;
826 case D3DFVF_TEXTUREFORMAT2: numFloats = 2; break;
827 case D3DFVF_TEXTUREFORMAT3: numFloats = 3; break;
828 case D3DFVF_TEXTUREFORMAT4: numFloats = 4; break;
829 default: numFloats = 0; break;
832 if (numFloats == 0 || coordIdx >= numTextures) {
833 VTRACE(("Skipping as invalid request - numfloats=%d, coordIdx=%d, numTextures=%d\n", numFloats, coordIdx, numTextures));
834 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
835 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
837 VTRACE(("tex: %d, ptr=%p, numcoords=%d\n", textureNo, coordPtr[coordIdx], numFloats));
838 glTexCoordPointer(numFloats, GL_FLOAT, skip, coordPtr[coordIdx]);
839 checkGLcall("glTexCoordPointer(x, ...)");
840 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
841 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
847 /* Finally do the drawing */
850 TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
852 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
853 glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT,
854 (char *)idxData+(2 * StartIdx));
856 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
857 GL_UNSIGNED_SHORT, (char *)idxData+(2 * StartIdx));
860 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
861 glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT,
862 (char *)idxData+(4 * StartIdx));
864 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
865 GL_UNSIGNED_INT, (char *)idxData+(2 * StartIdx));
868 checkGLcall("glDrawRangeElements");
872 /* Note first is now zero as we shuffled along earlier */
873 TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
874 glDrawArrays(primType, 0, NumVertexes);
875 checkGLcall("glDrawArrays");
880 /* If no normals, restore previous lighting state */
882 if (isLightingOn) glEnable(GL_LIGHTING);
883 else glDisable(GL_LIGHTING);
884 TRACE("Restored lighting to original state\n");
894 Simple utility routines used for dx -> gl mapping of byte formats
896 SHORT bytesPerPixel(D3DFORMAT fmt) {
901 case D3DFMT_A4R4G4B4: retVal = 2; break;
902 case D3DFMT_A8R8G8B8: retVal = 4; break;
903 case D3DFMT_X8R8G8B8: retVal = 4; break;
904 case D3DFMT_R8G8B8: retVal = 3; break;
905 case D3DFMT_R5G6B5: retVal = 2; break;
906 case D3DFMT_A1R5G5B5: retVal = 2; break;
907 /* depth/stencil buffer */
908 case D3DFMT_D16_LOCKABLE: retVal = 2; break;
909 case D3DFMT_D32: retVal = 4; break;
910 case D3DFMT_D15S1: retVal = 2; break;
911 case D3DFMT_D24S8: retVal = 4; break;
912 case D3DFMT_D16: retVal = 2; break;
913 case D3DFMT_D24X8: retVal = 4; break;
914 case D3DFMT_D24X4S4: retVal = 4; break;
917 /* Guess at the highest value of the above */
918 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt);
922 FIXME("Unhandled fmt %d\n", fmt);
925 TRACE("bytes/Pxl for fmt %d = %d\n", fmt, retVal);
929 GLint fmt2glintFmt(D3DFORMAT fmt) {
933 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
934 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
935 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
936 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
937 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
938 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
940 FIXME("Unhandled fmt %d\n", fmt);
943 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt, retVal);
946 GLenum fmt2glFmt(D3DFORMAT fmt) {
950 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
951 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
952 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
953 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
954 case D3DFMT_R5G6B5: retVal = GL_RGB; break;
955 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
957 FIXME("Unhandled fmt %d\n", fmt);
960 TRACE("fmt2glFmt for fmt %d = %x\n", fmt, retVal);
963 DWORD fmt2glType(D3DFORMAT fmt) {
967 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
968 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
969 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
970 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5_REV; break;
971 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
972 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
974 FIXME("Unhandled fmt %d\n", fmt);
977 TRACE("fmt2glType for fmt %d = %x\n", fmt, retVal);
981 int SOURCEx_RGB_EXT(DWORD arg) {
983 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
984 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
985 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
986 case D3DTSS_ALPHAARG0:
987 case D3DTSS_ALPHAARG1:
988 case D3DTSS_ALPHAARG2:
990 FIXME("Invalid arg %ld\n", arg);
991 return GL_SOURCE0_RGB_EXT;
994 int OPERANDx_RGB_EXT(DWORD arg) {
996 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
997 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
998 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
999 case D3DTSS_ALPHAARG0:
1000 case D3DTSS_ALPHAARG1:
1001 case D3DTSS_ALPHAARG2:
1003 FIXME("Invalid arg %ld\n", arg);
1004 return GL_OPERAND0_RGB_EXT;
1007 int SOURCEx_ALPHA_EXT(DWORD arg) {
1009 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
1010 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
1011 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
1012 case D3DTSS_COLORARG0:
1013 case D3DTSS_COLORARG1:
1014 case D3DTSS_COLORARG2:
1016 FIXME("Invalid arg %ld\n", arg);
1017 return GL_SOURCE0_ALPHA_EXT;
1020 int OPERANDx_ALPHA_EXT(DWORD arg) {
1022 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
1023 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
1024 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
1025 case D3DTSS_COLORARG0:
1026 case D3DTSS_COLORARG1:
1027 case D3DTSS_COLORARG2:
1029 FIXME("Invalid arg %ld\n", arg);
1030 return GL_OPERAND0_ALPHA_EXT;
1033 GLenum StencilOp(DWORD op) {
1035 case D3DSTENCILOP_KEEP : return GL_KEEP;
1036 case D3DSTENCILOP_ZERO : return GL_ZERO;
1037 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
1038 case D3DSTENCILOP_INCRSAT : return GL_INCR;
1039 case D3DSTENCILOP_DECRSAT : return GL_DECR;
1040 case D3DSTENCILOP_INVERT : return GL_INVERT;
1041 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op D3DSTENCILOP_INCR\n");
1042 return GL_INCR; /* Fixme - needs to support wrap */
1043 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op D3DSTENCILOP_DECR\n");
1044 return GL_DECR; /* Fixme - needs to support wrap */
1046 FIXME("Invalid stencil op %ld\n", op);
1054 void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand)
1056 BOOL isAlphaReplicate = FALSE;
1057 BOOL isComplement = FALSE;
1059 *operand = GL_SRC_COLOR;
1060 *source = GL_TEXTURE;
1062 /* Catch alpha replicate */
1063 if (iValue & D3DTA_ALPHAREPLICATE) {
1064 iValue = iValue & ~D3DTA_ALPHAREPLICATE;
1065 isAlphaReplicate = TRUE;
1068 /* Catch Complement */
1069 if (iValue & D3DTA_COMPLEMENT) {
1070 iValue = iValue & ~D3DTA_COMPLEMENT;
1071 isComplement = TRUE;
1074 /* Calculate the operand */
1075 if (isAlphaReplicate && !isComplement) {
1076 *operand = GL_SRC_ALPHA;
1077 } else if (isAlphaReplicate && isComplement) {
1078 *operand = GL_ONE_MINUS_SRC_ALPHA;
1079 } else if (isComplement) {
1081 *operand = GL_ONE_MINUS_SRC_ALPHA;
1083 *operand = GL_ONE_MINUS_SRC_COLOR;
1087 *operand = GL_SRC_ALPHA;
1089 *operand = GL_SRC_COLOR;
1093 /* Calculate the source */
1094 switch (iValue & D3DTA_SELECTMASK) {
1095 case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT;
1097 case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT;
1099 case D3DTA_TEXTURE: *source = GL_TEXTURE;
1101 case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT;
1103 case D3DTA_SPECULAR:
1105 * According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
1106 * isnt supported until base GL supports it
1107 * There is no concept of temp registers as far as I can tell
1111 FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
1112 *source = GL_TEXTURE;
1117 /* Apply the current values to the specified texture stage */
1118 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
1119 ICOM_THIS(IDirect3DDevice8Impl,iface);
1123 /* Make appropriate texture active */
1124 if (This->isMultiTexture) {
1125 #if defined(GL_VERSION_1_3)
1126 glActiveTexture(GL_TEXTURE0 + Stage);
1128 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
1130 checkGLcall("glActiveTextureARB");
1131 } else if (Stage > 0) {
1132 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
1135 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
1136 for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
1137 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
1140 /* Note the D3DRS value applies to all textures, but GL has one
1141 per texture, so apply it now ready to be used! */
1142 col[0] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
1143 col[1] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
1144 col[2] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
1145 col[3] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
1146 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1147 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1149 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
1152 /* IDirect3D IUnknown parts follow: */
1153 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
1155 ICOM_THIS(IDirect3DDevice8Impl,iface);
1157 if (IsEqualGUID(riid, &IID_IUnknown)
1158 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
1159 IDirect3DDevice8Impl_AddRef(iface);
1164 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
1165 return E_NOINTERFACE;
1168 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
1169 ICOM_THIS(IDirect3DDevice8Impl,iface);
1170 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
1171 return ++(This->ref);
1174 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
1175 ICOM_THIS(IDirect3DDevice8Impl,iface);
1176 ULONG ref = --This->ref;
1177 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
1179 HeapFree(GetProcessHeap(), 0, This);
1184 /* IDirect3DDevice Interface follow: */
1185 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
1186 ICOM_THIS(IDirect3DDevice8Impl,iface);
1187 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
1191 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
1192 ICOM_THIS(IDirect3DDevice8Impl,iface);
1193 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
1195 * pretend we have 32MB of any type of memory queried.
1197 return (1024*1024*32);
1200 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
1201 ICOM_THIS(IDirect3DDevice8Impl,iface);
1202 FIXME("(%p) : stub\n", This); return D3D_OK;
1204 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
1205 ICOM_THIS(IDirect3DDevice8Impl,iface);
1206 TRACE("(%p) : returning %p\n", This, This->direct3d8);
1209 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
1211 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
1214 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
1215 ICOM_THIS(IDirect3DDevice8Impl,iface);
1216 FIXME("(%p) : stub, calling idirect3d for now\n", This);
1217 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
1220 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
1225 ICOM_THIS(IDirect3DDevice8Impl,iface);
1226 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
1227 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
1228 pMode->RefreshRate = 85; /*FIXME: How to identify? */
1230 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1231 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1235 case 8: pMode->Format = D3DFMT_R8G8B8; break;
1236 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1237 case 24: pMode->Format = D3DFMT_R8G8B8; break;
1238 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1240 FIXME("Unrecognized display mode format\n");
1241 pMode->Format = D3DFMT_UNKNOWN;
1244 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
1247 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1248 ICOM_THIS(IDirect3DDevice8Impl,iface);
1249 TRACE("(%p) copying to %p\n", This, pParameters);
1250 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1253 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1254 ICOM_THIS(IDirect3DDevice8Impl,iface);
1255 FIXME("(%p) : stub\n", This); return D3D_OK;
1257 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1258 ICOM_THIS(IDirect3DDevice8Impl,iface);
1259 FIXME("(%p) : stub\n", This); return;
1261 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1262 ICOM_THIS(IDirect3DDevice8Impl,iface);
1263 FIXME("(%p) : stub\n", This); return D3D_OK;
1265 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1266 ICOM_THIS(IDirect3DDevice8Impl,iface);
1267 FIXME("(%p) : stub\n", This);
1271 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1272 ICOM_THIS(IDirect3DDevice8Impl,iface);
1273 FIXME("(%p) : stub\n", This); return D3D_OK;
1275 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1276 ICOM_THIS(IDirect3DDevice8Impl,iface);
1277 TRACE("(%p) : complete stub!\n", This);
1281 glXSwapBuffers(This->display, This->win);
1282 checkGLcall("glXSwapBuffers");
1288 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
1289 ICOM_THIS(IDirect3DDevice8Impl,iface);
1290 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1291 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1293 if (BackBuffer > This->PresentParms.BackBufferCount - 1) {
1294 FIXME("Only one backBuffer currently supported\n");
1295 return D3DERR_INVALIDCALL;
1298 /* Note inc ref on returned surface */
1299 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1303 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1304 ICOM_THIS(IDirect3DDevice8Impl,iface);
1305 FIXME("(%p) : stub\n", This);
1308 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1309 ICOM_THIS(IDirect3DDevice8Impl,iface);
1310 FIXME("(%p) : stub\n", This); return;
1312 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1313 ICOM_THIS(IDirect3DDevice8Impl,iface);
1314 FIXME("(%p) : stub\n", This); return;
1316 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1317 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1318 IDirect3DTexture8Impl *object;
1323 ICOM_THIS(IDirect3DDevice8Impl,iface);
1325 /* Allocate the storage for the device */
1326 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
1327 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1328 object->lpVtbl = &Direct3DTexture8_Vtbl;
1329 object->Device = This;
1330 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->device);*/
1331 object->ResourceType = D3DRTYPE_TEXTURE;
1333 object->width = Width;
1334 object->height = Height;
1335 object->levels = Levels;
1336 object->usage = Usage;
1337 object->format = Format;
1340 /* Calculate levels for mip mapping */
1345 while (tmpW > 1 && tmpH > 1) {
1346 tmpW = max(1, tmpW / 2);
1347 tmpH = max(1, tmpH / 2);
1350 TRACE("Calculated levels = %d\n", object->levels);
1353 /* Generate all the surfaces */
1356 for (i = 0; i < object->levels; i++)
1358 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1359 object->surfaces[i]->Container = (IUnknown*) object;
1360 /*IUnknown_AddRef(object->surfaces[i]->Container);*/
1361 object->surfaces[i]->myDesc.Usage = Usage;
1362 object->surfaces[i]->myDesc.Pool = Pool ;
1364 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1365 tmpW = max(1, tmpW / 2);
1366 tmpH = max(1, tmpH / 2);
1369 *ppTexture = (LPDIRECT3DTEXTURE8) object;
1372 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1374 IDirect3DVolumeTexture8Impl *object;
1380 ICOM_THIS(IDirect3DDevice8Impl,iface);
1382 /* Allocate the storage for it */
1383 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);
1384 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1385 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1386 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1387 object->Device = This;
1388 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1391 object->width = Width;
1392 object->height = Height;
1393 object->depth = Depth;
1394 object->levels = Levels;
1395 object->usage = Usage;
1396 object->format = Format;
1398 /* Calculate levels for mip mapping */
1404 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1405 tmpW = max(1, tmpW / 2);
1406 tmpH = max(1, tmpH / 2);
1407 tmpD = max(1, tmpD / 2);
1410 TRACE("Calculated levels = %d\n", object->levels);
1413 /* Generate all the surfaces */
1418 for (i = 0; i < object->levels; i++)
1420 IDirect3DVolume8Impl *volume;
1422 /* Create the volume - No entry point for this seperately?? */
1423 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1424 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1426 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1427 volume->Device = This;
1428 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) volume->Device);*/
1429 volume->ResourceType = D3DRTYPE_VOLUME;
1430 volume->Container = (IUnknown*) object;
1431 /*IUnknown_AddRef(volume->Container);*/
1434 volume->myDesc.Width = Width;
1435 volume->myDesc.Height = Height;
1436 volume->myDesc.Depth = Depth;
1437 volume->myDesc.Format = Format;
1438 volume->myDesc.Type = D3DRTYPE_VOLUME;
1439 volume->myDesc.Pool = Pool;
1440 volume->myDesc.Usage = Usage;
1441 volume->bytesPerPixel = bytesPerPixel(Format);
1442 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1443 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1445 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
1446 volume, volume->allocatedMemory, volume->myDesc.Size);
1448 tmpW = max(1, tmpW / 2);
1449 tmpH = max(1, tmpH / 2);
1450 tmpD = max(1, tmpD / 2);
1453 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8) object;
1456 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
1458 IDirect3DCubeTexture8Impl *object;
1459 ICOM_THIS(IDirect3DDevice8Impl,iface);
1463 /* Allocate the storage for it */
1464 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
1465 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1466 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1468 object->Device = This;
1469 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1470 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1472 object->edgeLength = EdgeLength;
1473 object->levels = Levels;
1474 object->usage = Usage;
1475 object->format = Format;
1477 /* Calculate levels for mip mapping */
1482 tmpW = max(1, tmpW / 2);
1485 TRACE("Calculated levels = %d\n", object->levels);
1488 /* Generate all the surfaces */
1490 for (i = 0; i < object->levels; i++)
1492 /* Create the 6 faces */
1493 for (j = 0; j < 6; j++) {
1494 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1495 object->surfaces[j][i]->Container = (IUnknown*) object;
1496 /*IUnknown_AddRef(object->surfaces[j][i]->Container);*/
1497 object->surfaces[j][i]->myDesc.Usage = Usage;
1498 object->surfaces[j][i]->myDesc.Pool = Pool;
1500 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1501 tmpW = max(1, tmpW / 2);
1505 TRACE("(%p) : Iface@%p\n", This, object);
1506 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1509 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1510 IDirect3DVertexBuffer8Impl *object;
1512 ICOM_THIS(IDirect3DDevice8Impl,iface);
1514 /* Allocate the storage for the device */
1515 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1516 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1517 object->Device = This;
1518 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1519 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1521 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1522 object->currentDesc.Usage = Usage;
1523 object->currentDesc.Pool = Pool;
1524 object->currentDesc.FVF = FVF;
1525 object->currentDesc.Size = Size;
1527 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1529 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1533 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) {
1534 IDirect3DIndexBuffer8Impl *object;
1536 ICOM_THIS(IDirect3DDevice8Impl,iface);
1537 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
1539 /* Allocate the storage for the device */
1540 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1541 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1542 object->Device = This;
1543 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1545 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1547 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1548 object->currentDesc.Usage = Usage;
1549 object->currentDesc.Pool = Pool;
1550 object->currentDesc.Format = Format;
1551 object->currentDesc.Size = Length;
1553 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1555 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1557 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1561 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
1562 IDirect3DSurface8Impl *object;
1564 ICOM_THIS(IDirect3DDevice8Impl,iface);
1566 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1567 if (NULL == object) {
1569 return D3DERR_OUTOFVIDEOMEMORY;
1571 *ppSurface = (LPDIRECT3DSURFACE8) object;
1572 object->lpVtbl = &Direct3DSurface8_Vtbl;
1573 object->Device = This;
1574 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1575 object->ResourceType = D3DRTYPE_SURFACE;
1576 object->Container = (IUnknown*) This;
1577 /*IUnknown_AddRef(object->Container);*/
1580 object->myDesc.Width = Width;
1581 object->myDesc.Height = Height;
1582 object->myDesc.Format = Format;
1583 object->myDesc.Type = D3DRTYPE_SURFACE;
1584 object->myDesc.Usage = D3DUSAGE_RENDERTARGET;
1585 object->myDesc.Pool = D3DPOOL_DEFAULT;
1586 object->myDesc.MultiSampleType = MultiSample;
1587 object->bytesPerPixel = bytesPerPixel(Format);
1588 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1589 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1590 object->lockable = Lockable;
1591 object->locked = FALSE;
1593 TRACE("(%p) : w(%d) h(%d) fmt(%d) lockable(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, Lockable, *ppSurface, object->allocatedMemory, object->myDesc.Size);
1596 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
1597 IDirect3DSurface8Impl *object;
1599 ICOM_THIS(IDirect3DDevice8Impl,iface);
1601 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1602 if (NULL == object) {
1604 return D3DERR_OUTOFVIDEOMEMORY;
1606 *ppSurface = (LPDIRECT3DSURFACE8) object;
1607 object->lpVtbl = &Direct3DSurface8_Vtbl;
1608 object->Device = This;
1609 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1610 object->ResourceType = D3DRTYPE_SURFACE;
1611 object->Container = (IUnknown*) This;
1612 /*IUnknown_AddRef(object->Container);*/
1615 object->myDesc.Width = Width;
1616 object->myDesc.Height = Height;
1617 object->myDesc.Format = Format;
1618 object->myDesc.Type = D3DRTYPE_SURFACE;
1619 object->myDesc.Usage = D3DUSAGE_DEPTHSTENCIL;
1620 object->myDesc.Pool = D3DPOOL_DEFAULT;
1621 object->myDesc.MultiSampleType = MultiSample;
1622 object->bytesPerPixel = bytesPerPixel(Format);
1623 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1624 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1625 object->lockable = TRUE;
1626 object->locked = FALSE;
1628 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);
1631 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
1632 IDirect3DSurface8Impl *object;
1634 ICOM_THIS(IDirect3DDevice8Impl,iface);
1636 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1637 *ppSurface = (LPDIRECT3DSURFACE8) object;
1638 object->lpVtbl = &Direct3DSurface8_Vtbl;
1639 object->Device = This;
1640 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1641 object->ResourceType = D3DRTYPE_SURFACE;
1642 object->Container = (IUnknown*) This;
1643 /*IUnknown_AddRef(object->Container);*/
1646 object->myDesc.Width = Width;
1647 object->myDesc.Height = Height;
1648 object->myDesc.Format = Format;
1649 object->myDesc.Type = D3DRTYPE_SURFACE;
1650 object->myDesc.Usage = 0;
1651 object->myDesc.Pool = D3DPOOL_SYSTEMMEM;
1652 object->bytesPerPixel = bytesPerPixel(Format);
1653 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1654 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1655 object->lockable = TRUE;
1656 object->locked = FALSE;
1658 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);
1661 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1662 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1664 HRESULT rc = D3D_OK;
1665 IDirect3DBaseTexture8* texture = NULL;
1668 IDirect3DSurface8Impl *src = (IDirect3DSurface8Impl*) pSourceSurface;
1669 IDirect3DSurface8Impl *dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1671 ICOM_THIS(IDirect3DDevice8Impl,iface);
1672 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1673 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1675 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1676 a sample and doesnt seem to break anything as far as I can tell */
1677 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1678 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1679 rc = D3DERR_INVALIDCALL;
1681 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1682 TRACE("Converting dest to same format as source, since dest was unknown\n");
1683 dst->myDesc.Format = src->myDesc.Format;
1685 /* Convert container as well */
1686 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1687 if (texture != NULL) {
1689 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1690 case D3DRTYPE_TEXTURE:
1691 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1693 case D3DRTYPE_VOLUMETEXTURE:
1694 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1696 case D3DRTYPE_CUBETEXTURE:
1697 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1700 FIXME("Unhandled texture type\n");
1703 /** Releasing texture after GetContainer */
1704 IDirect3DBaseTexture8_Release(texture);
1708 /* Quick if complete copy ... */
1709 if (rc == D3D_OK && (cRects == 0 && pSourceRectsArray==NULL && pDestPointsArray==NULL &&
1710 src->myDesc.Width == dst->myDesc.Width &&
1711 src->myDesc.Height == dst->myDesc.Height)) {
1714 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8)src, &lr, NULL, D3DLOCK_READONLY);
1715 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8)dst, &lr, NULL, D3DLOCK_DISCARD);
1716 TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1718 memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);
1720 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8)src);
1721 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8)dst);
1722 TRACE("Unlocked src and dst\n");
1726 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1727 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1728 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1730 char *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1731 char *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1733 /* Copy rect by rect */
1734 for (i=0; i<cRects; i++) {
1735 CONST RECT *r = &pSourceRectsArray[i];
1736 CONST POINT *p = &pDestPointsArray[i];
1739 int copyperline = (r->right - r->left) * bytesPerPixel;
1744 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top,
1745 r->right, r->bottom, p->x, p->y);
1747 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8)src, &lr, r, D3DLOCK_READONLY);
1748 dest_rect.left = p->x;
1749 dest_rect.top = p->y;
1750 dest_rect.right = p->x + (r->right - r->left);
1751 dest_rect.left = p->y + (r->bottom - r->top);
1752 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8)dst, &lr, &dest_rect, 0L);
1753 TRACE("Locked src and dst\n");
1755 /* Find where to start */
1756 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1757 to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel);
1759 /* Copy line by line */
1760 for (j=0; j<(r->bottom - r->top); j++) {
1761 memcpy(to + (j*pitchTo), from + (j*pitchFrom), copyperline);
1764 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8)src);
1765 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8)dst);
1766 TRACE("Unlocked src and dst\n");
1772 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1773 if (texture != NULL) {
1775 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1776 case D3DRTYPE_TEXTURE:
1778 IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)texture;
1779 pTexture->Dirty = TRUE;
1782 case D3DRTYPE_VOLUMETEXTURE:
1784 IDirect3DVolumeTexture8Impl *pTexture = (IDirect3DVolumeTexture8Impl *)texture;
1785 pTexture->Dirty = TRUE;
1788 case D3DRTYPE_CUBETEXTURE:
1790 IDirect3DCubeTexture8Impl *pTexture = (IDirect3DCubeTexture8Impl *)texture;
1791 pTexture->Dirty = TRUE;
1795 FIXME("Unhandled texture type\n");
1798 /** Releasing texture after GetContainer */
1799 IDirect3DBaseTexture8_Release(texture);
1805 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
1806 ICOM_THIS(IDirect3DDevice8Impl,iface);
1807 FIXME("(%p) : stub\n", This);
1810 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1812 D3DLOCKED_RECT lockedRect;
1816 ICOM_THIS(IDirect3DDevice8Impl,iface);
1818 FIXME("(%p) : stub\n", This);
1820 if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) {
1821 return D3DERR_INVALIDCALL;
1824 hr = IDirect3DSurface8Impl_LockRect(pDestSurface, &lockedRect, NULL, 0);
1826 return D3DERR_INVALIDCALL;
1832 vcheckGLcall("glFlush");
1833 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1834 vcheckGLcall("glIntegerv");
1835 glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
1836 vcheckGLcall("glIntegerv");
1838 glReadBuffer(GL_FRONT);
1839 vcheckGLcall("glReadBuffer");
1840 glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
1841 vcheckGLcall("glPixelStorei");
1842 glReadPixels(0, 0, This->PresentParms.BackBufferWidth, This->PresentParms.BackBufferHeight,
1843 GL_BGRA, GL_UNSIGNED_BYTE, lockedRect.pBits);
1844 vcheckGLcall("glReadPixels");
1845 glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
1846 vcheckGLcall("glPixelStorei");
1847 glReadBuffer(prev_read);
1848 vcheckGLcall("glReadBuffer");
1851 hr = IDirect3DSurface8Impl_UnlockRect(pDestSurface);
1854 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
1855 ICOM_THIS(IDirect3DDevice8Impl,iface);
1857 if ((IDirect3DSurface8Impl*) pRenderTarget == This->frontBuffer && (IDirect3DSurface8Impl*) pNewZStencil == This->depthStencilBuffer) {
1858 TRACE("Trying to do a NOP SetRenderTarget operation\n");
1862 FIXME("(%p) : invalid stub expect crash newRender@%p newZStencil@%p\n", This, pRenderTarget, pNewZStencil);
1866 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1867 ICOM_THIS(IDirect3DDevice8Impl,iface);
1869 TRACE("(%p)->(%p)\n", This, This->frontBuffer);
1871 *ppRenderTarget = (LPDIRECT3DSURFACE8) This->frontBuffer;
1872 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1876 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1877 ICOM_THIS(IDirect3DDevice8Impl,iface);
1879 TRACE("(%p)->(%p)\n", This, ppZStencilSurface);
1881 /* Note inc ref on returned surface */
1882 *ppZStencilSurface = (LPDIRECT3DSURFACE8) This->depthStencilBuffer;
1883 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppZStencilSurface);
1888 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1889 ICOM_THIS(IDirect3DDevice8Impl,iface);
1890 TRACE("(%p) : stub\n", This);
1893 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1894 ICOM_THIS(IDirect3DDevice8Impl,iface);
1895 TRACE("(%p)\n", This);
1900 checkGLcall("glFlush");
1902 /* Useful for debugging sometimes!
1903 printf("Hit Enter ...\n");
1909 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) {
1910 ICOM_THIS(IDirect3DDevice8Impl,iface);
1912 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1913 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1914 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1915 GLbitfield glMask = 0;
1916 GLboolean old_ztest;
1917 GLfloat old_z_clear_value;
1918 GLint old_stencil_clear_value;
1919 GLfloat old_color_clear_value[4];
1922 CONST D3DRECT *curRect;
1924 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1925 Count, pRects, Flags, Z, Stencil);
1928 if (Count > 0 && pRects) {
1929 glEnable(GL_SCISSOR_TEST);
1930 checkGLcall("glEnable GL_SCISSOR_TEST");
1936 for (i = 0; i < Count || i == 0; i++) {
1939 /* Note gl uses lower left, width/height */
1940 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1941 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1942 curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1943 glScissor(curRect->x1, curRect->y2, curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1944 checkGLcall("glScissor");
1947 /* Clear the whole screen */
1948 if (Flags & D3DCLEAR_STENCIL) {
1949 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1950 glClearStencil(Stencil);
1951 checkGLcall("glClearStencil");
1952 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1955 if (Flags & D3DCLEAR_ZBUFFER) {
1956 glGetBooleanv(GL_DEPTH_WRITEMASK, &old_ztest);
1957 glDepthMask(GL_TRUE);
1958 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1960 checkGLcall("glClearDepth");
1961 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1964 if (Flags & D3DCLEAR_TARGET) {
1965 TRACE("Clearing screen with glClear to color %lx\n", Color);
1966 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1967 glClearColor(((Color >> 16) & 0xFF) / 255.0,
1968 ((Color >> 8) & 0xFF) / 255.0,
1969 ((Color >> 0) & 0xFF) / 255.0,
1970 ((Color >> 24) & 0xFF) / 255.0);
1971 checkGLcall("glClearColor");
1972 glMask = glMask | GL_COLOR_BUFFER_BIT;
1976 checkGLcall("glClear");
1978 if (Flags & D3DCLEAR_STENCIL) {
1979 glClearStencil(old_stencil_clear_value);
1981 if (Flags & D3DCLEAR_ZBUFFER) {
1982 glDepthMask(old_ztest);
1983 glClearDepth(old_z_clear_value);
1985 if (Flags & D3DCLEAR_TARGET) {
1986 glClearColor(old_color_clear_value[0],
1987 old_color_clear_value[1],
1988 old_color_clear_value[2],
1989 old_color_clear_value[3]);
1992 if (curRect) curRect = curRect + sizeof(D3DRECT);
1995 if (Count > 0 && pRects) {
1996 glDisable(GL_SCISSOR_TEST);
1997 checkGLcall("glDisable");
2003 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts,CONST D3DMATRIX* lpmatrix) {
2004 ICOM_THIS(IDirect3DDevice8Impl,iface);
2008 BOOL viewChanged = TRUE;
2011 /* Most of this routine, comments included copied from ddraw tree initially: */
2012 TRACE("(%p) : State=%d\n", This, d3dts);
2014 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
2015 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
2016 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
2018 /* Handle recording of state blocks */
2019 if (This->isRecordingState) {
2020 TRACE("Recording... not performing anything\n");
2025 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
2027 where ViewMat = Camera space, WorldMat = world space.
2029 In OpenGL, camera and world space is combined into GL_MODELVIEW
2030 matrix. The Projection matrix stay projection matrix. */
2032 /* After reading through both OpenGL and Direct3D documentations, I
2033 thought that D3D matrices were written in 'line major mode' transposed
2034 from OpenGL's 'column major mode'. But I found out that a simple memcpy
2035 works fine to transfer one matrix format to the other (it did not work
2036 when transposing)....
2039 1) are the documentations wrong
2040 2) does the matrix work even if they are not read correctly
2041 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
2042 loading using glLoadMatrix ?
2044 Anyway, I always use 'conv_mat' to transfer the matrices from one format
2045 to the other so that if I ever find out that I need to transpose them, I
2046 will able to do it quickly, only by changing the macro conv_mat. */
2048 if (d3dts <= 256) { /* WORLDMATRIX(0) == 256! */
2050 case D3DTS_WORLDMATRIX(0):
2051 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)]);
2055 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_VIEW]);
2058 case D3DTS_PROJECTION:
2059 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_PROJECTION]);
2062 case D3DTS_TEXTURE0:
2063 case D3DTS_TEXTURE1:
2064 case D3DTS_TEXTURE2:
2065 case D3DTS_TEXTURE3:
2066 case D3DTS_TEXTURE4:
2067 case D3DTS_TEXTURE5:
2068 case D3DTS_TEXTURE6:
2069 case D3DTS_TEXTURE7:
2070 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
2074 FIXME("Unhandled transform state!!\n");
2079 * Indexed Vertex Blending Matrices 256 -> 511
2082 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
2083 if (checkGLSupport(ARB_VERTEX_BLEND)) {
2085 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
2091 * Move the GL operation to outside of switch to make it work
2092 * regardless of transform set order.
2095 if (memcmp(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX))) {
2096 glMatrixMode(GL_PROJECTION);
2097 checkGLcall("glMatrixMode");
2098 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
2099 checkGLcall("glLoadMatrixf");
2100 memcpy(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX));
2102 TRACE("Skipping as projection already correct\n");
2105 glMatrixMode(GL_MODELVIEW);
2106 checkGLcall("glMatrixMode");
2107 viewChanged = FALSE;
2108 if (memcmp(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX))) {
2109 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2110 checkGLcall("glLoadMatrixf");
2111 memcpy(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX));
2114 /* If we are changing the View matrix, reset the light and clipping planes to the new view */
2115 if (d3dts == D3DTS_VIEW) {
2117 /* NOTE: We have to reset the positions even if the light/plane is not currently
2118 enabled, since the call to enable it will not reset the position. */
2121 for (k = 0; k < This->maxLights; k++) {
2122 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
2123 checkGLcall("glLightfv posn");
2124 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
2125 checkGLcall("glLightfv dirn");
2128 /* Reset Clipping Planes if clipping is enabled */
2129 for (k = 0; k < This->clipPlanes; k++) {
2130 glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
2131 checkGLcall("glClipPlane");
2134 /* Reapply texture transforms as based off modelview when applied */
2135 for (Stage = 0; Stage < This->TextureUnits; Stage++) {
2137 /* Now apply texture transforms if not applying to the dummy textures */
2138 #if defined(GL_VERSION_1_3)
2139 glActiveTexture(GL_TEXTURE0 + Stage);
2141 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2143 checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage);");
2145 glMatrixMode(GL_TEXTURE);
2146 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
2150 conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
2151 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
2153 checkGLcall("Load matrix for texture");
2155 glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
2157 } else if (d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) {
2158 /* Now apply texture transforms if not applying to the dummy textures */
2159 Stage = d3dts-D3DTS_TEXTURE0;
2161 if (memcmp(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0], sizeof(D3DMATRIX))) {
2162 memcpy(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0], sizeof(D3DMATRIX));
2164 #if defined(GL_VERSION_1_3)
2165 glActiveTexture(GL_TEXTURE0 + Stage);
2167 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2169 checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage)");
2171 glMatrixMode(GL_TEXTURE);
2172 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
2176 conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
2177 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
2179 checkGLcall("Load matrix for texture");
2180 glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
2182 TRACE("Skipping texture transform as already correct\n");
2186 TRACE("Skipping view setup as view already correct\n");
2190 * Vertex Blending as described
2191 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/enums/d3dvertexblendflags.asp
2193 switch (This->UpdateStateBlock->vertex_blend) {
2194 case D3DVBF_DISABLE:
2196 if (viewChanged == TRUE ||
2197 (memcmp(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX)))) {
2198 memcpy(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX));
2199 if (viewChanged==FALSE) {
2200 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2201 checkGLcall("glLoadMatrixf");
2203 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
2204 checkGLcall("glMultMatrixf");
2206 TRACE("Skipping as world already correct\n");
2210 case D3DVBF_1WEIGHTS:
2211 case D3DVBF_2WEIGHTS:
2212 case D3DVBF_3WEIGHTS:
2214 FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n");
2216 * doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*)
2217 * so waiting for the values before matrix work
2218 for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
2219 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
2220 checkGLcall("glMultMatrixf");
2225 case D3DVBF_TWEENING:
2227 FIXME("valid/correct D3DVBF_TWEENING\n");
2228 f = This->UpdateStateBlock->tween_factor;
2229 m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f;
2230 m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f;
2231 m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f;
2232 m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
2233 if (viewChanged==FALSE) {
2234 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2235 checkGLcall("glLoadMatrixf");
2237 glMultMatrixf((float *) &m.u.m[0][0]);
2238 checkGLcall("glMultMatrixf");
2241 case D3DVBF_0WEIGHTS:
2243 FIXME("valid/correct D3DVBF_0WEIGHTS\n");
2244 /* single matrix of weight 1.0f */
2245 m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f;
2246 m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f;
2247 m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f;
2248 m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
2249 if (viewChanged == FALSE) {
2250 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2251 checkGLcall("glLoadMatrixf");
2253 glMultMatrixf((float *) &m.u.m[0][0]);
2254 checkGLcall("glMultMatrixf");
2258 break; /* stupid compilator */
2266 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
2267 ICOM_THIS(IDirect3DDevice8Impl,iface);
2268 TRACE("(%p) : for State %d\n", This, State);
2269 memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX));
2273 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
2274 D3DMATRIX *mat = NULL;
2277 /* Note: Using UpdateStateBlock means it would be recorded in a state block change,
2278 but works regardless of recording being on.
2279 If this is found to be wrong, change to StateBlock. */
2280 ICOM_THIS(IDirect3DDevice8Impl,iface);
2281 TRACE("(%p) : For state %u\n", This, State);
2283 if (State < HIGHEST_TRANSFORMSTATE)
2285 mat = &This->UpdateStateBlock->transforms[State];
2287 FIXME("Unhandled transform state!!\n");
2290 /* Copied from ddraw code: */
2291 temp.u.s._11 = (mat->u.s._11 * pMatrix->u.s._11) + (mat->u.s._21 * pMatrix->u.s._12) + (mat->u.s._31 * pMatrix->u.s._13) + (mat->u.s._41 * pMatrix->u.s._14);
2292 temp.u.s._21 = (mat->u.s._11 * pMatrix->u.s._21) + (mat->u.s._21 * pMatrix->u.s._22) + (mat->u.s._31 * pMatrix->u.s._23) + (mat->u.s._41 * pMatrix->u.s._24);
2293 temp.u.s._31 = (mat->u.s._11 * pMatrix->u.s._31) + (mat->u.s._21 * pMatrix->u.s._32) + (mat->u.s._31 * pMatrix->u.s._33) + (mat->u.s._41 * pMatrix->u.s._34);
2294 temp.u.s._41 = (mat->u.s._11 * pMatrix->u.s._41) + (mat->u.s._21 * pMatrix->u.s._42) + (mat->u.s._31 * pMatrix->u.s._43) + (mat->u.s._41 * pMatrix->u.s._44);
2296 temp.u.s._12 = (mat->u.s._12 * pMatrix->u.s._11) + (mat->u.s._22 * pMatrix->u.s._12) + (mat->u.s._32 * pMatrix->u.s._13) + (mat->u.s._42 * pMatrix->u.s._14);
2297 temp.u.s._22 = (mat->u.s._12 * pMatrix->u.s._21) + (mat->u.s._22 * pMatrix->u.s._22) + (mat->u.s._32 * pMatrix->u.s._23) + (mat->u.s._42 * pMatrix->u.s._24);
2298 temp.u.s._32 = (mat->u.s._12 * pMatrix->u.s._31) + (mat->u.s._22 * pMatrix->u.s._32) + (mat->u.s._32 * pMatrix->u.s._33) + (mat->u.s._42 * pMatrix->u.s._34);
2299 temp.u.s._42 = (mat->u.s._12 * pMatrix->u.s._41) + (mat->u.s._22 * pMatrix->u.s._42) + (mat->u.s._32 * pMatrix->u.s._43) + (mat->u.s._42 * pMatrix->u.s._44);
2301 temp.u.s._13 = (mat->u.s._13 * pMatrix->u.s._11) + (mat->u.s._23 * pMatrix->u.s._12) + (mat->u.s._33 * pMatrix->u.s._13) + (mat->u.s._43 * pMatrix->u.s._14);
2302 temp.u.s._23 = (mat->u.s._13 * pMatrix->u.s._21) + (mat->u.s._23 * pMatrix->u.s._22) + (mat->u.s._33 * pMatrix->u.s._23) + (mat->u.s._43 * pMatrix->u.s._24);
2303 temp.u.s._33 = (mat->u.s._13 * pMatrix->u.s._31) + (mat->u.s._23 * pMatrix->u.s._32) + (mat->u.s._33 * pMatrix->u.s._33) + (mat->u.s._43 * pMatrix->u.s._34);
2304 temp.u.s._43 = (mat->u.s._13 * pMatrix->u.s._41) + (mat->u.s._23 * pMatrix->u.s._42) + (mat->u.s._33 * pMatrix->u.s._43) + (mat->u.s._43 * pMatrix->u.s._44);
2306 temp.u.s._14 = (mat->u.s._14 * pMatrix->u.s._11) + (mat->u.s._24 * pMatrix->u.s._12) + (mat->u.s._34 * pMatrix->u.s._13) + (mat->u.s._44 * pMatrix->u.s._14);
2307 temp.u.s._24 = (mat->u.s._14 * pMatrix->u.s._21) + (mat->u.s._24 * pMatrix->u.s._22) + (mat->u.s._34 * pMatrix->u.s._23) + (mat->u.s._44 * pMatrix->u.s._24);
2308 temp.u.s._34 = (mat->u.s._14 * pMatrix->u.s._31) + (mat->u.s._24 * pMatrix->u.s._32) + (mat->u.s._34 * pMatrix->u.s._33) + (mat->u.s._44 * pMatrix->u.s._34);
2309 temp.u.s._44 = (mat->u.s._14 * pMatrix->u.s._41) + (mat->u.s._24 * pMatrix->u.s._42) + (mat->u.s._34 * pMatrix->u.s._43) + (mat->u.s._44 * pMatrix->u.s._44);
2311 /* Apply change via set transform - will reapply to eg. lights this way */
2312 IDirect3DDevice8Impl_SetTransform(iface, State, &temp);
2315 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
2316 ICOM_THIS(IDirect3DDevice8Impl,iface);
2318 TRACE("(%p)\n", This);
2319 This->UpdateStateBlock->Changed.viewport = TRUE;
2320 This->UpdateStateBlock->Set.viewport = TRUE;
2321 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
2323 /* Handle recording of state blocks */
2324 if (This->isRecordingState) {
2325 TRACE("Recording... not performing anything\n");
2329 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
2330 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
2332 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
2333 checkGLcall("glDepthRange");
2334 /* Note: GL requires lower left, DirectX supplies upper left */
2335 glViewport(pViewport->X, (This->PresentParms.BackBufferHeight - (pViewport->Y + pViewport->Height)),
2336 pViewport->Width, pViewport->Height);
2337 checkGLcall("glViewport");
2343 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
2344 ICOM_THIS(IDirect3DDevice8Impl,iface);
2345 TRACE("(%p)\n", This);
2346 memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8));
2350 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
2351 ICOM_THIS(IDirect3DDevice8Impl,iface);
2353 This->UpdateStateBlock->Changed.material = TRUE;
2354 This->UpdateStateBlock->Set.material = TRUE;
2355 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
2357 /* Handle recording of state blocks */
2358 if (This->isRecordingState) {
2359 TRACE("Recording... not performing anything\n");
2364 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
2365 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
2366 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
2367 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
2368 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
2370 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&This->UpdateStateBlock->material.Ambient);
2371 checkGLcall("glMaterialfv");
2372 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&This->UpdateStateBlock->material.Diffuse);
2373 checkGLcall("glMaterialfv");
2375 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&This->UpdateStateBlock->material.Specular);
2376 checkGLcall("glMaterialfv");
2377 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&This->UpdateStateBlock->material.Emissive);
2378 checkGLcall("glMaterialfv");
2379 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
2380 checkGLcall("glMaterialf");
2385 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
2386 ICOM_THIS(IDirect3DDevice8Impl,iface);
2387 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
2388 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
2389 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
2390 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
2391 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
2392 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
2396 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST D3DLIGHT8* pLight) {
2397 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
2401 ICOM_THIS(IDirect3DDevice8Impl,iface);
2402 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2404 if (Index > This->maxLights) {
2405 FIXME("Cannot handle more lights than device supports\n");
2406 return D3DERR_INVALIDCALL;
2409 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,
2410 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
2411 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
2412 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
2413 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
2414 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
2415 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
2417 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
2418 This->UpdateStateBlock->Set.lights[Index] = TRUE;
2419 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
2421 /* Handle recording of state blocks */
2422 if (This->isRecordingState) {
2423 TRACE("Recording... not performing anything\n");
2428 colRGBA[0] = pLight->Diffuse.r;
2429 colRGBA[1] = pLight->Diffuse.g;
2430 colRGBA[2] = pLight->Diffuse.b;
2431 colRGBA[3] = pLight->Diffuse.a;
2432 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
2433 checkGLcall("glLightfv");
2436 colRGBA[0] = pLight->Specular.r;
2437 colRGBA[1] = pLight->Specular.g;
2438 colRGBA[2] = pLight->Specular.b;
2439 colRGBA[3] = pLight->Specular.a;
2440 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
2441 checkGLcall("glLightfv");
2444 colRGBA[0] = pLight->Ambient.r;
2445 colRGBA[1] = pLight->Ambient.g;
2446 colRGBA[2] = pLight->Ambient.b;
2447 colRGBA[3] = pLight->Ambient.a;
2448 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
2449 checkGLcall("glLightfv");
2451 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2452 glMatrixMode(GL_MODELVIEW);
2454 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2456 /* Attenuation - Are these right? guessing... */
2457 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
2458 checkGLcall("glLightf");
2459 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
2460 checkGLcall("glLightf");
2462 quad_att = 1.4/(pLight->Range*pLight->Range);
2463 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
2464 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
2465 checkGLcall("glLightf");
2467 switch (pLight->Type) {
2468 case D3DLIGHT_POINT:
2470 This->lightPosn[Index][0] = pLight->Position.x;
2471 This->lightPosn[Index][1] = pLight->Position.y;
2472 This->lightPosn[Index][2] = pLight->Position.z;
2473 This->lightPosn[Index][3] = 1.0;
2474 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2475 checkGLcall("glLightfv");
2477 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
2478 checkGLcall("glLightf");
2485 This->lightPosn[Index][0] = pLight->Position.x;
2486 This->lightPosn[Index][1] = pLight->Position.y;
2487 This->lightPosn[Index][2] = pLight->Position.z;
2488 This->lightPosn[Index][3] = 1.0;
2489 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2490 checkGLcall("glLightfv");
2493 This->lightDirn[Index][0] = pLight->Direction.x;
2494 This->lightDirn[Index][1] = pLight->Direction.y;
2495 This->lightDirn[Index][2] = pLight->Direction.z;
2496 This->lightDirn[Index][3] = 1.0;
2497 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
2498 checkGLcall("glLightfv");
2501 * opengl-ish and d3d-ish spot lights use too different models for the
2502 * light "intensity" as a function of the angle towards the main light direction,
2503 * so we only can approximate very roughly.
2504 * however spot lights are rather rarely used in games (if ever used at all).
2505 * furthermore if still used, probably nobody pays attention to such details.
2507 if (pLight->Falloff == 0) {
2510 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
2512 if (rho < 0.0001) rho = 0.0001f;
2513 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
2514 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
2518 case D3DLIGHT_DIRECTIONAL:
2520 This->lightPosn[Index][0] = -pLight->Direction.x;
2521 This->lightPosn[Index][1] = -pLight->Direction.y;
2522 This->lightPosn[Index][2] = -pLight->Direction.z;
2523 This->lightPosn[Index][3] = 0.0;
2524 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
2525 checkGLcall("glLightfv");
2527 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
2528 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
2533 FIXME("Unrecognized light type %d\n", pLight->Type);
2536 /* Restore the modelview matrix */
2541 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
2542 ICOM_THIS(IDirect3DDevice8Impl,iface);
2543 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2545 if (Index > This->maxLights) {
2546 FIXME("Cannot handle more lights than device supports\n");
2547 return D3DERR_INVALIDCALL;
2550 memcpy(pLight, &This->StateBlock->lights[Index], sizeof(D3DLIGHT8));
2553 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
2554 ICOM_THIS(IDirect3DDevice8Impl,iface);
2555 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
2557 if (Index > This->maxLights) {
2558 FIXME("Cannot handle more lights than device supports\n");
2559 return D3DERR_INVALIDCALL;
2562 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
2563 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
2564 This->UpdateStateBlock->lightEnable[Index] = Enable;
2566 /* Handle recording of state blocks */
2567 if (This->isRecordingState) {
2568 TRACE("Recording... not performing anything\n");
2573 glEnable(GL_LIGHT0+Index);
2574 checkGLcall("glEnable GL_LIGHT0+Index");
2576 glDisable(GL_LIGHT0+Index);
2577 checkGLcall("glDisable GL_LIGHT0+Index");
2581 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
2582 ICOM_THIS(IDirect3DDevice8Impl,iface);
2583 TRACE("(%p) : for idx(%ld)\n", This, Index);
2585 if (Index > This->maxLights) {
2586 FIXME("Cannot handle more lights than device supports\n");
2587 return D3DERR_INVALIDCALL;
2590 *pEnable = This->StateBlock->lightEnable[Index];
2593 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
2594 ICOM_THIS(IDirect3DDevice8Impl,iface);
2595 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
2597 /* Validate Index */
2598 if (Index >= This->clipPlanes ) {
2599 TRACE("Application has requested clipplane this device doesnt support\n");
2600 return D3DERR_INVALIDCALL;
2603 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
2604 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
2605 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
2606 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
2607 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
2608 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
2610 /* Handle recording of state blocks */
2611 if (This->isRecordingState) {
2612 TRACE("Recording... not performing anything\n");
2618 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2619 glMatrixMode(GL_MODELVIEW);
2621 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2623 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
2624 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
2625 glClipPlane(GL_CLIP_PLANE0+Index, This->UpdateStateBlock->clipplane[Index]);
2628 checkGLcall("glClipPlane");
2632 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
2633 ICOM_THIS(IDirect3DDevice8Impl,iface);
2634 TRACE("(%p) : for idx %ld\n", This, Index);
2636 /* Validate Index */
2637 if (Index >= This->clipPlanes ) {
2638 TRACE("Application has requested clipplane this device doesnt support\n");
2639 return D3DERR_INVALIDCALL;
2642 pPlane[0] = This->StateBlock->clipplane[Index][0];
2643 pPlane[1] = This->StateBlock->clipplane[Index][0];
2644 pPlane[2] = This->StateBlock->clipplane[Index][0];
2645 pPlane[3] = This->StateBlock->clipplane[Index][0];
2648 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
2649 ICOM_THIS(IDirect3DDevice8Impl,iface);
2650 DWORD OldValue = This->StateBlock->renderstate[State];
2652 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
2653 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2654 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2655 This->UpdateStateBlock->renderstate[State] = Value;
2657 /* Handle recording of state blocks */
2658 if (This->isRecordingState) {
2659 TRACE("Recording... not performing anything\n");
2664 case D3DRS_FILLMODE :
2665 switch ((D3DFILLMODE) Value) {
2666 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2667 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2668 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2670 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2672 checkGLcall("glPolygonMode (fillmode)");
2675 case D3DRS_LIGHTING :
2677 glEnable(GL_LIGHTING);
2678 checkGLcall("glEnable GL_LIGHTING");
2680 glDisable(GL_LIGHTING);
2681 checkGLcall("glDisable GL_LIGHTING");
2685 case D3DRS_ZENABLE :
2686 switch ((D3DZBUFFERTYPE) Value) {
2688 glDisable(GL_DEPTH_TEST);
2689 checkGLcall("glDisable GL_DEPTH_TEST");
2692 glEnable(GL_DEPTH_TEST);
2693 checkGLcall("glEnable GL_DEPTH_TEST");
2698 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2702 case D3DRS_CULLMODE :
2704 /* If we are culling "back faces with clockwise vertices" then
2705 set front faces to be counter clockwise and enable culling
2707 switch ((D3DCULL) Value) {
2709 glDisable(GL_CULL_FACE);
2710 checkGLcall("glDisable GL_CULL_FACE");
2713 glEnable(GL_CULL_FACE);
2714 checkGLcall("glEnable GL_CULL_FACE");
2715 glFrontFace(GL_CCW);
2716 checkGLcall("glFrontFace GL_CCW");
2717 glCullFace(GL_BACK);
2720 glEnable(GL_CULL_FACE);
2721 checkGLcall("glEnable GL_CULL_FACE");
2723 checkGLcall("glFrontFace GL_CW");
2724 glCullFace(GL_BACK);
2727 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2731 case D3DRS_SHADEMODE :
2732 switch ((D3DSHADEMODE) Value) {
2734 glShadeModel(GL_FLAT);
2735 checkGLcall("glShadeModel");
2737 case D3DSHADE_GOURAUD:
2738 glShadeModel(GL_SMOOTH);
2739 checkGLcall("glShadeModel");
2741 case D3DSHADE_PHONG:
2742 FIXME("D3DSHADE_PHONG isnt supported?\n");
2743 return D3DERR_INVALIDCALL;
2745 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
2749 case D3DRS_DITHERENABLE :
2751 glEnable(GL_DITHER);
2752 checkGLcall("glEnable GL_DITHER");
2754 glDisable(GL_DITHER);
2755 checkGLcall("glDisable GL_DITHER");
2759 case D3DRS_ZWRITEENABLE :
2762 checkGLcall("glDepthMask");
2765 checkGLcall("glDepthMask");
2771 int glParm = GL_LESS;
2773 switch ((D3DCMPFUNC) Value) {
2774 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2775 case D3DCMP_LESS: glParm=GL_LESS; break;
2776 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2777 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2778 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2779 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2780 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2781 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2783 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2785 glDepthFunc(glParm);
2786 checkGLcall("glDepthFunc");
2790 case D3DRS_AMBIENT :
2794 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2795 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2796 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2797 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2798 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0],col[1],col[2],col[3]);
2799 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2800 checkGLcall("glLightModel for MODEL_AMBIENT");
2805 case D3DRS_ALPHABLENDENABLE :
2808 checkGLcall("glEnable GL_BLEND");
2810 glDisable(GL_BLEND);
2811 checkGLcall("glDisable GL_BLEND");
2815 case D3DRS_SRCBLEND :
2816 case D3DRS_DESTBLEND :
2818 int newVal = GL_ZERO;
2820 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2821 case D3DBLEND_ONE : newVal = GL_ONE; break;
2822 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2823 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2824 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2825 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2826 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2827 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2828 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2829 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2830 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2832 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2833 This->srcBlend = newVal;
2834 This->dstBlend = newVal;
2837 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2838 This->srcBlend = newVal;
2839 This->dstBlend = newVal;
2842 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
2845 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
2846 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
2847 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
2848 glBlendFunc(This->srcBlend, This->dstBlend);
2850 checkGLcall("glBlendFunc");
2854 case D3DRS_ALPHATESTENABLE :
2856 glEnable(GL_ALPHA_TEST);
2857 checkGLcall("glEnable GL_ALPHA_TEST");
2859 glDisable(GL_ALPHA_TEST);
2860 checkGLcall("glDisable GL_ALPHA_TEST");
2864 case D3DRS_ALPHAFUNC :
2866 int glParm = GL_LESS;
2869 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
2870 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
2872 switch ((D3DCMPFUNC) Value) {
2873 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2874 case D3DCMP_LESS: glParm=GL_LESS; break;
2875 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2876 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2877 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2878 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2879 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2880 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2882 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2884 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2885 glAlphaFunc(glParm, ref);
2886 checkGLcall("glAlphaFunc");
2890 case D3DRS_ALPHAREF :
2892 int glParm = GL_LESS;
2895 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
2896 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
2898 ref = ((float) Value) / 255.0;
2899 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2900 glAlphaFunc(glParm, ref);
2901 checkGLcall("glAlphaFunc");
2905 case D3DRS_CLIPPLANEENABLE :
2906 case D3DRS_CLIPPING :
2908 /* Ensure we only do the changed clip planes */
2909 DWORD enable = 0xFFFFFFFF;
2910 DWORD disable = 0x00000000;
2912 /* If enabling / disabling all */
2913 if (State == D3DRS_CLIPPING) {
2915 enable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2918 disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2922 enable = Value & ~OldValue;
2923 disable = ~Value & OldValue;
2926 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
2927 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
2928 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
2929 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
2930 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
2931 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
2933 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
2934 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
2935 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
2936 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
2937 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
2938 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
2942 case D3DRS_BLENDOP :
2944 int glParm = GL_FUNC_ADD;
2946 switch ((D3DBLENDOP) Value) {
2947 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
2948 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
2949 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
2950 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
2951 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
2953 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
2955 TRACE("glBlendEquation(%x)\n", glParm);
2956 glBlendEquation(glParm);
2957 checkGLcall("glBlendEquation");
2961 case D3DRS_TEXTUREFACTOR :
2965 /* Note the texture color applies to all textures whereas
2966 GL_TEXTURE_ENV_COLOR applies to active only */
2968 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2969 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
2970 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
2971 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
2973 /* Set the default alpha blend color */
2974 glBlendColor(col[0], col[1], col[2], col[3]);
2975 checkGLcall("glBlendColor");
2977 /* And now the default texture color as well */
2978 for (i = 0; i < This->TextureUnits; i++) {
2980 /* Note the D3DRS value applies to all textures, but GL has one
2981 per texture, so apply it now ready to be used! */
2982 if (This->isMultiTexture) {
2983 #if defined(GL_VERSION_1_3)
2984 glActiveTexture(GL_TEXTURE0 + i);
2986 glActiveTextureARB(GL_TEXTURE0_ARB + i);
2988 checkGLcall("Activate texture.. to update const color");
2990 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2993 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
2994 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2999 case D3DRS_SPECULARENABLE :
3002 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
3003 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
3005 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
3006 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
3011 case D3DRS_STENCILENABLE :
3013 glEnable(GL_STENCIL_TEST);
3014 checkGLcall("glEnable GL_STENCIL_TEST");
3016 glDisable(GL_STENCIL_TEST);
3017 checkGLcall("glDisable GL_STENCIL_TEST");
3021 case D3DRS_STENCILFUNC :
3023 int glParm = GL_ALWAYS;
3025 GLuint mask = 0xFFFFFFFF;
3027 glGetIntegerv(GL_STENCIL_REF, &ref);
3028 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
3029 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
3030 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
3032 switch ((D3DCMPFUNC) Value) {
3033 case D3DCMP_NEVER: glParm=GL_NEVER; break;
3034 case D3DCMP_LESS: glParm=GL_LESS; break;
3035 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
3036 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
3037 case D3DCMP_GREATER: glParm=GL_GREATER; break;
3038 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
3039 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
3040 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
3042 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
3044 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3045 glStencilFunc(glParm, ref, mask);
3046 checkGLcall("glStencilFunc");
3050 case D3DRS_STENCILREF :
3052 int glParm = GL_ALWAYS;
3054 GLuint mask = 0xFFFFFFFF;
3056 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
3057 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
3058 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
3059 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
3062 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3063 glStencilFunc(glParm, ref, mask);
3064 checkGLcall("glStencilFunc");
3068 case D3DRS_STENCILMASK :
3070 int glParm = GL_ALWAYS;
3072 GLuint mask = Value;
3074 glGetIntegerv(GL_STENCIL_REF, &ref);
3075 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
3076 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
3077 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
3079 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3080 glStencilFunc(glParm, ref, mask);
3081 checkGLcall("glStencilFunc");
3085 case D3DRS_STENCILFAIL :
3091 fail = StencilOp(Value);
3092 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
3093 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
3094 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
3095 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
3097 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3098 glStencilOp(fail, zfail, zpass);
3099 checkGLcall("glStencilOp(fail, zfail, zpass);");
3102 case D3DRS_STENCILZFAIL :
3108 glGetIntegerv(GL_STENCIL_FAIL, &fail);
3109 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
3110 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
3111 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
3112 zfail = StencilOp(Value);
3114 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3115 glStencilOp(fail, zfail, zpass);
3116 checkGLcall("glStencilOp(fail, zfail, zpass);");
3119 case D3DRS_STENCILPASS :
3125 glGetIntegerv(GL_STENCIL_FAIL, &fail);
3126 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
3127 zpass = StencilOp(Value);
3128 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
3129 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
3131 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3132 glStencilOp(fail, zfail, zpass);
3133 checkGLcall("glStencilOp(fail, zfail, zpass);");
3137 case D3DRS_STENCILWRITEMASK :
3139 glStencilMask(Value);
3140 TRACE("glStencilMask(%lu)\n", Value);
3141 checkGLcall("glStencilMask");
3145 case D3DRS_FOGENABLE :
3147 if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
3149 checkGLcall("glEnable GL_FOG\n");
3152 checkGLcall("glDisable GL_FOG\n");
3157 case D3DRS_FOGCOLOR :
3160 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3161 col[1] = ((Value >> 8 ) & 0xFF) / 255.0;
3162 col[2] = ((Value >> 0 ) & 0xFF) / 255.0;
3163 col[3] = ((Value >> 24 ) & 0xFF) / 255.0;
3165 /* Set the default alpha blend color */
3166 glFogfv(GL_FOG_COLOR, &col[0]);
3167 checkGLcall("glFog GL_FOG_COLOR");
3171 case D3DRS_FOGSTART :
3173 float *f = (float *)&Value;
3174 glFogfv(GL_FOG_START, f);
3175 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
3176 TRACE("Fog Start == %f\n", *f);
3182 float *f = (float *)&Value;
3183 glFogfv(GL_FOG_END, f);
3184 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
3185 TRACE("Fog End == %f\n", *f);
3189 case D3DRS_FOGDENSITY :
3191 glFogf(GL_FOG_DENSITY, (float) Value);
3192 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
3196 case D3DRS_VERTEXBLEND :
3198 This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
3199 TRACE("Vertex Blending state to %ld\n", Value);
3203 case D3DRS_TWEENFACTOR :
3205 This->UpdateStateBlock->tween_factor = *((float*) &Value);
3206 TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
3210 case D3DRS_INDEXEDVERTEXBLENDENABLE :
3212 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
3217 case D3DRS_COLORVERTEX :
3218 case D3DRS_DIFFUSEMATERIALSOURCE :
3219 case D3DRS_SPECULARMATERIALSOURCE :
3220 case D3DRS_AMBIENTMATERIALSOURCE :
3221 case D3DRS_EMISSIVEMATERIALSOURCE :
3223 GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
3225 if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
3226 glEnable(GL_COLOR_MATERIAL);
3227 checkGLcall("glEnable GL_GL_COLOR_MATERIAL\n");
3229 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
3230 This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
3231 This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
3232 This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE],
3233 This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]);
3235 if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
3236 if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
3237 Parm = GL_AMBIENT_AND_DIFFUSE;
3241 } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
3243 } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
3245 } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
3252 glDisable(GL_COLOR_MATERIAL);
3253 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
3255 TRACE("glColorMaterial Parm=%d\n", Parm);
3256 glColorMaterial(GL_FRONT_AND_BACK, Parm);
3257 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)\n");
3261 glDisable(GL_COLOR_MATERIAL);
3262 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
3267 /* Unhandled yet...! */
3268 case D3DRS_LINEPATTERN :
3269 case D3DRS_LASTPIXEL :
3270 case D3DRS_ZVISIBLE :
3271 case D3DRS_FOGTABLEMODE :
3272 case D3DRS_EDGEANTIALIAS :
3274 case D3DRS_RANGEFOGENABLE :
3283 case D3DRS_FOGVERTEXMODE :
3284 case D3DRS_LOCALVIEWER :
3285 case D3DRS_NORMALIZENORMALS :
3286 case D3DRS_SOFTWAREVERTEXPROCESSING :
3287 case D3DRS_POINTSIZE :
3288 case D3DRS_POINTSIZE_MIN :
3289 case D3DRS_POINTSPRITEENABLE :
3290 case D3DRS_POINTSCALEENABLE :
3291 case D3DRS_POINTSCALE_A :
3292 case D3DRS_POINTSCALE_B :
3293 case D3DRS_POINTSCALE_C :
3294 case D3DRS_MULTISAMPLEANTIALIAS :
3295 case D3DRS_MULTISAMPLEMASK :
3296 case D3DRS_PATCHEDGESTYLE :
3297 case D3DRS_PATCHSEGMENTS :
3298 case D3DRS_DEBUGMONITORTOKEN :
3299 case D3DRS_POINTSIZE_MAX :
3300 case D3DRS_COLORWRITEENABLE :
3301 case D3DRS_POSITIONORDER :
3302 case D3DRS_NORMALORDER :
3303 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
3304 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
3307 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
3312 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
3313 ICOM_THIS(IDirect3DDevice8Impl,iface);
3314 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
3315 *pValue = This->StateBlock->renderstate[State];
3318 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
3319 ICOM_THIS(IDirect3DDevice8Impl,iface);
3321 TRACE("(%p)\n", This);
3323 return IDirect3DDeviceImpl_BeginStateBlock(This);
3325 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
3326 IDirect3DStateBlockImpl* pSB;
3327 ICOM_THIS(IDirect3DDevice8Impl,iface);
3330 TRACE("(%p)\n", This);
3332 res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB);
3333 *pToken = (DWORD) pSB;
3337 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3338 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3339 ICOM_THIS(IDirect3DDevice8Impl,iface);
3341 TRACE("(%p)\n", This);
3343 return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB);
3346 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3347 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3348 ICOM_THIS(IDirect3DDevice8Impl,iface);
3350 TRACE("(%p)\n", This);
3352 return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB);
3354 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3355 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3356 ICOM_THIS(IDirect3DDevice8Impl,iface);
3358 TRACE("(%p)\n", This);
3360 return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB);
3363 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
3364 IDirect3DStateBlockImpl* pSB;
3365 ICOM_THIS(IDirect3DDevice8Impl,iface);
3368 TRACE("(%p) : for type %d\n", This, Type);
3370 res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB);
3371 *pToken = (DWORD) pSB;
3375 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
3376 ICOM_THIS(IDirect3DDevice8Impl,iface);
3377 FIXME("(%p) : stub\n", This); return D3D_OK;
3379 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
3380 ICOM_THIS(IDirect3DDevice8Impl,iface);
3381 FIXME("(%p) : stub\n", This); return D3D_OK;
3383 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
3384 ICOM_THIS(IDirect3DDevice8Impl,iface);
3385 TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage);
3386 *ppTexture = (LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage];
3387 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
3390 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
3392 IDirect3DBaseTexture8 *oldTxt;
3393 BOOL reapplyStates = TRUE;
3395 ICOM_THIS(IDirect3DDevice8Impl,iface);
3396 D3DRESOURCETYPE textureType;
3398 oldTxt = This->UpdateStateBlock->textures[Stage];
3399 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
3401 /* Reject invalid texture units */
3402 if (Stage >= This->TextureUnits) {
3403 TRACE("Attempt to access invalid texture rejected\n");
3404 return D3DERR_INVALIDCALL;
3407 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
3408 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
3409 This->UpdateStateBlock->textures[Stage] = pTexture;
3411 /* Handle recording of state blocks */
3412 if (This->isRecordingState) {
3413 TRACE("Recording... not performing anything\n");
3417 /* Make appropriate texture active */
3418 if (This->isMultiTexture) {
3419 #if defined(GL_VERSION_1_3)
3420 glActiveTexture(GL_TEXTURE0 + Stage);
3422 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3424 checkGLcall("glActiveTextureARB");
3425 } else if (Stage>0) {
3426 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3429 /* Decrement the count of the previous texture */
3430 if (oldTxt != NULL) {
3431 IDirect3DBaseTexture8Impl_Release(oldTxt);
3435 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]);
3437 /* Now setup the texture appropraitly */
3438 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
3440 if (textureType == D3DRTYPE_TEXTURE) {
3441 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl *) pTexture;
3443 if ((void *)oldTxt == (void *)pTexture2 && pTexture2->Dirty == FALSE) {
3444 TRACE("Skipping setting texture as old == new\n");
3445 reapplyStates = FALSE;
3448 /* Standard 2D texture */
3449 TRACE("Standard 2d texture\n");
3450 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D;
3452 /* Load up the texture now */
3453 IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8)pTexture);
3455 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3456 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3459 /* Standard 3D (volume) texture */
3460 TRACE("Standard 3d texture\n");
3461 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
3463 for (i=0; i<pTexture2->levels; i++)
3466 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3467 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3468 checkGLcall("glBindTexture");
3469 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3471 /* No need to walk through all mip-map levels, since already all assigned */
3472 i = pTexture2->levels;
3476 if (pTexture2->volumes[i]->textureName == 0) {
3477 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3478 checkGLcall("glGenTextures");
3479 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3482 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3483 checkGLcall("glBindTexture");
3485 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3486 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3489 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3490 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3491 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3492 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3493 pTexture2->volumes[i]->allocatedMemory);
3494 glTexImage3D(GL_TEXTURE_3D, i,
3495 fmt2glintFmt(pTexture2->format),
3496 pTexture2->volumes[i]->myDesc.Width,
3497 pTexture2->volumes[i]->myDesc.Height,
3498 pTexture2->volumes[i]->myDesc.Depth,
3500 fmt2glFmt(pTexture2->format),
3501 fmt2glType(pTexture2->format),
3502 pTexture2->volumes[i]->allocatedMemory
3504 checkGLcall("glTexImage3D");
3506 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3507 pTexture2->Dirty = FALSE;
3512 FIXME("(%p) : Incorrect type for a texture : %d\n", This, textureType);
3515 TRACE("Setting to no texture (ie default texture)\n");
3516 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D;
3517 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3518 checkGLcall("glBindTexture");
3519 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3522 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3523 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3524 if (reapplyStates) {
3525 setupTextureStates (iface, Stage);
3531 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3532 ICOM_THIS(IDirect3DDevice8Impl,iface);
3533 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
3534 *pValue = This->UpdateStateBlock->texture_state[Stage][Type];
3538 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
3539 ICOM_THIS(IDirect3DDevice8Impl,iface);
3541 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3543 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value);
3545 /* Reject invalid texture units */
3546 if (Stage >= This->TextureUnits) {
3547 TRACE("Attempt to access invalid texture rejected\n");
3548 return D3DERR_INVALIDCALL;
3551 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3552 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3553 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3555 /* Handle recording of state blocks */
3556 if (This->isRecordingState) {
3557 TRACE("Recording... not performing anything\n");
3561 /* Make appropriate texture active */
3562 VTRACE(("Activating appropriate texture state %ld\n", Stage));
3563 if (This->isMultiTexture) {
3564 #if defined(GL_VERSION_1_3)
3565 glActiveTexture(GL_TEXTURE0 + Stage);
3566 vcheckGLcall("glActiveTexture");
3568 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3569 vcheckGLcall("glActiveTextureARB");
3571 } else if (Stage > 0) {
3572 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3577 case D3DTSS_MINFILTER :
3578 case D3DTSS_MIPFILTER :
3580 DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER];
3581 DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER];
3582 GLint realVal = GL_LINEAR;
3584 if (ValueMIN == D3DTEXF_POINT) {
3586 if (ValueMIP == D3DTEXF_POINT) {
3587 realVal = GL_NEAREST_MIPMAP_NEAREST;
3588 } else if (ValueMIP == D3DTEXF_LINEAR) {
3589 realVal = GL_NEAREST_MIPMAP_LINEAR;
3590 } else if (ValueMIP == D3DTEXF_NONE) {
3591 realVal = GL_NEAREST;
3593 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3594 realVal = GL_NEAREST_MIPMAP_LINEAR;
3596 } else if (ValueMIN == D3DTEXF_LINEAR) {
3598 if (ValueMIP == D3DTEXF_POINT) {
3599 realVal = GL_LINEAR_MIPMAP_NEAREST;
3600 } else if (ValueMIP == D3DTEXF_LINEAR) {
3601 realVal = GL_LINEAR_MIPMAP_LINEAR;
3602 } else if (ValueMIP == D3DTEXF_NONE) {
3603 realVal = GL_LINEAR;
3605 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3606 realVal = GL_LINEAR_MIPMAP_LINEAR;
3608 } else if (ValueMIN == D3DTEXF_NONE) {
3609 /* Doesnt really make sense - Windows just seems to disable
3610 mipmapping when this occurs */
3611 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3612 realVal = GL_LINEAR;
3615 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3616 realVal = GL_LINEAR_MIPMAP_LINEAR;
3619 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3620 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3621 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3626 case D3DTSS_MAGFILTER :
3627 if (Value == D3DTEXF_POINT) {
3628 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3629 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3630 } else if (Value == D3DTEXF_LINEAR) {
3631 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3632 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3634 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3638 case D3DTSS_COLORARG0 :
3639 case D3DTSS_ALPHAARG0 :
3640 /* FIXME: Mesa seems to struggle setting these at the moment */
3641 /*FIXME("COLORARG0/ALPHAARG0 support still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);*/
3644 case D3DTSS_COLORARG1 :
3645 case D3DTSS_COLORARG2 :
3646 case D3DTSS_ALPHAARG1 :
3647 case D3DTSS_ALPHAARG2 :
3649 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3650 int operand = GL_SRC_COLOR;
3651 int source = GL_TEXTURE;
3653 GetSrcAndOpFromValue(Value, isAlphaArg, &source, &operand);
3655 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3656 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3657 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3658 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3659 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3661 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3662 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3663 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3664 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3665 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3670 case D3DTSS_ALPHAOP :
3671 case D3DTSS_COLOROP :
3675 int Parm = (Type == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3677 if (Type == D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3678 /* TODO: Disable by making this and all later levels disabled */
3679 glDisable(GL_TEXTURE_1D);
3680 checkGLcall("Disable GL_TEXTURE_1D");
3681 glDisable(GL_TEXTURE_2D);
3682 checkGLcall("Disable GL_TEXTURE_2D");
3683 glDisable(GL_TEXTURE_3D);
3684 checkGLcall("Disable GL_TEXTURE_3D");
3687 /* Enable only the appropriate texture dimension */
3688 if (Type == D3DTSS_COLOROP) {
3689 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
3690 glEnable(GL_TEXTURE_1D);
3691 checkGLcall("Enable GL_TEXTURE_1D");
3693 glDisable(GL_TEXTURE_1D);
3694 checkGLcall("Disable GL_TEXTURE_1D");
3696 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
3697 glEnable(GL_TEXTURE_2D);
3698 checkGLcall("Enable GL_TEXTURE_2D");
3700 glDisable(GL_TEXTURE_2D);
3701 checkGLcall("Disable GL_TEXTURE_2D");
3703 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
3704 glEnable(GL_TEXTURE_3D);
3705 checkGLcall("Enable GL_TEXTURE_3D");
3707 glDisable(GL_TEXTURE_3D);
3708 checkGLcall("Disable GL_TEXTURE_3D");
3712 /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
3713 if (Value != D3DTOP_DISABLE) {
3714 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
3717 /* Now set up the operand correctly */
3719 case D3DTOP_DISABLE :
3720 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3721 and it works, so ignore this op */
3722 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3725 case D3DTOP_SELECTARG1 :
3727 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3728 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3729 #if 0 /* don't seem to do anything */
3730 BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP);
3734 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1];
3735 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
3737 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_ALPHA_EXT, source, GL_OPERAND0_ALPHA_EXT, operand);
3738 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, source);
3739 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 'source')");
3740 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operand);
3741 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 'operand')");
3743 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_RGB_EXT, source, GL_OPERAND0_RGB_EXT, operand);
3744 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, source);
3745 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')");
3746 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operand);
3747 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 'operand')");
3749 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2];
3750 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
3752 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_ALPHA_EXT, source, GL_OPERAND1_ALPHA_EXT, operand);
3753 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, source);
3754 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 'source')");
3755 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operand);
3756 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 'operand')");
3758 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_RGB_EXT, source, GL_OPERAND1_RGB_EXT, operand);
3759 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, source);
3760 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 'source')");
3761 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operand);
3762 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 'operand')");
3768 case D3DTOP_SELECTARG2 :
3770 BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP);
3774 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3775 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3776 /* GL_REPLACE, swap args 0 and 1? */
3777 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2];
3778 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
3780 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_ALPHA_EXT, source, GL_OPERAND0_ALPHA_EXT, operand);
3781 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, source);
3782 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 'source')");
3783 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operand);
3784 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 'operand')");
3786 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_RGB_EXT, source, GL_OPERAND0_RGB_EXT, operand);
3787 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, source);
3788 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')");
3789 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operand);
3790 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 'operand')");
3792 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1];
3793 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
3795 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_ALPHA_EXT, source, GL_OPERAND1_ALPHA_EXT, operand);
3796 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, source);
3797 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 'source')");
3798 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operand);
3799 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 'operand')");
3801 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_RGB_EXT, source, GL_OPERAND1_RGB_EXT, operand);
3802 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, source);
3803 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 'source')");
3804 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operand);
3805 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 'operand')");
3810 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3811 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3812 case D3DTOP_MODULATE :
3815 if (Type == D3DTSS_ALPHAOP) {
3816 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3817 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3819 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3820 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3822 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3823 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3827 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3828 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3831 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3832 case D3DTOP_ADDSIGNED :
3833 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3834 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3837 case D3DTOP_DOTPRODUCT3 :
3838 #if defined(GL_VERSION_1_3)
3840 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3841 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3845 FIXME("DotProduct3 extension requested but not supported via this version of opengl\n");
3848 case D3DTOP_SUBTRACT :
3849 #if defined(GL_VERSION_1_3)
3850 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT);
3851 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT)");
3856 * if ARB_texture_env_combine is supported
3857 * we can use GL_SUBTRACT_ARB here
3860 case D3DTOP_ADDSMOOTH :
3861 case D3DTOP_BLENDDIFFUSEALPHA :
3862 case D3DTOP_BLENDTEXTUREALPHA :
3863 case D3DTOP_BLENDFACTORALPHA :
3864 case D3DTOP_BLENDTEXTUREALPHAPM :
3865 case D3DTOP_BLENDCURRENTALPHA :
3866 case D3DTOP_PREMODULATE :
3867 case D3DTOP_MODULATEALPHA_ADDCOLOR :
3868 case D3DTOP_MODULATECOLOR_ADDALPHA :
3869 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
3870 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
3871 case D3DTOP_BUMPENVMAP :
3872 case D3DTOP_BUMPENVMAPLUMINANCE :
3873 case D3DTOP_MULTIPLYADD :
3876 FIXME("Unhandled texture operation %ld\n", Value);
3882 case D3DTSS_ADDRESSU :
3883 case D3DTSS_ADDRESSV :
3884 case D3DTSS_ADDRESSW :
3886 GLint wrapParm = GL_REPEAT;
3888 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3889 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break;
3890 case D3DTADDRESS_BORDER: wrapParm = GL_REPEAT; break; /* FIXME: Not right, but better */
3891 #if defined(GL_VERSION_1_4)
3892 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT; break;
3893 #elif defined(GL_ARB_texture_mirrored_repeat)
3894 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT_ARB; break;
3896 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL pre-1.4 */
3898 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL */
3900 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3901 wrapParm = GL_REPEAT;
3905 case D3DTSS_ADDRESSU:
3906 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3907 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3908 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3910 case D3DTSS_ADDRESSV:
3911 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3912 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3913 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3915 case D3DTSS_ADDRESSW:
3916 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3917 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3918 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3921 break; /** stupic compilator */
3926 case D3DTSS_BORDERCOLOR :
3929 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3930 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3931 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3932 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3934 TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value);
3935 glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3936 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3940 case D3DTSS_TEXCOORDINDEX :
3942 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
3945 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
3947 switch (Value & 0xFFFFFF00) {
3948 case D3DTSS_TCI_PASSTHRU:
3949 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
3952 case D3DTSS_TCI_CAMERASPACEPOSITION:
3953 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3954 as the input texture coordinates for this stage's texture transformation. This
3955 equates roughly to EYE_LINEAR */
3957 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
3958 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
3959 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
3960 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
3961 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3963 glMatrixMode(GL_MODELVIEW);
3966 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3967 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3968 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3969 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3972 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
3973 glEnable(GL_TEXTURE_GEN_S);
3974 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3975 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3976 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3977 glEnable(GL_TEXTURE_GEN_T);
3978 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3979 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3980 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3981 glEnable(GL_TEXTURE_GEN_R);
3982 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3983 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3984 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3990 /* ? disable GL_TEXTURE_GEN_n ? */
3991 FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value);
3998 case D3DTSS_BUMPENVMAT00 :
3999 case D3DTSS_BUMPENVMAT01 :
4000 TRACE("BUMPENVMAT0%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT00, Stage, Type, Value);
4002 case D3DTSS_BUMPENVMAT10 :
4003 case D3DTSS_BUMPENVMAT11 :
4004 TRACE("BUMPENVMAT1%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT10, Stage, Type, Value);
4007 case D3DTSS_MIPMAPLODBIAS :
4008 case D3DTSS_MAXMIPLEVEL :
4009 case D3DTSS_MAXANISOTROPY :
4010 case D3DTSS_BUMPENVLSCALE :
4011 case D3DTSS_BUMPENVLOFFSET :
4012 case D3DTSS_TEXTURETRANSFORMFLAGS :
4013 case D3DTSS_RESULTARG :
4015 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
4016 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
4020 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
4021 ICOM_THIS(IDirect3DDevice8Impl,iface);
4022 TRACE("(%p) : stub\n", This); /* FIXME: Needs doing, but called often and is harmless */
4025 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
4026 ICOM_THIS(IDirect3DDevice8Impl,iface);
4027 FIXME("(%p) : stub\n", This); return D3D_OK;
4029 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
4030 ICOM_THIS(IDirect3DDevice8Impl,iface);
4031 FIXME("(%p) : stub\n", This); return D3D_OK;
4033 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
4034 ICOM_THIS(IDirect3DDevice8Impl,iface);
4035 FIXME("(%p) : stub\n", This); return D3D_OK;
4037 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
4038 ICOM_THIS(IDirect3DDevice8Impl,iface);
4039 FIXME("(%p) : stub\n", This); return D3D_OK;
4041 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
4042 ICOM_THIS(IDirect3DDevice8Impl,iface);
4043 FIXME("(%p) : stub\n", This); return D3D_OK;
4045 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
4047 IDirect3DVertexBuffer8 *pVB;
4049 ICOM_THIS(IDirect3DDevice8Impl,iface);
4050 pVB = This->StateBlock->stream_source[0];
4052 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
4054 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
4055 This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
4059 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
4060 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
4062 IDirect3DIndexBuffer8 *pIB;
4063 IDirect3DVertexBuffer8 *pVB;
4064 D3DINDEXBUFFER_DESC IdxBufDsc;
4066 ICOM_THIS(IDirect3DDevice8Impl,iface);
4067 pIB = This->StateBlock->pIndexData;
4068 pVB = This->StateBlock->stream_source[0];
4070 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
4071 minIndex, NumVertices, startIndex, primCount);
4073 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
4074 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
4080 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
4081 This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
4086 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
4087 ICOM_THIS(IDirect3DDevice8Impl,iface);
4089 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
4091 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
4093 This->StateBlock->stream_source[0] = NULL;
4094 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
4095 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock->VertexShader, pVertexStreamZeroData,
4097 This->StateBlock->stream_stride[0] = 0;
4099 /*stream zero settings set to null at end */
4102 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
4103 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
4104 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
4105 UINT VertexStreamZeroStride) {
4107 ICOM_THIS(IDirect3DDevice8Impl,iface);
4108 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
4109 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
4111 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
4112 if (IndexDataFormat == D3DFMT_INDEX16) {
4118 This->StateBlock->stream_source[0] = NULL;
4119 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
4120 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock->VertexShader, pVertexStreamZeroData,
4121 This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
4123 /*stream zero settings set to null at end */
4124 This->StateBlock->stream_stride[0] = 0;
4125 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
4129 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
4130 ICOM_THIS(IDirect3DDevice8Impl,iface);
4131 FIXME("(%p) : stub\n", This); return D3D_OK;
4133 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
4134 ICOM_THIS(IDirect3DDevice8Impl,iface);
4135 IDirect3DVertexShaderImpl* object;
4136 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4140 TRACE("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
4141 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
4142 return D3DERR_INVALIDCALL;
4144 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
4145 if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
4146 return D3DERR_OUTOFVIDEOMEMORY;
4149 /** Create the Vertex Shader */
4150 res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
4151 /** TODO: check FAILED(res) */
4153 /** Create and Bind the Vertex Shader Declaration */
4154 res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
4155 /** TODO: check FAILED(res) */
4157 VertexShaders[i] = object;
4158 VertexShaderDeclarations[i] = attached_decl;
4159 *pHandle = VS_HIGHESTFIXEDFXF + i;
4163 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4164 ICOM_THIS(IDirect3DDevice8Impl,iface);
4166 This->UpdateStateBlock->VertexShader = Handle;
4167 This->UpdateStateBlock->Changed.vertexShader = TRUE;
4168 This->UpdateStateBlock->Set.vertexShader = TRUE;
4170 if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
4171 FIXME("(%p) : Created shader, Handle=%lx\n", This, Handle);
4172 This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
4173 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
4174 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
4175 } else { /* use a fvf, so desactivate the vshader decl */
4176 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
4177 This->UpdateStateBlock->vertexShaderDecl = NULL;
4178 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
4179 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
4181 /* Handle recording of state blocks */
4182 if (This->isRecordingState) {
4183 TRACE("Recording... not performing anything\n");
4187 * TODO: merge HAL shaders context switching from prototype
4191 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4192 ICOM_THIS(IDirect3DDevice8Impl,iface);
4193 TRACE("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
4194 *pHandle = This->StateBlock->VertexShader;
4198 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4199 ICOM_THIS(IDirect3DDevice8Impl,iface);
4200 IDirect3DVertexShaderImpl* object;
4201 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4203 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4204 return D3DERR_INVALIDCALL;
4208 * Delete Vertex Shader
4210 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
4211 if (NULL == object) {
4212 return D3DERR_INVALIDCALL;
4214 FIXME("(%p) : freing VertexShader %p\n", This, object);
4215 /* TODO: check validity of object */
4216 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
4217 HeapFree(GetProcessHeap(), 0, (void *)object->data);
4218 HeapFree(GetProcessHeap(), 0, (void *)object);
4219 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
4222 * Delete Vertex Shader Declaration
4224 attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
4225 if (NULL == attached_decl) {
4226 return D3DERR_INVALIDCALL;
4228 FIXME("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
4229 /* TODO: check validity of object */
4230 HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
4231 HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
4232 VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
4237 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
4238 ICOM_THIS(IDirect3DDevice8Impl,iface);
4240 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
4241 ERR("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);
4242 return D3DERR_INVALIDCALL;
4244 if (NULL == pConstantData) {
4245 return D3DERR_INVALIDCALL;
4247 if (ConstantCount > 1) {
4248 FLOAT* f = (FLOAT*)pConstantData;
4250 TRACE("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
4251 for (i = 0; i < ConstantCount; ++i) {
4252 TRACE("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
4256 FLOAT* f = (FLOAT*)pConstantData;
4257 TRACE("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
4259 This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
4260 memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
4263 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
4264 ICOM_THIS(IDirect3DDevice8Impl,iface);
4266 TRACE("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
4267 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
4268 return D3DERR_INVALIDCALL;
4270 if (NULL == pConstantData) {
4271 return D3DERR_INVALIDCALL;
4273 memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
4276 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4277 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
4278 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4280 attached_decl = VERTEX_SHADER_DECL(Handle);
4281 if (NULL == attached_decl) {
4282 return D3DERR_INVALIDCALL;
4284 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
4286 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4287 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
4288 IDirect3DVertexShaderImpl* object;
4290 object = VERTEX_SHADER(Handle);
4291 if (NULL == object) {
4292 return D3DERR_INVALIDCALL;
4294 return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
4297 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
4298 ICOM_THIS(IDirect3DDevice8Impl,iface);
4299 IDirect3DIndexBuffer8 *oldIdxs;
4301 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
4302 oldIdxs = This->StateBlock->pIndexData;
4304 This->UpdateStateBlock->Changed.Indices = TRUE;
4305 This->UpdateStateBlock->Set.Indices = TRUE;
4306 This->UpdateStateBlock->pIndexData = pIndexData;
4307 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
4309 /* Handle recording of state blocks */
4310 if (This->isRecordingState) {
4311 TRACE("Recording... not performing anything\n");
4315 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
4316 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
4319 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
4320 ICOM_THIS(IDirect3DDevice8Impl,iface);
4321 FIXME("(%p) : stub\n", This);
4323 *ppIndexData = This->StateBlock->pIndexData;
4324 /* up ref count on ppindexdata */
4325 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
4326 *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
4330 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
4331 ICOM_THIS(IDirect3DDevice8Impl,iface);
4332 IDirect3DPixelShaderImpl* object;
4335 FIXME("(%p) : PixelShader not fully supported yet\n", This);
4336 if (NULL == pFunction || NULL == pHandle) {
4337 return D3DERR_INVALIDCALL;
4339 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
4340 if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
4341 return D3DERR_OUTOFVIDEOMEMORY;
4343 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
4344 if (NULL == object) {
4345 return D3DERR_OUTOFVIDEOMEMORY;
4348 object->data = NULL; /* TODO */
4350 PixelShaders[i] = object;
4351 *pHandle = VS_HIGHESTFIXEDFXF + i;
4353 object->function = pFunction;
4354 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
4355 object->functionLength = i + 1;
4359 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4360 ICOM_THIS(IDirect3DDevice8Impl,iface);
4362 This->UpdateStateBlock->PixelShader = Handle;
4363 This->UpdateStateBlock->Changed.pixelShader = TRUE;
4364 This->UpdateStateBlock->Set.pixelShader = TRUE;
4366 /* Handle recording of state blocks */
4367 if (This->isRecordingState) {
4368 TRACE("Recording... not performing anything\n");
4372 /* FIXME: Quieten when not being used */
4374 FIXME("(%p) : stub %ld\n", This, Handle);
4376 TRACE("(%p) : stub %ld\n", This, Handle);
4381 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4382 ICOM_THIS(IDirect3DDevice8Impl,iface);
4383 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
4384 *pHandle = This->StateBlock->PixelShader;
4388 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4389 ICOM_THIS(IDirect3DDevice8Impl,iface);
4390 IDirect3DPixelShaderImpl* object;
4392 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4393 return D3DERR_INVALIDCALL;
4395 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
4396 TRACE("(%p) : freeing PixelShader %p\n", This, object);
4397 /* TODO: check validity of object before free */
4398 HeapFree(GetProcessHeap(), 0, (void *)object);
4399 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
4403 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
4404 ICOM_THIS(IDirect3DDevice8Impl,iface);
4405 FIXME("(%p) : stub\n", This);
4408 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
4409 ICOM_THIS(IDirect3DDevice8Impl,iface);
4410 FIXME("(%p) : stub\n", This);
4413 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4414 ICOM_THIS(IDirect3DDevice8Impl,iface);
4415 IDirect3DPixelShaderImpl* object;
4417 object = PIXEL_SHADER(Handle);
4418 if (NULL == object) {
4419 return D3DERR_INVALIDCALL;
4421 if (NULL == pData) {
4422 *pSizeOfData = object->functionLength;
4425 if (*pSizeOfData < object->functionLength) {
4426 *pSizeOfData = object->functionLength;
4427 return D3DERR_MOREDATA;
4429 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
4430 memcpy(pData, object->function, object->functionLength);
4433 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
4434 ICOM_THIS(IDirect3DDevice8Impl,iface);
4435 FIXME("(%p) : stub\n", This); return D3D_OK;
4437 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
4438 ICOM_THIS(IDirect3DDevice8Impl,iface);
4439 FIXME("(%p) : stub\n", This); return D3D_OK;
4441 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
4442 ICOM_THIS(IDirect3DDevice8Impl,iface);
4443 FIXME("(%p) : stub\n", This); return D3D_OK;
4446 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
4447 IDirect3DVertexBuffer8 *oldSrc;
4448 ICOM_THIS(IDirect3DDevice8Impl,iface);
4450 oldSrc = This->StateBlock->stream_source[StreamNumber];
4451 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
4453 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
4454 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
4455 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
4456 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
4458 /* Handle recording of state blocks */
4459 if (This->isRecordingState) {
4460 TRACE("Recording... not performing anything\n");
4464 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
4465 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
4468 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
4469 ICOM_THIS(IDirect3DDevice8Impl,iface);
4470 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
4471 *pStream = This->StateBlock->stream_source[StreamNumber];
4472 *pStride = This->StateBlock->stream_stride[StreamNumber];
4473 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
4478 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
4480 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4481 IDirect3DDevice8Impl_QueryInterface,
4482 IDirect3DDevice8Impl_AddRef,
4483 IDirect3DDevice8Impl_Release,
4484 IDirect3DDevice8Impl_TestCooperativeLevel,
4485 IDirect3DDevice8Impl_GetAvailableTextureMem,
4486 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
4487 IDirect3DDevice8Impl_GetDirect3D,
4488 IDirect3DDevice8Impl_GetDeviceCaps,
4489 IDirect3DDevice8Impl_GetDisplayMode,
4490 IDirect3DDevice8Impl_GetCreationParameters,
4491 IDirect3DDevice8Impl_SetCursorProperties,
4492 IDirect3DDevice8Impl_SetCursorPosition,
4493 IDirect3DDevice8Impl_ShowCursor,
4494 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
4495 IDirect3DDevice8Impl_Reset,
4496 IDirect3DDevice8Impl_Present,
4497 IDirect3DDevice8Impl_GetBackBuffer,
4498 IDirect3DDevice8Impl_GetRasterStatus,
4499 IDirect3DDevice8Impl_SetGammaRamp,
4500 IDirect3DDevice8Impl_GetGammaRamp,
4501 IDirect3DDevice8Impl_CreateTexture,
4502 IDirect3DDevice8Impl_CreateVolumeTexture,
4503 IDirect3DDevice8Impl_CreateCubeTexture,
4504 IDirect3DDevice8Impl_CreateVertexBuffer,
4505 IDirect3DDevice8Impl_CreateIndexBuffer,
4506 IDirect3DDevice8Impl_CreateRenderTarget,
4507 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4508 IDirect3DDevice8Impl_CreateImageSurface,
4509 IDirect3DDevice8Impl_CopyRects,
4510 IDirect3DDevice8Impl_UpdateTexture,
4511 IDirect3DDevice8Impl_GetFrontBuffer,
4512 IDirect3DDevice8Impl_SetRenderTarget,
4513 IDirect3DDevice8Impl_GetRenderTarget,
4514 IDirect3DDevice8Impl_GetDepthStencilSurface,
4515 IDirect3DDevice8Impl_BeginScene,
4516 IDirect3DDevice8Impl_EndScene,
4517 IDirect3DDevice8Impl_Clear,
4518 IDirect3DDevice8Impl_SetTransform,
4519 IDirect3DDevice8Impl_GetTransform,
4520 IDirect3DDevice8Impl_MultiplyTransform,
4521 IDirect3DDevice8Impl_SetViewport,
4522 IDirect3DDevice8Impl_GetViewport,
4523 IDirect3DDevice8Impl_SetMaterial,
4524 IDirect3DDevice8Impl_GetMaterial,
4525 IDirect3DDevice8Impl_SetLight,
4526 IDirect3DDevice8Impl_GetLight,
4527 IDirect3DDevice8Impl_LightEnable,
4528 IDirect3DDevice8Impl_GetLightEnable,
4529 IDirect3DDevice8Impl_SetClipPlane,
4530 IDirect3DDevice8Impl_GetClipPlane,
4531 IDirect3DDevice8Impl_SetRenderState,
4532 IDirect3DDevice8Impl_GetRenderState,
4533 IDirect3DDevice8Impl_BeginStateBlock,
4534 IDirect3DDevice8Impl_EndStateBlock,
4535 IDirect3DDevice8Impl_ApplyStateBlock,
4536 IDirect3DDevice8Impl_CaptureStateBlock,
4537 IDirect3DDevice8Impl_DeleteStateBlock,
4538 IDirect3DDevice8Impl_CreateStateBlock,
4539 IDirect3DDevice8Impl_SetClipStatus,
4540 IDirect3DDevice8Impl_GetClipStatus,
4541 IDirect3DDevice8Impl_GetTexture,
4542 IDirect3DDevice8Impl_SetTexture,
4543 IDirect3DDevice8Impl_GetTextureStageState,
4544 IDirect3DDevice8Impl_SetTextureStageState,
4545 IDirect3DDevice8Impl_ValidateDevice,
4546 IDirect3DDevice8Impl_GetInfo,
4547 IDirect3DDevice8Impl_SetPaletteEntries,
4548 IDirect3DDevice8Impl_GetPaletteEntries,
4549 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4550 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4551 IDirect3DDevice8Impl_DrawPrimitive,
4552 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4553 IDirect3DDevice8Impl_DrawPrimitiveUP,
4554 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4555 IDirect3DDevice8Impl_ProcessVertices,
4556 IDirect3DDevice8Impl_CreateVertexShader,
4557 IDirect3DDevice8Impl_SetVertexShader,
4558 IDirect3DDevice8Impl_GetVertexShader,
4559 IDirect3DDevice8Impl_DeleteVertexShader,
4560 IDirect3DDevice8Impl_SetVertexShaderConstant,
4561 IDirect3DDevice8Impl_GetVertexShaderConstant,
4562 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4563 IDirect3DDevice8Impl_GetVertexShaderFunction,
4564 IDirect3DDevice8Impl_SetStreamSource,
4565 IDirect3DDevice8Impl_GetStreamSource,
4566 IDirect3DDevice8Impl_SetIndices,
4567 IDirect3DDevice8Impl_GetIndices,
4568 IDirect3DDevice8Impl_CreatePixelShader,
4569 IDirect3DDevice8Impl_SetPixelShader,
4570 IDirect3DDevice8Impl_GetPixelShader,
4571 IDirect3DDevice8Impl_DeletePixelShader,
4572 IDirect3DDevice8Impl_SetPixelShaderConstant,
4573 IDirect3DDevice8Impl_GetPixelShaderConstant,
4574 IDirect3DDevice8Impl_GetPixelShaderFunction,
4575 IDirect3DDevice8Impl_DrawRectPatch,
4576 IDirect3DDevice8Impl_DrawTriPatch,
4577 IDirect3DDevice8Impl_DeletePatch