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);
41 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
43 /* Some #defines for additional diagnostics */
45 /* Per-vertex trace: */
47 # define VTRACE(A) TRACE A
53 static IDirect3DVertexShaderImpl* VertexShaders[64];
54 static IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
55 static IDirect3DPixelShaderImpl* PixelShaders[64];
57 /* CreateVertexShader can return > 0xFFFF */
58 #define VS_HIGHESTFIXEDFXF 0xF0000000
61 * Utility functions or macros
63 #define conv_mat(mat,gl_mat) \
65 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
66 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
67 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
68 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
69 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
72 #define VERTEX_SHADER(Handle) \
73 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
74 #define VERTEX_SHADER_DECL(Handle) \
75 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaderDeclarations) / sizeof(IDirect3DVertexShaderDeclarationImpl*)) ? NULL : VertexShaderDeclarations[Handle]) : VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF])
76 #define PIXEL_SHADER(Handle) \
77 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
79 #define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
81 const char* debug_d3ddevicetype(D3DDEVTYPE devtype) {
83 #define DEVTYPE_TO_STR(dev) case dev: return #dev
84 DEVTYPE_TO_STR(D3DDEVTYPE_HAL);
85 DEVTYPE_TO_STR(D3DDEVTYPE_REF);
86 DEVTYPE_TO_STR(D3DDEVTYPE_SW);
89 FIXME("Unrecognized %u D3DDEVTYPE!\n", devtype);
90 return "unrecognized";
94 const char* debug_d3dusage(DWORD usage) {
96 #define D3DUSAGE_TO_STR(u) case u: return #u
97 D3DUSAGE_TO_STR(D3DUSAGE_RENDERTARGET);
98 D3DUSAGE_TO_STR(D3DUSAGE_DEPTHSTENCIL);
99 D3DUSAGE_TO_STR(D3DUSAGE_WRITEONLY);
100 D3DUSAGE_TO_STR(D3DUSAGE_SOFTWAREPROCESSING);
101 D3DUSAGE_TO_STR(D3DUSAGE_DONOTCLIP);
102 D3DUSAGE_TO_STR(D3DUSAGE_POINTS);
103 D3DUSAGE_TO_STR(D3DUSAGE_RTPATCHES);
104 D3DUSAGE_TO_STR(D3DUSAGE_NPATCHES);
105 D3DUSAGE_TO_STR(D3DUSAGE_DYNAMIC);
106 #undef D3DUSAGE_TO_STR
107 case 0: return "none";
109 FIXME("Unrecognized %lu Usage!\n", usage);
110 return "unrecognized";
114 const char* debug_d3dformat(D3DFORMAT fmt) {
116 #define FMT_TO_STR(fmt) case fmt: return #fmt
117 FMT_TO_STR(D3DFMT_UNKNOWN);
118 FMT_TO_STR(D3DFMT_R8G8B8);
119 FMT_TO_STR(D3DFMT_A8R8G8B8);
120 FMT_TO_STR(D3DFMT_X8R8G8B8);
121 FMT_TO_STR(D3DFMT_R5G6B5);
122 FMT_TO_STR(D3DFMT_X1R5G5B5);
123 FMT_TO_STR(D3DFMT_A1R5G5B5);
124 FMT_TO_STR(D3DFMT_A4R4G4B4);
125 FMT_TO_STR(D3DFMT_R3G3B2);
126 FMT_TO_STR(D3DFMT_A8);
127 FMT_TO_STR(D3DFMT_A8R3G3B2);
128 FMT_TO_STR(D3DFMT_X4R4G4B4);
129 FMT_TO_STR(D3DFMT_A8P8);
130 FMT_TO_STR(D3DFMT_P8);
131 FMT_TO_STR(D3DFMT_L8);
132 FMT_TO_STR(D3DFMT_A8L8);
133 FMT_TO_STR(D3DFMT_A4L4);
134 FMT_TO_STR(D3DFMT_V8U8);
135 FMT_TO_STR(D3DFMT_L6V5U5);
136 FMT_TO_STR(D3DFMT_X8L8V8U8);
137 FMT_TO_STR(D3DFMT_Q8W8V8U8);
138 FMT_TO_STR(D3DFMT_V16U16);
139 FMT_TO_STR(D3DFMT_W11V11U10);
140 FMT_TO_STR(D3DFMT_UYVY);
141 FMT_TO_STR(D3DFMT_YUY2);
142 FMT_TO_STR(D3DFMT_DXT1);
143 FMT_TO_STR(D3DFMT_DXT2);
144 FMT_TO_STR(D3DFMT_DXT3);
145 FMT_TO_STR(D3DFMT_DXT4);
146 FMT_TO_STR(D3DFMT_DXT5);
147 FMT_TO_STR(D3DFMT_D16_LOCKABLE);
148 FMT_TO_STR(D3DFMT_D32);
149 FMT_TO_STR(D3DFMT_D15S1);
150 FMT_TO_STR(D3DFMT_D24S8);
151 FMT_TO_STR(D3DFMT_D16);
152 FMT_TO_STR(D3DFMT_D24X8);
153 FMT_TO_STR(D3DFMT_D24X4S4);
154 FMT_TO_STR(D3DFMT_VERTEXDATA);
155 FMT_TO_STR(D3DFMT_INDEX16);
156 FMT_TO_STR(D3DFMT_INDEX32);
159 FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
160 return "unrecognized";
164 const char* debug_d3dressourcetype(D3DRESOURCETYPE res) {
166 #define RES_TO_STR(res) case res: return #res;
167 RES_TO_STR(D3DRTYPE_SURFACE);
168 RES_TO_STR(D3DRTYPE_VOLUME);
169 RES_TO_STR(D3DRTYPE_TEXTURE);
170 RES_TO_STR(D3DRTYPE_VOLUMETEXTURE);
171 RES_TO_STR(D3DRTYPE_CUBETEXTURE);
172 RES_TO_STR(D3DRTYPE_VERTEXBUFFER);
173 RES_TO_STR(D3DRTYPE_INDEXBUFFER);
176 FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res);
177 return "unrecognized";
181 const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) {
182 switch (PrimitiveType) {
183 #define PRIM_TO_STR(prim) case prim: return #prim;
184 PRIM_TO_STR(D3DPT_POINTLIST);
185 PRIM_TO_STR(D3DPT_LINELIST);
186 PRIM_TO_STR(D3DPT_LINESTRIP);
187 PRIM_TO_STR(D3DPT_TRIANGLELIST);
188 PRIM_TO_STR(D3DPT_TRIANGLESTRIP);
189 PRIM_TO_STR(D3DPT_TRIANGLEFAN);
192 FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
193 return "unrecognized";
197 /* Routine common to the draw primitive and draw indexed primitive routines */
198 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
205 const void *vertexBufData,
208 long StartVertexIndex,
214 int NumVertexes = NumPrimitives;
215 IDirect3DVertexShaderImpl* vertex_shader = NULL;
216 BOOL useVertexShaderFunction = FALSE;
218 ICOM_THIS(IDirect3DDevice8Impl,iface);
220 /* Dont understand how to handle multiple streams, but if a fixed
221 FVF is passed in rather than a handle, it must use stream 0 */
223 if (This->UpdateStateBlock->VertexShader > VS_HIGHESTFIXEDFXF) {
224 vertex_shader = VERTEX_SHADER(This->UpdateStateBlock->VertexShader);
225 if (NULL == vertex_shader) {
226 ERR_(d3d_shader)("trying to use unitialised vertex shader: %lu\n", This->UpdateStateBlock->VertexShader);
229 if (NULL == vertex_shader->function) {
230 TRACE_(d3d_shader)("vertex shader declared without program, using FVF pure mode\n");
232 useVertexShaderFunction = TRUE;
234 fvf = (D3DFORMAT) This->UpdateStateBlock->vertexShaderDecl->fvf;
235 TRACE_(d3d_shader)("vertex shader declared FVF: %08lx\n", This->UpdateStateBlock->vertexShaderDecl->fvf);
236 memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8));
238 /** init Constants */
239 if (TRUE == This->UpdateStateBlock->Changed.vertexShaderConstant) {
240 TRACE_(d3d_shader)("vertex shader init Constant\n");
241 IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96);
247 int skip = This->StateBlock->stream_stride[0];
248 GLenum primType = GL_POINTS;
258 const char *curVtx = NULL;
259 const short *pIdxBufS = NULL;
260 const long *pIdxBufL = NULL;
262 BOOL isLightingOn = FALSE;
264 int coordIdxInfo = 0x00; /* Information on number of coords supplied */
265 float s[8], t[8], r[8], q[8]; /* Holding place for tex coords */
266 const char *coordPtr[8]; /* Holding place for the ptr to tex coords */
267 int numCoords[8]; /* Holding place for D3DFVF_TEXTUREFORMATx */
272 z = 0.0f; /* x,y,z coordinates */
275 nz = 0.0f; /* normal x,y,z coordinates */
276 float rhw = 0.0f; /* rhw */
277 float ptSize = 0.0f; /* Point size */
278 DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
279 DWORD specularColor = 0; /* Specular Color */
284 if (idxBytes == 2) pIdxBufS = (short *) idxData;
285 else pIdxBufL = (long *) idxData;
288 /* Check vertex formats expected ? */
290 * FVF parser as seen it
291 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/Reference/CPP/D3D/FlexibleVertexFormatFlags.asp
293 normal = fvf & D3DFVF_NORMAL;
294 isRHW = fvf & D3DFVF_XYZRHW;
295 isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
296 numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2 + ((FALSE == isLastUByte4) ? 0 : -1); /* WARNING can be < 0 because -2 */
297 isPtSize = fvf & D3DFVF_PSIZE;
298 isDiffuse = fvf & D3DFVF_DIFFUSE;
299 isSpecular = fvf & D3DFVF_SPECULAR;
300 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
301 coordIdxInfo = (fvf & 0x00FF0000) >> 16; /* 16 is from definition of D3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */
303 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d, coordIdxInfo=%x)\n",
304 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends, coordIdxInfo);
306 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
307 set by the appropriate render state */
309 isLightingOn = glIsEnabled(GL_LIGHTING);
310 glDisable(GL_LIGHTING);
311 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
315 double X, Y, height, width, minZ, maxZ;
317 * Already transformed vertex do not need transform
318 * matrices. Reset all matrices to identity.
319 * Leave the default matrix in world mode.
321 glMatrixMode(GL_MODELVIEW);
322 checkGLcall("glMatrixMode");
324 checkGLcall("glLoadIdentity");
326 * As seen in d3d7 code:
327 * See the OpenGL Red Book for an explanation of the following translation (in the OpenGL
328 * Correctness Tips section).
330 glTranslatef(0.375f, 0.375f, 0.0f);
334 glMatrixMode(GL_PROJECTION);
335 checkGLcall("glMatrixMode");
337 checkGLcall("glLoadIdentity");
338 X = This->StateBlock->viewport.X;
339 Y = This->StateBlock->viewport.Y;
340 height = This->StateBlock->viewport.Height;
341 width = This->StateBlock->viewport.Width;
342 minZ = This->StateBlock->viewport.MinZ;
343 maxZ = This->StateBlock->viewport.MaxZ;
344 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
345 /*glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);*/
346 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
347 checkGLcall("glOrtho");
349 glMatrixMode(GL_MODELVIEW);
350 checkGLcall("glMatrixMode");
351 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
352 checkGLcall("glLoadMatrixf");
353 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
354 checkGLcall("glMultMatrixf");
356 glMatrixMode(GL_PROJECTION);
357 checkGLcall("glMatrixMode");
358 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
359 checkGLcall("glLoadMatrixf");
362 /* Set OpenGL to the appropriate Primitive Type */
363 switch (PrimitiveType) {
364 case D3DPT_POINTLIST:
366 primType = GL_POINTS;
367 NumVertexes = NumPrimitives;
373 NumVertexes = NumPrimitives * 2;
376 case D3DPT_LINESTRIP:
377 TRACE("LINE_STRIP\n");
378 primType = GL_LINE_STRIP;
379 NumVertexes = NumPrimitives + 1;
382 case D3DPT_TRIANGLELIST:
383 TRACE("TRIANGLES\n");
384 primType = GL_TRIANGLES;
385 NumVertexes = NumPrimitives * 3;
388 case D3DPT_TRIANGLESTRIP:
389 TRACE("TRIANGLE_STRIP\n");
390 primType = GL_TRIANGLE_STRIP;
391 NumVertexes = NumPrimitives + 2;
394 case D3DPT_TRIANGLEFAN:
395 TRACE("TRIANGLE_FAN\n");
396 primType = GL_TRIANGLE_FAN;
397 NumVertexes = NumPrimitives + 2;
401 FIXME("Unhandled primitive\n");
405 /* Fixme, Ideally, only use this per-vertex code for software HAL
406 but until opengl supports all the functions returned to setup
407 vertex arrays, we need to drop down to the slow mechanism for
410 if (isPtSize || isDiffuse || useVertexShaderFunction == TRUE || (numBlends > 0)) {
411 TRACE("Using slow per-vertex code\n");
413 /* Enable this one to be able to debug what is going on, but it is slower
414 than the pointer/array version */
415 VTRACE(("glBegin(%x)\n", primType));
418 /* Draw the primitives */
419 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
421 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
427 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
428 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
430 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
431 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
435 /* Work through the vertex buffer */
436 x = *(float *)curPos;
437 curPos = curPos + sizeof(float);
438 y = *(float *)curPos;
439 curPos = curPos + sizeof(float);
440 z = *(float *)curPos;
441 curPos = curPos + sizeof(float);
442 VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
444 /* RHW follows, only if transformed */
446 rhw = *(float *)curPos;
447 curPos = curPos + sizeof(float);
448 VTRACE(("rhw=%f\n", rhw));
454 D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
455 DWORD skippedBlendLastUByte4 = 0;
457 for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
458 ((float*)&skippedBlend)[i] = *(float *)curPos;
459 curPos = curPos + sizeof(float);
463 skippedBlendLastUByte4 = *(DWORD*)curPos;
464 curPos = curPos + sizeof(DWORD);
468 /* Vertex Normal Data (untransformed only) */
470 nx = *(float *)curPos;
471 curPos = curPos + sizeof(float);
472 ny = *(float *)curPos;
473 curPos = curPos + sizeof(float);
474 nz = *(float *)curPos;
475 curPos = curPos + sizeof(float);
476 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
480 ptSize = *(float *)curPos;
481 VTRACE(("ptSize=%f\n", ptSize));
482 curPos = curPos + sizeof(float);
486 diffuseColor = *(DWORD *)curPos;
487 VTRACE(("diffuseColor=%lx\n", diffuseColor));
488 curPos = curPos + sizeof(DWORD);
492 specularColor = *(DWORD *)curPos;
493 VTRACE(("specularColor=%lx\n", specularColor));
494 curPos = curPos + sizeof(DWORD);
498 /* numTextures indicates the number of texture coordinates supplied */
499 /* However, the first set may not be for stage 0 texture - it all */
500 /* depends on D3DTSS_TEXCOORDINDEX. */
501 /* The number of bytes for each coordinate set is based off */
502 /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
504 /* Initialize unused coords to unsupplied so we can check later */
505 for (textureNo = numTextures; textureNo < 7; textureNo++) numCoords[textureNo] = -1;
507 /* So, for each supplied texture extract the coords */
508 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
510 numCoords[textureNo] = coordIdxInfo & 0x03;
513 s[textureNo] = *(float *)curPos;
514 curPos = curPos + sizeof(float);
515 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
516 t[textureNo] = *(float *)curPos;
517 curPos = curPos + sizeof(float);
518 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
519 r[textureNo] = *(float *)curPos;
520 curPos = curPos + sizeof(float);
521 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
522 q[textureNo] = *(float *)curPos;
523 curPos = curPos + sizeof(float);
528 coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
531 /* Now use the appropriate set of texture indexes */
532 for (textureNo = 0; textureNo < This->TextureUnits; ++textureNo) {
534 if (!(This->isMultiTexture) && textureNo > 0) {
535 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
539 /* Query tex coords */
540 if ((This->StateBlock->textures[textureNo] != NULL) &&
541 (useVertexShaderFunction == FALSE)) {
543 int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
546 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
547 } else if (coordIdx >= numTextures) {
548 VTRACE(("tex: %d - Skip tex coords, as requested higher than supplied\n", textureNo));
551 int coordsToUse = numCoords[coordIdx];
553 /* If texture transform flags in effect, values passed through to vertex
554 depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
556 This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)
558 /* This indicates how many coords to use regardless of the
559 texture type. However, d3d/opengl fill in the rest appropriately */
560 coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
562 /* BUT - Projected is more 'fun' - Move the last coord to the 'q'
563 parameter (see comments under D3DTSS_TEXTURETRANSFORMFLAGS */
564 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
565 switch (coordsToUse) {
566 case 0: /* Drop Through */
568 FIXME("D3DTTFF_PROJECTED but only zero or one coordinate?\n");
571 q[textureNo] = t[textureNo];
576 q[textureNo] = r[textureNo];
580 case 4: /* Nop here */
583 FIXME("Unexpected D3DTSS_TEXTURETRANSFORMFLAGS value of %ld\n",
584 This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
589 switch (coordsToUse) { /* Supply the provided texture coords */
590 case D3DFVF_TEXTUREFORMAT1:
591 VTRACE(("tex:%d, s=%f\n", textureNo, s[coordIdx]));
592 if (This->isMultiTexture) {
593 #if defined(GL_VERSION_1_3)
594 glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s[coordIdx]);
596 glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx]);
599 glTexCoord1f(s[coordIdx]);
602 case D3DFVF_TEXTUREFORMAT2:
603 VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s[coordIdx], t[coordIdx]));
604 if (This->isMultiTexture) {
605 #if defined(GL_VERSION_1_3)
606 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx]);
608 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx]);
611 glTexCoord2f(s[coordIdx], t[coordIdx]);
614 case D3DFVF_TEXTUREFORMAT3:
615 VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx]));
616 if (This->isMultiTexture) {
617 #if defined(GL_VERSION_1_3)
618 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
620 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
623 glTexCoord3f(s[coordIdx], t[coordIdx], r[coordIdx]);
626 case D3DFVF_TEXTUREFORMAT4:
627 VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]));
628 if (This->isMultiTexture) {
629 #if defined(GL_VERSION_1_3)
630 glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
632 glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
635 glTexCoord4f(s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
639 FIXME("Should not get here as numCoords is two bits only (%x)!\n", numCoords[coordIdx]);
646 /** if vertex shader program specified ... using it */
647 if (TRUE == useVertexShaderFunction) {
650 * this code must become the really
651 * vs input params init
653 * because its possible to use input registers for anything
654 * and some samples use registers for other things than they are
659 * no really valid declaration, user defined input register use
660 * so fill input registers as described in vertex shader declaration
662 IDirect3DDeviceImpl_FillVertexShaderInput(This, vertex_shader, vertexBufData, StartVertexIndex,
663 (!isIndexed) ? (vx_index * skip) :
664 (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) :
665 ((pIdxBufL[StartIdx + vx_index]) * skip));
667 memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
668 IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
670 TRACE_VECTOR(vertex_shader->output.oPos);
671 TRACE_VECTOR(vertex_shader->output.oD[0]);
672 TRACE_VECTOR(vertex_shader->output.oD[1]);
673 TRACE_VECTOR(vertex_shader->output.oT[0]);
674 TRACE_VECTOR(vertex_shader->output.oT[1]);
675 TRACE_VECTOR(vertex_shader->input.V[0]);
676 TRACE_VECTOR(vertex_shader->data->C[0]);
677 TRACE_VECTOR(vertex_shader->data->C[1]);
678 TRACE_VECTOR(vertex_shader->data->C[2]);
679 TRACE_VECTOR(vertex_shader->data->C[3]);
680 TRACE_VECTOR(vertex_shader->data->C[4]);
681 TRACE_VECTOR(vertex_shader->data->C[5]);
682 TRACE_VECTOR(vertex_shader->data->C[6]);
683 TRACE_VECTOR(vertex_shader->data->C[7]);
685 x = vertex_shader->output.oPos.x;
686 y = vertex_shader->output.oPos.y;
687 z = vertex_shader->output.oPos.z;
689 if (1.0f != vertex_shader->output.oPos.w || isRHW) {
690 rhw = vertex_shader->output.oPos.w;
692 /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
693 glColor4fv((float*) &vertex_shader->output.oD[0]);
695 /* Requires secondary color extensions to compile... */
696 #if defined(GL_VERSION_1_4)
697 glSecondaryColor3fv((float*) &vertex_shader->output.oD[1]);
698 checkGLcall("glSecondaryColor3fv");
700 if (checkGLSupport(EXT_SECONDARY_COLOR)) {
701 /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/
702 /*GLExtCall(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]);*/
703 /*checkGLcall("glSecondaryColor3fvEXT");*/
706 /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
707 for (textureNo = 0; textureNo < 4; ++textureNo) {
710 if (!(This->isMultiTexture) && textureNo > 0) {
711 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
714 /* Query tex coords */
715 if (This->StateBlock->textures[textureNo] != NULL) {
716 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
717 case D3DRTYPE_TEXTURE:
718 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
719 s = vertex_shader->output.oT[textureNo].x;
720 t = vertex_shader->output.oT[textureNo].y;
721 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t));
722 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
723 VTRACE(("Skip tex coords, as being system generated\n"));
725 if (This->isMultiTexture) {
726 #if defined(GL_VERSION_1_3)
727 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
729 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
731 /*checkGLcall("glMultiTexCoord2fARB");*/
734 /*checkGLcall("gTexCoord2f");*/
739 case D3DRTYPE_VOLUMETEXTURE:
740 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
741 s = vertex_shader->output.oT[textureNo].x;
742 t = vertex_shader->output.oT[textureNo].y;
743 r = vertex_shader->output.oT[textureNo].z;
744 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r));
745 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
746 VTRACE(("Skip tex coords, as being system generated\n"));
748 if (This->isMultiTexture) {
749 #if defined(GL_VERSION_1_3)
750 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
752 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
754 /*checkGLcall("glMultiTexCoord2fARB");*/
756 glTexCoord3f(s, t, r);
757 /*checkGLcall("gTexCoord3f");*/
763 /* Avoid compiler warnings, need these vars later for other textures */
765 FIXME("Unhandled texture type\n");
770 if (1.0f == rhw || rhw < 0.01f) {
771 TRACE_(d3d_shader)("Vertex: glVertex:x,y,z=%f,%f,%f\n", x, y, z);
773 /*checkGLcall("glVertex3f");*/
775 GLfloat w = 1.0f / rhw;
776 TRACE_(d3d_shader)("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw);
778 /*glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);*/
779 glVertex4f(x * w, y * w, z * w, 1.0f);
780 /*checkGLcall("glVertex4f");*/
784 * FALSE == useVertexShaderFunction
788 /* Handle these vertexes */
790 glColor4ub((diffuseColor >> 16) & 0xFF,
791 (diffuseColor >> 8) & 0xFF,
792 (diffuseColor >> 0) & 0xFF,
793 (diffuseColor >> 24) & 0xFF);
794 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
795 ((diffuseColor >> 16) & 0xFF) / 255.0f,
796 ((diffuseColor >> 8) & 0xFF) / 255.0f,
797 ((diffuseColor >> 0) & 0xFF) / 255.0f,
798 ((diffuseColor >> 24) & 0xFF) / 255.0f));
802 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
803 glNormal3f(nx, ny, nz);
806 if (1.0f == rhw || rhw < 0.01f) {
807 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
810 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
811 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
817 curVtx = curVtx + skip;
822 checkGLcall("glEnd and previous calls");
825 TRACE("Using fast vertex array code\n");
827 /* Faster version, harder to debug */
828 /* Shuffle to the beginning of the vertexes to render and index from there */
829 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
832 /* Set up the vertex pointers */
834 glVertexPointer(4, GL_FLOAT, skip, curPos);
835 checkGLcall("glVertexPointer(4, ...)");
836 curPos += 4 * sizeof(float);
838 glVertexPointer(3, GL_FLOAT, skip, curPos);
839 checkGLcall("glVertexPointer(3, ...)");
840 curPos += 3 * sizeof(float);
842 glEnableClientState(GL_VERTEX_ARRAY);
843 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
846 /* no such functionality in the fixed function GL pipeline */
847 /* FIXME: Wont get here as will drop to slow method */
848 /* FIXME("Cannot handle blending data here in openGl\n");*/
849 if (checkGLSupport(ARB_VERTEX_BLEND)) {
851 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
854 GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
855 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
856 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
857 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
859 curPos += numBlends * sizeof(float);
861 FIXME("unsupported blending in openGl\n");
864 if (checkGLSupport(ARB_VERTEX_BLEND)) {
866 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
869 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
870 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
877 glNormalPointer(GL_FLOAT, skip, curPos);
878 checkGLcall("glNormalPointer");
879 glEnableClientState(GL_NORMAL_ARRAY);
880 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
881 curPos += 3 * sizeof(float);
883 glDisableClientState(GL_NORMAL_ARRAY);
884 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
886 checkGLcall("glNormal3f(0, 0, 1)");
890 /* no such functionality in the fixed function GL pipeline */
891 /* FIXME: Wont get here as will drop to slow method */
892 FIXME("Cannot change ptSize here in openGl\n");
893 curPos = curPos + sizeof(float);
897 glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
898 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
899 glEnableClientState(GL_COLOR_ARRAY);
900 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
901 curPos += sizeof(DWORD);
904 glDisableClientState(GL_COLOR_ARRAY);
905 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
906 glColor4f(1, 1, 1, 1);
907 checkGLcall("glColor4f(1, 1, 1, 1)");
910 /* Requires secondary color extensions to compile... */
912 #if defined(GL_VERSION_1_4)
913 glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
914 checkGLcall("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos)");
915 glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
916 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY)");
919 /* FIXME: check for GL_EXT_secondary_color */
920 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos);
921 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
922 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
923 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
926 curPos += sizeof(DWORD);
928 #if defined(GL_VERSION_1_4)
929 glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
930 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY)");
931 glSecondaryColor3f(0, 0, 0);
932 checkGLcall("glSecondaryColor3f(0, 0, 0)");
935 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
936 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
937 glSecondaryColor3fEXT(0, 0, 0);
938 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
944 /* numTextures indicates the number of texture coordinates supplied */
945 /* However, the first set may not be for stage 0 texture - it all */
946 /* depends on D3DTSS_TEXCOORDINDEX. */
947 /* The number of bytes for each coordinate set is based off */
948 /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
950 /* Initialize unused coords to unsupplied so we can check later */
951 for (textureNo = numTextures; textureNo < 7; textureNo++) coordPtr[textureNo] = NULL;
953 /* So, for each supplied texture extract the coords */
954 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
956 numCoords[textureNo] = coordIdxInfo & 0x03;
957 coordPtr[textureNo] = curPos;
960 curPos = curPos + sizeof(float);
961 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
962 curPos = curPos + sizeof(float);
963 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
964 curPos = curPos + sizeof(float);
965 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
966 curPos = curPos + sizeof(float);
970 coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
973 /* Now use the appropriate set of texture indexes */
974 for (textureNo = 0; textureNo < This->TextureUnits; ++textureNo) {
976 if (!(This->isMultiTexture) && textureNo > 0) {
977 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
981 /* Query tex coords */
982 if ((This->StateBlock->textures[textureNo] != NULL) && (useVertexShaderFunction == FALSE)) {
983 int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
986 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
989 int coordsToUse = numCoords[coordIdx];
990 #if defined(GL_VERSION_1_3)
991 glClientActiveTexture(GL_TEXTURE0 + textureNo);
993 glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
996 /* If texture transform flags in effect, values passed through to vertex
997 depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
998 if (coordsToUse > 0 &&
999 This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)
1001 /* This indicates how many coords to use regardless of the
1002 texture type. However, d3d/opengl fill in the rest appropriately */
1003 coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
1005 /* BUT - Projected is more 'fun' - Cant be done for ptr mode.
1006 Probably should scan enabled texture units and drop back to
1007 slow mode if found? */
1008 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
1009 FIXME("Cannot handle projected transform state in fast mode\n");
1013 switch (coordsToUse) { /* Supply the provided texture coords */
1014 case D3DFVF_TEXTUREFORMAT1: numFloats = 1; break;
1015 case D3DFVF_TEXTUREFORMAT2: numFloats = 2; break;
1016 case D3DFVF_TEXTUREFORMAT3: numFloats = 3; break;
1017 case D3DFVF_TEXTUREFORMAT4: numFloats = 4; break;
1018 default: numFloats = 0; break;
1021 if (numFloats == 0 || coordIdx >= numTextures) {
1022 VTRACE(("Skipping as invalid request - numfloats=%d, coordIdx=%d, numTextures=%d\n", numFloats, coordIdx, numTextures));
1023 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1024 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
1026 VTRACE(("tex: %d, ptr=%p, numcoords=%d\n", textureNo, coordPtr[coordIdx], numFloats));
1027 glTexCoordPointer(numFloats, GL_FLOAT, skip, coordPtr[coordIdx]);
1028 checkGLcall("glTexCoordPointer(x, ...)");
1029 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1030 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
1036 /* Finally do the drawing */
1039 TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
1041 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
1042 glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT,
1043 (char *)idxData+(2 * StartIdx));
1045 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
1046 GL_UNSIGNED_SHORT, (char *)idxData+(2 * StartIdx));
1049 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
1050 glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT,
1051 (char *)idxData+(4 * StartIdx));
1053 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
1054 GL_UNSIGNED_INT, (char *)idxData+(2 * StartIdx));
1057 checkGLcall("glDrawRangeElements");
1061 /* Note first is now zero as we shuffled along earlier */
1062 TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
1063 glDrawArrays(primType, 0, NumVertexes);
1064 checkGLcall("glDrawArrays");
1069 /* If no normals, restore previous lighting state */
1071 if (isLightingOn) glEnable(GL_LIGHTING);
1072 else glDisable(GL_LIGHTING);
1073 TRACE("Restored lighting to original state\n");
1083 * Simple utility routines used for dx -> gl mapping of byte formats
1085 SHORT bytesPerPixel(D3DFORMAT fmt) {
1090 case D3DFMT_P8: retVal = 1; break;
1091 case D3DFMT_A4R4G4B4: retVal = 2; break;
1092 case D3DFMT_R5G6B5: retVal = 2; break;
1093 case D3DFMT_X1R5G5B5: retVal = 2; break;
1094 case D3DFMT_A1R5G5B5: retVal = 2; break;
1095 case D3DFMT_R8G8B8: retVal = 3; break;
1096 case D3DFMT_X8R8G8B8: retVal = 4; break;
1097 case D3DFMT_A8R8G8B8: retVal = 4; break;
1098 /* depth/stencil buffer */
1099 case D3DFMT_D16_LOCKABLE: retVal = 2; break;
1100 case D3DFMT_D16: retVal = 2; break;
1101 case D3DFMT_D15S1: retVal = 2; break;
1102 case D3DFMT_D24X4S4: retVal = 4; break;
1103 case D3DFMT_D24S8: retVal = 4; break;
1104 case D3DFMT_D24X8: retVal = 4; break;
1105 case D3DFMT_D32: retVal = 4; break;
1107 case D3DFMT_UNKNOWN:
1108 /* Guess at the highest value of the above */
1109 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %u\n", fmt);
1114 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1117 TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
1121 GLint fmt2glintFmt(D3DFORMAT fmt) {
1125 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
1126 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
1127 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
1128 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
1129 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
1130 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
1132 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1135 TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
1138 GLenum fmt2glFmt(D3DFORMAT fmt) {
1142 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
1143 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
1144 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
1145 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
1146 case D3DFMT_R5G6B5: retVal = GL_RGB; break;
1147 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
1149 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1152 TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
1155 DWORD fmt2glType(D3DFORMAT fmt) {
1159 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
1160 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
1161 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
1162 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5; break;
1163 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
1164 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
1166 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1167 retVal = GL_UNSIGNED_BYTE;
1169 TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
1173 int SOURCEx_RGB_EXT(DWORD arg) {
1175 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
1176 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
1177 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
1178 case D3DTSS_ALPHAARG0:
1179 case D3DTSS_ALPHAARG1:
1180 case D3DTSS_ALPHAARG2:
1182 FIXME("Invalid arg %ld\n", arg);
1183 return GL_SOURCE0_RGB_EXT;
1186 int OPERANDx_RGB_EXT(DWORD arg) {
1188 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
1189 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
1190 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
1191 case D3DTSS_ALPHAARG0:
1192 case D3DTSS_ALPHAARG1:
1193 case D3DTSS_ALPHAARG2:
1195 FIXME("Invalid arg %ld\n", arg);
1196 return GL_OPERAND0_RGB_EXT;
1199 int SOURCEx_ALPHA_EXT(DWORD arg) {
1201 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
1202 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
1203 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
1204 case D3DTSS_COLORARG0:
1205 case D3DTSS_COLORARG1:
1206 case D3DTSS_COLORARG2:
1208 FIXME("Invalid arg %ld\n", arg);
1209 return GL_SOURCE0_ALPHA_EXT;
1212 int OPERANDx_ALPHA_EXT(DWORD arg) {
1214 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
1215 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
1216 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
1217 case D3DTSS_COLORARG0:
1218 case D3DTSS_COLORARG1:
1219 case D3DTSS_COLORARG2:
1221 FIXME("Invalid arg %ld\n", arg);
1222 return GL_OPERAND0_ALPHA_EXT;
1225 GLenum StencilOp(DWORD op) {
1227 case D3DSTENCILOP_KEEP : return GL_KEEP;
1228 case D3DSTENCILOP_ZERO : return GL_ZERO;
1229 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
1230 case D3DSTENCILOP_INCRSAT : return GL_INCR;
1231 case D3DSTENCILOP_DECRSAT : return GL_DECR;
1232 case D3DSTENCILOP_INVERT : return GL_INVERT;
1233 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op D3DSTENCILOP_INCR\n");
1234 return GL_INCR; /* Fixme - needs to support wrap */
1235 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op D3DSTENCILOP_DECR\n");
1236 return GL_DECR; /* Fixme - needs to support wrap */
1238 FIXME("Invalid stencil op %ld\n", op);
1246 void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand)
1248 BOOL isAlphaReplicate = FALSE;
1249 BOOL isComplement = FALSE;
1251 *operand = GL_SRC_COLOR;
1252 *source = GL_TEXTURE;
1254 /* Catch alpha replicate */
1255 if (iValue & D3DTA_ALPHAREPLICATE) {
1256 iValue = iValue & ~D3DTA_ALPHAREPLICATE;
1257 isAlphaReplicate = TRUE;
1260 /* Catch Complement */
1261 if (iValue & D3DTA_COMPLEMENT) {
1262 iValue = iValue & ~D3DTA_COMPLEMENT;
1263 isComplement = TRUE;
1266 /* Calculate the operand */
1267 if (isAlphaReplicate && !isComplement) {
1268 *operand = GL_SRC_ALPHA;
1269 } else if (isAlphaReplicate && isComplement) {
1270 *operand = GL_ONE_MINUS_SRC_ALPHA;
1271 } else if (isComplement) {
1273 *operand = GL_ONE_MINUS_SRC_ALPHA;
1275 *operand = GL_ONE_MINUS_SRC_COLOR;
1279 *operand = GL_SRC_ALPHA;
1281 *operand = GL_SRC_COLOR;
1285 /* Calculate the source */
1286 switch (iValue & D3DTA_SELECTMASK) {
1287 case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT;
1289 case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT;
1291 case D3DTA_TEXTURE: *source = GL_TEXTURE;
1293 case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT;
1295 case D3DTA_SPECULAR:
1297 * According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
1298 * isnt supported until base GL supports it
1299 * There is no concept of temp registers as far as I can tell
1303 FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
1304 *source = GL_TEXTURE;
1309 /* Apply the current values to the specified texture stage */
1310 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
1311 ICOM_THIS(IDirect3DDevice8Impl,iface);
1315 /* Make appropriate texture active */
1316 if (This->isMultiTexture) {
1317 #if defined(GL_VERSION_1_3)
1318 glActiveTexture(GL_TEXTURE0 + Stage);
1320 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
1322 checkGLcall("glActiveTextureARB");
1323 } else if (Stage > 0) {
1324 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
1327 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
1328 for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
1329 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
1332 /* Note the D3DRS value applies to all textures, but GL has one
1333 per texture, so apply it now ready to be used! */
1335 col[0] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
1336 col[1] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
1337 col[2] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
1338 col[3] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
1340 D3DCOLORTOGLFLOAT4(This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR], col);
1341 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1342 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1344 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
1347 /* IDirect3D IUnknown parts follow: */
1348 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
1350 ICOM_THIS(IDirect3DDevice8Impl,iface);
1352 if (IsEqualGUID(riid, &IID_IUnknown)
1353 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
1354 IDirect3DDevice8Impl_AddRef(iface);
1359 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
1360 return E_NOINTERFACE;
1363 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
1364 ICOM_THIS(IDirect3DDevice8Impl,iface);
1365 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
1366 return ++(This->ref);
1369 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
1370 ICOM_THIS(IDirect3DDevice8Impl,iface);
1371 ULONG ref = --This->ref;
1372 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
1374 HeapFree(GetProcessHeap(), 0, This);
1379 /* IDirect3DDevice Interface follow: */
1380 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
1381 ICOM_THIS(IDirect3DDevice8Impl,iface);
1382 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
1386 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
1387 ICOM_THIS(IDirect3DDevice8Impl,iface);
1388 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
1390 * pretend we have 32MB of any type of memory queried.
1392 return (1024*1024*32);
1395 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
1396 ICOM_THIS(IDirect3DDevice8Impl,iface);
1397 FIXME("(%p) : stub\n", This); return D3D_OK;
1399 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
1400 ICOM_THIS(IDirect3DDevice8Impl,iface);
1401 TRACE("(%p) : returning %p\n", This, This->direct3d8);
1404 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
1406 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
1409 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
1410 ICOM_THIS(IDirect3DDevice8Impl,iface);
1411 FIXME("(%p) : stub, calling idirect3d for now\n", This);
1412 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
1415 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
1420 ICOM_THIS(IDirect3DDevice8Impl,iface);
1421 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
1422 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
1423 pMode->RefreshRate = 85; /*FIXME: How to identify? */
1425 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1426 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1430 case 8: pMode->Format = D3DFMT_R8G8B8; break;
1431 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1432 case 24: /*pMode->Format = D3DFMT_R8G8B8; break; */
1433 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1435 FIXME("Unrecognized display mode format\n");
1436 pMode->Format = D3DFMT_UNKNOWN;
1439 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
1440 pMode->Format, debug_d3dformat(pMode->Format));
1443 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1444 ICOM_THIS(IDirect3DDevice8Impl,iface);
1445 TRACE("(%p) copying to %p\n", This, pParameters);
1446 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1449 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1450 ICOM_THIS(IDirect3DDevice8Impl,iface);
1451 FIXME("(%p) : stub\n", This); return D3D_OK;
1453 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1454 ICOM_THIS(IDirect3DDevice8Impl,iface);
1455 FIXME("(%p) : stub\n", This); return;
1457 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1458 ICOM_THIS(IDirect3DDevice8Impl,iface);
1459 FIXME("(%p) : stub\n", This); return D3D_OK;
1461 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1462 ICOM_THIS(IDirect3DDevice8Impl,iface);
1463 FIXME("(%p) : stub\n", This);
1467 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1468 ICOM_THIS(IDirect3DDevice8Impl,iface);
1469 FIXME("(%p) : stub\n", This); return D3D_OK;
1471 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1472 ICOM_THIS(IDirect3DDevice8Impl,iface);
1473 TRACE("(%p) : complete stub!\n", This);
1477 glXSwapBuffers(This->display, This->win);
1478 checkGLcall("glXSwapBuffers");
1484 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
1485 ICOM_THIS(IDirect3DDevice8Impl,iface);
1486 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1487 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1489 if (BackBuffer > This->PresentParms.BackBufferCount - 1) {
1490 FIXME("Only one backBuffer currently supported\n");
1491 return D3DERR_INVALIDCALL;
1494 /* Note inc ref on returned surface */
1495 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1499 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1500 ICOM_THIS(IDirect3DDevice8Impl,iface);
1501 FIXME("(%p) : stub\n", This);
1504 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1505 ICOM_THIS(IDirect3DDevice8Impl,iface);
1506 FIXME("(%p) : stub\n", This); return;
1508 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1509 ICOM_THIS(IDirect3DDevice8Impl,iface);
1510 FIXME("(%p) : stub\n", This); return;
1512 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1513 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1514 IDirect3DTexture8Impl *object;
1519 ICOM_THIS(IDirect3DDevice8Impl,iface);
1521 /* Allocate the storage for the device */
1522 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, debug_d3dformat(Format), Pool);
1523 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1524 object->lpVtbl = &Direct3DTexture8_Vtbl;
1525 object->Device = This;
1526 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->device);*/
1527 object->ResourceType = D3DRTYPE_TEXTURE;
1529 object->width = Width;
1530 object->height = Height;
1531 object->levels = Levels;
1532 object->usage = Usage;
1533 object->format = Format;
1536 /* Calculate levels for mip mapping */
1541 while (tmpW > 1 && tmpH > 1) {
1542 tmpW = max(1, tmpW / 2);
1543 tmpH = max(1, tmpH / 2);
1546 TRACE("Calculated levels = %d\n", object->levels);
1549 /* Generate all the surfaces */
1552 for (i = 0; i < object->levels; i++)
1554 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1555 object->surfaces[i]->Container = (IUnknown*) object;
1556 /*IUnknown_AddRef(object->surfaces[i]->Container);*/
1557 object->surfaces[i]->myDesc.Usage = Usage;
1558 object->surfaces[i]->myDesc.Pool = Pool ;
1560 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1561 tmpW = max(1, tmpW / 2);
1562 tmpH = max(1, tmpH / 2);
1565 *ppTexture = (LPDIRECT3DTEXTURE8) object;
1568 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1570 IDirect3DVolumeTexture8Impl *object;
1576 ICOM_THIS(IDirect3DDevice8Impl,iface);
1578 /* Allocate the storage for it */
1579 TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%d)\n", This, Width, Height, Depth, Levels, Usage, Format, debug_d3dformat(Format), Pool);
1580 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1581 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1582 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1583 object->Device = This;
1584 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1587 object->width = Width;
1588 object->height = Height;
1589 object->depth = Depth;
1590 object->levels = Levels;
1591 object->usage = Usage;
1592 object->format = Format;
1594 /* Calculate levels for mip mapping */
1600 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1601 tmpW = max(1, tmpW / 2);
1602 tmpH = max(1, tmpH / 2);
1603 tmpD = max(1, tmpD / 2);
1606 TRACE("Calculated levels = %d\n", object->levels);
1609 /* Generate all the surfaces */
1614 for (i = 0; i < object->levels; i++)
1616 IDirect3DVolume8Impl *volume;
1618 /* Create the volume - No entry point for this seperately?? */
1619 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1620 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1622 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1623 volume->Device = This;
1624 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) volume->Device);*/
1625 volume->ResourceType = D3DRTYPE_VOLUME;
1626 volume->Container = (IUnknown*) object;
1627 /*IUnknown_AddRef(volume->Container);*/
1630 volume->myDesc.Width = Width;
1631 volume->myDesc.Height = Height;
1632 volume->myDesc.Depth = Depth;
1633 volume->myDesc.Format = Format;
1634 volume->myDesc.Type = D3DRTYPE_VOLUME;
1635 volume->myDesc.Pool = Pool;
1636 volume->myDesc.Usage = Usage;
1637 volume->bytesPerPixel = bytesPerPixel(Format);
1638 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1639 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1641 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%u,%s) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format, debug_d3dformat(Format),
1642 volume, volume->allocatedMemory, volume->myDesc.Size);
1644 tmpW = max(1, tmpW / 2);
1645 tmpH = max(1, tmpH / 2);
1646 tmpD = max(1, tmpD / 2);
1649 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8) object;
1652 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
1654 IDirect3DCubeTexture8Impl *object;
1655 ICOM_THIS(IDirect3DDevice8Impl,iface);
1659 /* Allocate the storage for it */
1660 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, debug_d3dformat(Format), Pool);
1661 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1662 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1664 object->Device = This;
1665 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1666 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1668 object->edgeLength = EdgeLength;
1669 object->levels = Levels;
1670 object->usage = Usage;
1671 object->format = Format;
1673 /* Calculate levels for mip mapping */
1678 tmpW = max(1, tmpW / 2);
1681 TRACE("Calculated levels = %d\n", object->levels);
1684 /* Generate all the surfaces */
1686 for (i = 0; i < object->levels; i++) {
1687 /* Create the 6 faces */
1688 for (j = 0; j < 6; j++) {
1689 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1690 object->surfaces[j][i]->Container = (IUnknown*) object;
1691 /*IUnknown_AddRef(object->surfaces[j][i]->Container);*/
1692 object->surfaces[j][i]->myDesc.Usage = Usage;
1693 object->surfaces[j][i]->myDesc.Pool = Pool;
1694 /*object->surfaces[j][i]->myDesc.Format = Format;*/
1696 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1697 tmpW = max(1, tmpW / 2);
1701 TRACE("(%p) : Iface@%p\n", This, object);
1702 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1705 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1706 IDirect3DVertexBuffer8Impl *object;
1708 ICOM_THIS(IDirect3DDevice8Impl,iface);
1710 /* Allocate the storage for the device */
1711 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1712 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1713 object->Device = This;
1714 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1715 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1717 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1718 object->currentDesc.Usage = Usage;
1719 object->currentDesc.Pool = Pool;
1720 object->currentDesc.FVF = FVF;
1721 object->currentDesc.Size = Size;
1723 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1725 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1729 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) {
1730 IDirect3DIndexBuffer8Impl *object;
1732 ICOM_THIS(IDirect3DDevice8Impl,iface);
1733 TRACE("(%p) : Len=%d, Use=%lx, Format=(%u,%s), Pool=%d\n", This, Length, Usage, Format, debug_d3dformat(Format), Pool);
1735 /* Allocate the storage for the device */
1736 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1737 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1738 object->Device = This;
1739 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1741 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1743 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1744 object->currentDesc.Usage = Usage;
1745 object->currentDesc.Pool = Pool;
1746 object->currentDesc.Format = Format;
1747 object->currentDesc.Size = Length;
1749 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1751 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1753 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1757 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
1758 IDirect3DSurface8Impl *object;
1760 ICOM_THIS(IDirect3DDevice8Impl,iface);
1762 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1763 if (NULL == object) {
1765 return D3DERR_OUTOFVIDEOMEMORY;
1767 *ppSurface = (LPDIRECT3DSURFACE8) object;
1768 object->lpVtbl = &Direct3DSurface8_Vtbl;
1769 object->Device = This;
1770 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1771 object->ResourceType = D3DRTYPE_SURFACE;
1772 object->Container = (IUnknown*) This;
1773 /*IUnknown_AddRef(object->Container);*/
1776 object->myDesc.Width = Width;
1777 object->myDesc.Height = Height;
1778 object->myDesc.Format = Format;
1779 object->myDesc.Type = D3DRTYPE_SURFACE;
1780 object->myDesc.Usage = D3DUSAGE_RENDERTARGET;
1781 object->myDesc.Pool = D3DPOOL_DEFAULT;
1782 object->myDesc.MultiSampleType = MultiSample;
1783 object->bytesPerPixel = bytesPerPixel(Format);
1784 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1785 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1786 object->lockable = Lockable;
1787 object->locked = FALSE;
1789 TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), Lockable, *ppSurface, object->allocatedMemory, object->myDesc.Size);
1792 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
1793 IDirect3DSurface8Impl *object;
1795 ICOM_THIS(IDirect3DDevice8Impl,iface);
1797 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1798 if (NULL == object) {
1800 return D3DERR_OUTOFVIDEOMEMORY;
1802 *ppSurface = (LPDIRECT3DSURFACE8) object;
1803 object->lpVtbl = &Direct3DSurface8_Vtbl;
1804 object->Device = This;
1805 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1806 object->ResourceType = D3DRTYPE_SURFACE;
1807 object->Container = (IUnknown*) This;
1808 /*IUnknown_AddRef(object->Container);*/
1811 object->myDesc.Width = Width;
1812 object->myDesc.Height = Height;
1813 object->myDesc.Format = Format;
1814 object->myDesc.Type = D3DRTYPE_SURFACE;
1815 object->myDesc.Usage = D3DUSAGE_DEPTHSTENCIL;
1816 object->myDesc.Pool = D3DPOOL_DEFAULT;
1817 object->myDesc.MultiSampleType = MultiSample;
1818 object->bytesPerPixel = bytesPerPixel(Format);
1819 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1820 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1821 object->lockable = (D3DFMT_D16_LOCKABLE == Format) ? TRUE : FALSE;
1822 object->locked = FALSE;
1824 TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), *ppSurface, object->allocatedMemory, object->myDesc.Size);
1827 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
1828 IDirect3DSurface8Impl *object;
1830 ICOM_THIS(IDirect3DDevice8Impl,iface);
1832 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1833 *ppSurface = (LPDIRECT3DSURFACE8) object;
1834 object->lpVtbl = &Direct3DSurface8_Vtbl;
1835 object->Device = This;
1836 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1837 object->ResourceType = D3DRTYPE_SURFACE;
1838 object->Container = (IUnknown*) This;
1839 /*IUnknown_AddRef(object->Container);*/
1842 object->myDesc.Width = Width;
1843 object->myDesc.Height = Height;
1844 object->myDesc.Format = Format;
1845 object->myDesc.Type = D3DRTYPE_SURFACE;
1846 object->myDesc.Usage = 0;
1847 object->myDesc.Pool = D3DPOOL_SYSTEMMEM;
1848 object->bytesPerPixel = bytesPerPixel(Format);
1849 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1850 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1851 object->lockable = TRUE;
1852 object->locked = FALSE;
1854 TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), *ppSurface, object->allocatedMemory, object->myDesc.Size);
1857 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1858 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1860 HRESULT rc = D3D_OK;
1861 IDirect3DBaseTexture8* texture = NULL;
1864 IDirect3DSurface8Impl* src = (IDirect3DSurface8Impl*) pSourceSurface;
1865 IDirect3DSurface8Impl* dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1867 ICOM_THIS(IDirect3DDevice8Impl,iface);
1868 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1869 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1871 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1872 a sample and doesnt seem to break anything as far as I can tell */
1873 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1874 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1875 rc = D3DERR_INVALIDCALL;
1877 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1878 TRACE("Converting dest to same format as source, since dest was unknown\n");
1879 dst->myDesc.Format = src->myDesc.Format;
1881 /* Convert container as well */
1882 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1883 if (texture != NULL) {
1885 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1886 case D3DRTYPE_TEXTURE:
1887 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1889 case D3DRTYPE_VOLUMETEXTURE:
1890 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1892 case D3DRTYPE_CUBETEXTURE:
1893 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1896 FIXME("Unhandled texture type\n");
1899 /** Releasing texture after GetContainer */
1900 IDirect3DBaseTexture8_Release(texture);
1904 /* Quick if complete copy ... */
1905 if (rc == D3D_OK && cRects == 0 && pSourceRectsArray == NULL && pDestPointsArray == NULL) {
1907 if (src->myDesc.Width == dst->myDesc.Width && src->myDesc.Height == dst->myDesc.Height) {
1909 D3DLOCKED_RECT lrSrc;
1910 D3DLOCKED_RECT lrDst;
1911 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, NULL, D3DLOCK_READONLY);
1912 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, NULL, 0L);
1913 TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1915 /*memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);*/
1916 memcpy(lrDst.pBits, lrSrc.pBits, src->myDesc.Size);
1918 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
1919 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
1920 TRACE("Unlocked src and dst\n");
1924 FIXME("Wanted to copy all surfaces but size not compatible\n");
1925 rc = D3DERR_INVALIDCALL;
1931 if (NULL != pSourceRectsArray && NULL != pDestPointsArray) {
1933 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1935 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1936 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1937 char *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1938 char *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1943 /* Copy rect by rect */
1944 for (i = 0; i < cRects; i++) {
1945 CONST RECT* r = &pSourceRectsArray[i];
1946 CONST POINT* p = &pDestPointsArray[i];
1947 int copyperline = (r->right - r->left) * bytesPerPixel;
1949 D3DLOCKED_RECT lrSrc;
1950 D3DLOCKED_RECT lrDst;
1954 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top, r->right, r->bottom, p->x, p->y);
1956 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, r, D3DLOCK_READONLY);
1957 dest_rect.left = p->x;
1958 dest_rect.top = p->y;
1959 dest_rect.right = p->x + (r->right - r->left);
1960 dest_rect.left = p->y + (r->bottom - r->top);
1961 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, &dest_rect, 0L);
1962 TRACE("Locked src and dst\n");
1964 /* Find where to start */
1966 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1967 to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel);
1968 /* Copy line by line */
1969 for (j = 0; j < (r->bottom - r->top); j++) {
1970 memcpy(to + (j * pitchTo), from + (j * pitchFrom), copyperline);
1974 for (j = 0; j < (r->bottom - r->top); j++) {
1975 memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline);
1978 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
1979 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
1980 TRACE("Unlocked src and dst\n");
1985 FIXME("Wanted to copy partial surfaces not implemented\n");
1986 rc = D3DERR_INVALIDCALL;
1993 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1994 if (texture != NULL) {
1996 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1997 case D3DRTYPE_TEXTURE:
1999 IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)texture;
2000 pTexture->Dirty = TRUE;
2003 case D3DRTYPE_VOLUMETEXTURE:
2005 IDirect3DVolumeTexture8Impl *pTexture = (IDirect3DVolumeTexture8Impl *)texture;
2006 pTexture->Dirty = TRUE;
2009 case D3DRTYPE_CUBETEXTURE:
2011 IDirect3DCubeTexture8Impl *pTexture = (IDirect3DCubeTexture8Impl *)texture;
2012 pTexture->Dirty = TRUE;
2016 FIXME("Unhandled texture type\n");
2019 /** Releasing texture after GetContainer */
2020 IDirect3DBaseTexture8_Release(texture);
2026 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
2027 ICOM_THIS(IDirect3DDevice8Impl,iface);
2028 FIXME("(%p) : stub\n", This);
2031 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
2033 D3DLOCKED_RECT lockedRect;
2038 ICOM_THIS(IDirect3DDevice8Impl,iface);
2040 FIXME("(%p) : see if behavior correct\n", This);
2042 if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) {
2043 ERR("(%p) : surface(%p) have a invalid format\n", This, pDestSurface);
2044 return D3DERR_INVALIDCALL;
2047 wantedRect.left = 0;
2049 wantedRect.right = This->PresentParms.BackBufferWidth;
2050 wantedRect.bottom = This->PresentParms.BackBufferHeight;
2052 hr = IDirect3DSurface8Impl_LockRect(pDestSurface, &lockedRect, &wantedRect, 0);
2054 ERR("(%p) : cannot lock surface\n", This);
2055 return D3DERR_INVALIDCALL;
2062 IDirect3DSurface8Impl* tmp = ((IDirect3DSurface8Impl*) pDestSurface);
2063 FIXME("dest:%u,%u,bpp:%u\n", tmp->myDesc.Width, tmp->myDesc.Height, tmp->bytesPerPixel);
2064 FIXME("dest2:pitch%u\n", lockedRect.Pitch);
2065 FIXME("src:%u,%u\n", This->PresentParms.BackBufferWidth, This->PresentParms.BackBufferHeight);
2066 tmp = This->frontBuffer;
2067 FIXME("src2:%u,%u,bpp:%u\n", tmp->myDesc.Width, tmp->myDesc.Height, tmp->bytesPerPixel);
2072 vcheckGLcall("glFlush");
2073 glGetIntegerv(GL_READ_BUFFER, &prev_read);
2074 vcheckGLcall("glIntegerv");
2075 glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
2076 vcheckGLcall("glIntegerv");
2078 glReadBuffer(GL_FRONT);
2079 vcheckGLcall("glReadBuffer");
2080 glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
2081 vcheckGLcall("glPixelStorei");
2085 for (j = 0; j < This->PresentParms.BackBufferHeight; ++j) {
2086 /*memcpy(lockedRect.pBits + (j * lockedRect.Pitch), This->frontBuffer->allocatedMemory + (j * i), i);*/
2087 glReadPixels(0, This->PresentParms.BackBufferHeight - j - 1, This->PresentParms.BackBufferWidth, 1,
2088 GL_BGRA, GL_UNSIGNED_BYTE, ((char*) lockedRect.pBits) + (j * lockedRect.Pitch));
2089 vcheckGLcall("glReadPixels");
2093 glReadPixels(0, 0, This->PresentParms.BackBufferWidth, This->PresentParms.BackBufferHeight,
2094 GL_BGRA, GL_UNSIGNED_BYTE, lockedRect.pBits);
2096 glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
2097 vcheckGLcall("glPixelStorei");
2098 glReadBuffer(prev_read);
2099 vcheckGLcall("glReadBuffer");
2103 hr = IDirect3DSurface8Impl_UnlockRect(pDestSurface);
2106 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
2107 ICOM_THIS(IDirect3DDevice8Impl,iface);
2109 if ((IDirect3DSurface8Impl*) pRenderTarget == This->frontBuffer && (IDirect3DSurface8Impl*) pNewZStencil == This->depthStencilBuffer) {
2110 TRACE("Trying to do a NOP SetRenderTarget operation\n");
2114 FIXME("(%p) : invalid stub expect crash newRender@%p newZStencil@%p\n", This, pRenderTarget, pNewZStencil);
2118 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
2119 ICOM_THIS(IDirect3DDevice8Impl,iface);
2121 TRACE("(%p)->(%p)\n", This, This->frontBuffer);
2123 *ppRenderTarget = (LPDIRECT3DSURFACE8) This->frontBuffer;
2124 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
2128 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
2129 ICOM_THIS(IDirect3DDevice8Impl,iface);
2131 TRACE("(%p)->(%p)\n", This, ppZStencilSurface);
2133 /* Note inc ref on returned surface */
2134 *ppZStencilSurface = (LPDIRECT3DSURFACE8) This->depthStencilBuffer;
2135 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppZStencilSurface);
2140 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
2141 ICOM_THIS(IDirect3DDevice8Impl,iface);
2142 TRACE("(%p) : stub\n", This);
2145 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
2146 ICOM_THIS(IDirect3DDevice8Impl,iface);
2147 TRACE("(%p)\n", This);
2152 checkGLcall("glFlush");
2154 /* Useful for debugging sometimes!
2155 printf("Hit Enter ...\n");
2161 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
2162 ICOM_THIS(IDirect3DDevice8Impl,iface);
2164 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
2165 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
2166 when the depth-buffer format does not contain stencil buffer information, this method fails. */
2167 GLbitfield glMask = 0;
2168 GLboolean old_ztest;
2169 GLfloat old_z_clear_value;
2170 GLint old_stencil_clear_value;
2171 GLfloat old_color_clear_value[4];
2173 CONST D3DRECT* curRect;
2175 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
2176 Count, pRects, Flags, Z, Stencil);
2179 if (Count > 0 && pRects) {
2180 glEnable(GL_SCISSOR_TEST);
2181 checkGLcall("glEnable GL_SCISSOR_TEST");
2187 for (i = 0; i < Count || i == 0; i++) {
2190 /* Note gl uses lower left, width/height */
2191 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
2192 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
2193 curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2),
2194 curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
2195 glScissor(curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2),
2196 curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
2197 checkGLcall("glScissor");
2200 /* Clear the whole screen */
2201 if (Flags & D3DCLEAR_STENCIL) {
2202 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
2203 glClearStencil(Stencil);
2204 checkGLcall("glClearStencil");
2205 glMask = glMask | GL_STENCIL_BUFFER_BIT;
2208 if (Flags & D3DCLEAR_ZBUFFER) {
2209 glGetBooleanv(GL_DEPTH_WRITEMASK, &old_ztest);
2210 glDepthMask(GL_TRUE);
2211 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
2213 checkGLcall("glClearDepth");
2214 glMask = glMask | GL_DEPTH_BUFFER_BIT;
2217 if (Flags & D3DCLEAR_TARGET) {
2218 TRACE("Clearing screen with glClear to color %lx\n", Color);
2219 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
2220 glClearColor(((Color >> 16) & 0xFF) / 255.0,
2221 ((Color >> 8) & 0xFF) / 255.0,
2222 ((Color >> 0) & 0xFF) / 255.0,
2223 ((Color >> 24) & 0xFF) / 255.0);
2224 checkGLcall("glClearColor");
2225 glMask = glMask | GL_COLOR_BUFFER_BIT;
2229 checkGLcall("glClear");
2231 if (Flags & D3DCLEAR_STENCIL) {
2232 glClearStencil(old_stencil_clear_value);
2234 if (Flags & D3DCLEAR_ZBUFFER) {
2235 glDepthMask(old_ztest);
2236 glClearDepth(old_z_clear_value);
2238 if (Flags & D3DCLEAR_TARGET) {
2239 glClearColor(old_color_clear_value[0],
2240 old_color_clear_value[1],
2241 old_color_clear_value[2],
2242 old_color_clear_value[3]);
2245 if (curRect) curRect = curRect + sizeof(D3DRECT);
2248 if (Count > 0 && pRects) {
2249 glDisable(GL_SCISSOR_TEST);
2250 checkGLcall("glDisable");
2256 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts, CONST D3DMATRIX* lpmatrix) {
2257 ICOM_THIS(IDirect3DDevice8Impl,iface);
2261 BOOL viewChanged = TRUE;
2264 /* Most of this routine, comments included copied from ddraw tree initially: */
2265 TRACE("(%p) : State=%d\n", This, d3dts);
2267 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
2268 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
2269 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
2271 /* Handle recording of state blocks */
2272 if (This->isRecordingState) {
2273 TRACE("Recording... not performing anything\n");
2278 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
2280 where ViewMat = Camera space, WorldMat = world space.
2282 In OpenGL, camera and world space is combined into GL_MODELVIEW
2283 matrix. The Projection matrix stay projection matrix. */
2285 /* After reading through both OpenGL and Direct3D documentations, I
2286 thought that D3D matrices were written in 'line major mode' transposed
2287 from OpenGL's 'column major mode'. But I found out that a simple memcpy
2288 works fine to transfer one matrix format to the other (it did not work
2289 when transposing)....
2292 1) are the documentations wrong
2293 2) does the matrix work even if they are not read correctly
2294 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
2295 loading using glLoadMatrix ?
2297 Anyway, I always use 'conv_mat' to transfer the matrices from one format
2298 to the other so that if I ever find out that I need to transpose them, I
2299 will able to do it quickly, only by changing the macro conv_mat. */
2304 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_VIEW]);
2307 case D3DTS_PROJECTION:
2308 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_PROJECTION]);
2311 case D3DTS_TEXTURE0:
2312 case D3DTS_TEXTURE1:
2313 case D3DTS_TEXTURE2:
2314 case D3DTS_TEXTURE3:
2315 case D3DTS_TEXTURE4:
2316 case D3DTS_TEXTURE5:
2317 case D3DTS_TEXTURE6:
2318 case D3DTS_TEXTURE7:
2319 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
2323 FIXME("Unhandled transform state!!\n");
2328 * Indexed Vertex Blending Matrices 256 -> 511
2329 * where WORLDMATRIX(0) == 256!
2332 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
2333 if (checkGLSupport(ARB_VERTEX_BLEND)) {
2335 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
2341 * Move the GL operation to outside of switch to make it work
2342 * regardless of transform set order.
2345 if (memcmp(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX))) {
2346 glMatrixMode(GL_PROJECTION);
2347 checkGLcall("glMatrixMode");
2348 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
2349 checkGLcall("glLoadMatrixf");
2350 memcpy(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX));
2352 TRACE("Skipping as projection already correct\n");
2355 glMatrixMode(GL_MODELVIEW);
2356 checkGLcall("glMatrixMode");
2357 viewChanged = FALSE;
2358 if (memcmp(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX))) {
2359 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2360 checkGLcall("glLoadMatrixf");
2361 memcpy(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX));
2364 /* If we are changing the View matrix, reset the light and clipping planes to the new view */
2365 if (d3dts == D3DTS_VIEW) {
2367 /* NOTE: We have to reset the positions even if the light/plane is not currently
2368 enabled, since the call to enable it will not reset the position. */
2371 for (k = 0; k < This->maxLights; k++) {
2372 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
2373 checkGLcall("glLightfv posn");
2374 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
2375 checkGLcall("glLightfv dirn");
2378 /* Reset Clipping Planes if clipping is enabled */
2379 for (k = 0; k < This->clipPlanes; k++) {
2380 glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
2381 checkGLcall("glClipPlane");
2384 /* Reapply texture transforms as based off modelview when applied */
2385 for (Stage = 0; Stage < This->TextureUnits; Stage++) {
2387 /* Only applicable if the transforms are not disabled */
2388 if (This->UpdateStateBlock->texture_state[Stage][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)
2390 /* Now apply texture transforms if not applying to the dummy textures */
2391 #if defined(GL_VERSION_1_3)
2392 glActiveTexture(GL_TEXTURE0 + Stage);
2394 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2396 checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage);");
2398 glMatrixMode(GL_TEXTURE);
2399 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
2403 conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
2404 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
2407 checkGLcall("Load matrix for texture");
2409 glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
2411 } else if ((d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) &&
2412 (This->UpdateStateBlock->texture_state[d3dts - D3DTS_TEXTURE0][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE)) {
2413 /* Now apply texture transforms if not applying to the dummy textures */
2414 Stage = d3dts - D3DTS_TEXTURE0;
2416 if (memcmp(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], sizeof(D3DMATRIX))) {
2417 memcpy(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], sizeof(D3DMATRIX));
2419 #if defined(GL_VERSION_1_3)
2420 glActiveTexture(GL_TEXTURE0 + Stage);
2422 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2424 checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage)");
2426 glMatrixMode(GL_TEXTURE);
2427 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
2431 conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
2432 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
2434 checkGLcall("Load matrix for texture");
2435 glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
2437 TRACE("Skipping texture transform as already correct\n");
2441 TRACE("Skipping view setup as view already correct\n");
2445 * Vertex Blending as described
2446 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/enums/d3dvertexblendflags.asp
2448 switch (This->UpdateStateBlock->vertex_blend) {
2449 case D3DVBF_DISABLE:
2451 if (viewChanged == TRUE ||
2452 (memcmp(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX)))) {
2453 memcpy(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX));
2454 if (viewChanged == FALSE) {
2455 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2456 checkGLcall("glLoadMatrixf");
2458 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
2459 checkGLcall("glMultMatrixf");
2461 TRACE("Skipping as world already correct\n");
2465 case D3DVBF_1WEIGHTS:
2466 case D3DVBF_2WEIGHTS:
2467 case D3DVBF_3WEIGHTS:
2469 FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n");
2471 * doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*)
2472 * so waiting for the values before matrix work
2473 for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
2474 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
2475 checkGLcall("glMultMatrixf");
2480 case D3DVBF_TWEENING:
2482 FIXME("valid/correct D3DVBF_TWEENING\n");
2483 f = This->UpdateStateBlock->tween_factor;
2484 m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f;
2485 m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f;
2486 m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f;
2487 m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
2488 if (viewChanged == FALSE) {
2489 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2490 checkGLcall("glLoadMatrixf");
2492 glMultMatrixf((float *) &m.u.m[0][0]);
2493 checkGLcall("glMultMatrixf");
2496 case D3DVBF_0WEIGHTS:
2498 FIXME("valid/correct D3DVBF_0WEIGHTS\n");
2499 /* single matrix of weight 1.0f */
2500 m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f;
2501 m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f;
2502 m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f;
2503 m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
2504 if (viewChanged == FALSE) {
2505 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2506 checkGLcall("glLoadMatrixf");
2508 glMultMatrixf((float *) &m.u.m[0][0]);
2509 checkGLcall("glMultMatrixf");
2513 break; /* stupid compilator */
2521 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
2522 ICOM_THIS(IDirect3DDevice8Impl,iface);
2523 TRACE("(%p) : for State %d\n", This, State);
2524 memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX));
2528 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
2529 D3DMATRIX *mat = NULL;
2532 /* Note: Using UpdateStateBlock means it would be recorded in a state block change,
2533 but works regardless of recording being on.
2534 If this is found to be wrong, change to StateBlock. */
2535 ICOM_THIS(IDirect3DDevice8Impl,iface);
2536 TRACE("(%p) : For state %u\n", This, State);
2538 if (State < HIGHEST_TRANSFORMSTATE)
2540 mat = &This->UpdateStateBlock->transforms[State];
2542 FIXME("Unhandled transform state!!\n");
2545 /* Copied from ddraw code: */
2546 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);
2547 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);
2548 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);
2549 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);
2551 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);
2552 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);
2553 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);
2554 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);
2556 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);
2557 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);
2558 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);
2559 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);
2561 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);
2562 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);
2563 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);
2564 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);
2566 /* Apply change via set transform - will reapply to eg. lights this way */
2567 IDirect3DDevice8Impl_SetTransform(iface, State, &temp);
2570 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
2571 ICOM_THIS(IDirect3DDevice8Impl,iface);
2573 TRACE("(%p)\n", This);
2574 This->UpdateStateBlock->Changed.viewport = TRUE;
2575 This->UpdateStateBlock->Set.viewport = TRUE;
2576 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
2578 /* Handle recording of state blocks */
2579 if (This->isRecordingState) {
2580 TRACE("Recording... not performing anything\n");
2584 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
2585 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
2587 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
2588 checkGLcall("glDepthRange");
2589 /* Note: GL requires lower left, DirectX supplies upper left */
2590 glViewport(pViewport->X, (This->PresentParms.BackBufferHeight - (pViewport->Y + pViewport->Height)),
2591 pViewport->Width, pViewport->Height);
2592 checkGLcall("glViewport");
2598 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
2599 ICOM_THIS(IDirect3DDevice8Impl,iface);
2600 TRACE("(%p)\n", This);
2601 memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8));
2605 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
2606 ICOM_THIS(IDirect3DDevice8Impl,iface);
2608 This->UpdateStateBlock->Changed.material = TRUE;
2609 This->UpdateStateBlock->Set.material = TRUE;
2610 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
2612 /* Handle recording of state blocks */
2613 if (This->isRecordingState) {
2614 TRACE("Recording... not performing anything\n");
2619 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
2620 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
2621 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
2622 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
2623 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
2625 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->UpdateStateBlock->material.Ambient);
2626 checkGLcall("glMaterialfv");
2627 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->UpdateStateBlock->material.Diffuse);
2628 checkGLcall("glMaterialfv");
2630 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular);
2631 checkGLcall("glMaterialfv");
2632 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->UpdateStateBlock->material.Emissive);
2633 checkGLcall("glMaterialfv");
2634 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
2635 checkGLcall("glMaterialf");
2640 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
2641 ICOM_THIS(IDirect3DDevice8Impl,iface);
2642 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
2643 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
2644 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
2645 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
2646 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
2647 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
2651 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) {
2652 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
2656 ICOM_THIS(IDirect3DDevice8Impl,iface);
2657 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2659 if (Index >= This->maxLights) {
2660 TRACE("Cannot handle more lights than device supports\n");
2661 return D3DERR_INVALIDCALL;
2664 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,
2665 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
2666 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
2667 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
2668 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
2669 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
2670 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
2672 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
2673 This->UpdateStateBlock->Set.lights[Index] = TRUE;
2674 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
2676 /* Handle recording of state blocks */
2677 if (This->isRecordingState) {
2678 TRACE("Recording... not performing anything\n");
2683 colRGBA[0] = pLight->Diffuse.r;
2684 colRGBA[1] = pLight->Diffuse.g;
2685 colRGBA[2] = pLight->Diffuse.b;
2686 colRGBA[3] = pLight->Diffuse.a;
2687 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
2688 checkGLcall("glLightfv");
2691 colRGBA[0] = pLight->Specular.r;
2692 colRGBA[1] = pLight->Specular.g;
2693 colRGBA[2] = pLight->Specular.b;
2694 colRGBA[3] = pLight->Specular.a;
2695 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
2696 checkGLcall("glLightfv");
2699 colRGBA[0] = pLight->Ambient.r;
2700 colRGBA[1] = pLight->Ambient.g;
2701 colRGBA[2] = pLight->Ambient.b;
2702 colRGBA[3] = pLight->Ambient.a;
2703 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
2704 checkGLcall("glLightfv");
2706 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2707 glMatrixMode(GL_MODELVIEW);
2709 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2711 /* Attenuation - Are these right? guessing... */
2712 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
2713 checkGLcall("glLightf");
2714 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
2715 checkGLcall("glLightf");
2717 quad_att = 1.4/(pLight->Range*pLight->Range);
2718 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
2719 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
2720 checkGLcall("glLightf");
2722 switch (pLight->Type) {
2723 case D3DLIGHT_POINT:
2725 This->lightPosn[Index][0] = pLight->Position.x;
2726 This->lightPosn[Index][1] = pLight->Position.y;
2727 This->lightPosn[Index][2] = pLight->Position.z;
2728 This->lightPosn[Index][3] = 1.0;
2729 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2730 checkGLcall("glLightfv");
2732 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
2733 checkGLcall("glLightf");
2740 This->lightPosn[Index][0] = pLight->Position.x;
2741 This->lightPosn[Index][1] = pLight->Position.y;
2742 This->lightPosn[Index][2] = pLight->Position.z;
2743 This->lightPosn[Index][3] = 1.0;
2744 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2745 checkGLcall("glLightfv");
2748 This->lightDirn[Index][0] = pLight->Direction.x;
2749 This->lightDirn[Index][1] = pLight->Direction.y;
2750 This->lightDirn[Index][2] = pLight->Direction.z;
2751 This->lightDirn[Index][3] = 1.0;
2752 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
2753 checkGLcall("glLightfv");
2756 * opengl-ish and d3d-ish spot lights use too different models for the
2757 * light "intensity" as a function of the angle towards the main light direction,
2758 * so we only can approximate very roughly.
2759 * however spot lights are rather rarely used in games (if ever used at all).
2760 * furthermore if still used, probably nobody pays attention to such details.
2762 if (pLight->Falloff == 0) {
2765 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
2767 if (rho < 0.0001) rho = 0.0001f;
2768 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
2769 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
2773 case D3DLIGHT_DIRECTIONAL:
2775 This->lightPosn[Index][0] = -pLight->Direction.x;
2776 This->lightPosn[Index][1] = -pLight->Direction.y;
2777 This->lightPosn[Index][2] = -pLight->Direction.z;
2778 This->lightPosn[Index][3] = 0.0;
2779 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
2780 checkGLcall("glLightfv");
2782 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
2783 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
2788 FIXME("Unrecognized light type %d\n", pLight->Type);
2791 /* Restore the modelview matrix */
2796 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
2797 ICOM_THIS(IDirect3DDevice8Impl,iface);
2798 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2800 if (Index >= This->maxLights) {
2801 TRACE("Cannot handle more lights than device supports\n");
2802 return D3DERR_INVALIDCALL;
2805 memcpy(pLight, &This->StateBlock->lights[Index], sizeof(D3DLIGHT8));
2808 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
2809 ICOM_THIS(IDirect3DDevice8Impl,iface);
2810 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
2812 if (Index >= This->maxLights) {
2813 TRACE("Cannot handle more lights than device supports\n");
2814 return D3DERR_INVALIDCALL;
2817 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
2818 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
2819 This->UpdateStateBlock->lightEnable[Index] = Enable;
2821 /* Handle recording of state blocks */
2822 if (This->isRecordingState) {
2823 TRACE("Recording... not performing anything\n");
2828 glEnable(GL_LIGHT0 + Index);
2829 checkGLcall("glEnable GL_LIGHT0+Index");
2831 glDisable(GL_LIGHT0 + Index);
2832 checkGLcall("glDisable GL_LIGHT0+Index");
2836 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
2837 ICOM_THIS(IDirect3DDevice8Impl,iface);
2838 TRACE("(%p) : for idx(%ld)\n", This, Index);
2840 if (Index >= This->maxLights) {
2841 TRACE("Cannot handle more lights than device supports\n");
2842 return D3DERR_INVALIDCALL;
2845 *pEnable = This->StateBlock->lightEnable[Index];
2848 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
2849 ICOM_THIS(IDirect3DDevice8Impl,iface);
2850 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
2852 /* Validate Index */
2853 if (Index >= This->clipPlanes ) {
2854 TRACE("Application has requested clipplane this device doesnt support\n");
2855 return D3DERR_INVALIDCALL;
2858 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
2859 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
2860 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
2861 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
2862 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
2863 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
2865 /* Handle recording of state blocks */
2866 if (This->isRecordingState) {
2867 TRACE("Recording... not performing anything\n");
2873 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2874 glMatrixMode(GL_MODELVIEW);
2876 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2878 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
2879 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
2880 glClipPlane(GL_CLIP_PLANE0 + Index, This->UpdateStateBlock->clipplane[Index]);
2883 checkGLcall("glClipPlane");
2887 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
2888 ICOM_THIS(IDirect3DDevice8Impl,iface);
2889 TRACE("(%p) : for idx %ld\n", This, Index);
2891 /* Validate Index */
2892 if (Index >= This->clipPlanes ) {
2893 TRACE("Application has requested clipplane this device doesnt support\n");
2894 return D3DERR_INVALIDCALL;
2897 pPlane[0] = This->StateBlock->clipplane[Index][0];
2898 pPlane[1] = This->StateBlock->clipplane[Index][0];
2899 pPlane[2] = This->StateBlock->clipplane[Index][0];
2900 pPlane[3] = This->StateBlock->clipplane[Index][0];
2903 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
2904 ICOM_THIS(IDirect3DDevice8Impl,iface);
2905 DWORD OldValue = This->StateBlock->renderstate[State];
2907 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
2908 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2909 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2910 This->UpdateStateBlock->renderstate[State] = Value;
2912 /* Handle recording of state blocks */
2913 if (This->isRecordingState) {
2914 TRACE("Recording... not performing anything\n");
2919 case D3DRS_FILLMODE :
2920 switch ((D3DFILLMODE) Value) {
2921 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2922 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2923 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2925 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2927 checkGLcall("glPolygonMode (fillmode)");
2930 case D3DRS_LIGHTING :
2932 glEnable(GL_LIGHTING);
2933 checkGLcall("glEnable GL_LIGHTING");
2935 glDisable(GL_LIGHTING);
2936 checkGLcall("glDisable GL_LIGHTING");
2940 case D3DRS_ZENABLE :
2941 switch ((D3DZBUFFERTYPE) Value) {
2943 glDisable(GL_DEPTH_TEST);
2944 checkGLcall("glDisable GL_DEPTH_TEST");
2947 glEnable(GL_DEPTH_TEST);
2948 checkGLcall("glEnable GL_DEPTH_TEST");
2953 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2957 case D3DRS_CULLMODE :
2959 /* If we are culling "back faces with clockwise vertices" then
2960 set front faces to be counter clockwise and enable culling
2962 switch ((D3DCULL) Value) {
2964 glDisable(GL_CULL_FACE);
2965 checkGLcall("glDisable GL_CULL_FACE");
2968 glEnable(GL_CULL_FACE);
2969 checkGLcall("glEnable GL_CULL_FACE");
2970 glFrontFace(GL_CCW);
2971 checkGLcall("glFrontFace GL_CCW");
2972 glCullFace(GL_BACK);
2975 glEnable(GL_CULL_FACE);
2976 checkGLcall("glEnable GL_CULL_FACE");
2978 checkGLcall("glFrontFace GL_CW");
2979 glCullFace(GL_BACK);
2982 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2986 case D3DRS_SHADEMODE :
2987 switch ((D3DSHADEMODE) Value) {
2989 glShadeModel(GL_FLAT);
2990 checkGLcall("glShadeModel");
2992 case D3DSHADE_GOURAUD:
2993 glShadeModel(GL_SMOOTH);
2994 checkGLcall("glShadeModel");
2996 case D3DSHADE_PHONG:
2997 FIXME("D3DSHADE_PHONG isnt supported?\n");
2998 return D3DERR_INVALIDCALL;
3000 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
3004 case D3DRS_DITHERENABLE :
3006 glEnable(GL_DITHER);
3007 checkGLcall("glEnable GL_DITHER");
3009 glDisable(GL_DITHER);
3010 checkGLcall("glDisable GL_DITHER");
3014 case D3DRS_ZWRITEENABLE :
3017 checkGLcall("glDepthMask");
3020 checkGLcall("glDepthMask");
3026 int glParm = GL_LESS;
3028 switch ((D3DCMPFUNC) Value) {
3029 case D3DCMP_NEVER: glParm=GL_NEVER; break;
3030 case D3DCMP_LESS: glParm=GL_LESS; break;
3031 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
3032 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
3033 case D3DCMP_GREATER: glParm=GL_GREATER; break;
3034 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
3035 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
3036 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
3038 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
3040 glDepthFunc(glParm);
3041 checkGLcall("glDepthFunc");
3045 case D3DRS_AMBIENT :
3049 col[0] = ((Value >> 16) & 0xFF) / 255.0;
3050 col[1] = ((Value >> 8) & 0xFF) / 255.0;
3051 col[2] = ((Value >> 0) & 0xFF) / 255.0;
3052 col[3] = ((Value >> 24) & 0xFF) / 255.0;
3054 D3DCOLORTOGLFLOAT4(Value, col);
3055 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
3056 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
3057 checkGLcall("glLightModel for MODEL_AMBIENT");
3062 case D3DRS_ALPHABLENDENABLE :
3065 checkGLcall("glEnable GL_BLEND");
3067 glDisable(GL_BLEND);
3068 checkGLcall("glDisable GL_BLEND");
3072 case D3DRS_SRCBLEND :
3073 case D3DRS_DESTBLEND :
3075 int newVal = GL_ZERO;
3077 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
3078 case D3DBLEND_ONE : newVal = GL_ONE; break;
3079 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
3080 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
3081 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
3082 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
3083 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
3084 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
3085 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
3086 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
3087 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
3089 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
3090 This->srcBlend = newVal;
3091 This->dstBlend = newVal;
3094 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
3095 This->srcBlend = newVal;
3096 This->dstBlend = newVal;
3099 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
3102 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
3103 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
3104 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
3105 glBlendFunc(This->srcBlend, This->dstBlend);
3107 checkGLcall("glBlendFunc");
3111 case D3DRS_ALPHATESTENABLE :
3113 glEnable(GL_ALPHA_TEST);
3114 checkGLcall("glEnable GL_ALPHA_TEST");
3116 glDisable(GL_ALPHA_TEST);
3117 checkGLcall("glDisable GL_ALPHA_TEST");
3121 case D3DRS_ALPHAFUNC :
3123 int glParm = GL_LESS;
3126 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
3127 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
3129 switch ((D3DCMPFUNC) Value) {
3130 case D3DCMP_NEVER: glParm=GL_NEVER; break;
3131 case D3DCMP_LESS: glParm=GL_LESS; break;
3132 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
3133 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
3134 case D3DCMP_GREATER: glParm=GL_GREATER; break;
3135 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
3136 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
3137 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
3139 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
3141 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
3142 glAlphaFunc(glParm, ref);
3143 checkGLcall("glAlphaFunc");
3147 case D3DRS_ALPHAREF :
3149 int glParm = GL_LESS;
3152 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
3153 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
3155 ref = ((float) Value) / 255.0f;
3156 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
3157 glAlphaFunc(glParm, ref);
3158 checkGLcall("glAlphaFunc");
3162 case D3DRS_CLIPPLANEENABLE :
3163 case D3DRS_CLIPPING :
3165 /* Ensure we only do the changed clip planes */
3166 DWORD enable = 0xFFFFFFFF;
3167 DWORD disable = 0x00000000;
3169 /* If enabling / disabling all */
3170 if (State == D3DRS_CLIPPING) {
3172 enable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
3175 disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
3179 enable = Value & ~OldValue;
3180 disable = ~Value & OldValue;
3183 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
3184 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
3185 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
3186 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
3187 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
3188 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
3190 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
3191 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
3192 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
3193 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
3194 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
3195 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
3199 case D3DRS_BLENDOP :
3201 int glParm = GL_FUNC_ADD;
3203 switch ((D3DBLENDOP) Value) {
3204 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
3205 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
3206 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
3207 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
3208 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
3210 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
3212 TRACE("glBlendEquation(%x)\n", glParm);
3213 glBlendEquation(glParm);
3214 checkGLcall("glBlendEquation");
3218 case D3DRS_TEXTUREFACTOR :
3222 /* Note the texture color applies to all textures whereas
3223 GL_TEXTURE_ENV_COLOR applies to active only */
3226 col[0] = ((Value >> 16) & 0xFF) / 255.0f;
3227 col[1] = ((Value >> 8) & 0xFF) / 255.0f;
3228 col[2] = ((Value >> 0) & 0xFF) / 255.0f;
3229 col[3] = ((Value >> 24) & 0xFF) / 255.0f;
3231 D3DCOLORTOGLFLOAT4(Value, col);
3232 /* Set the default alpha blend color */
3233 glBlendColor(col[0], col[1], col[2], col[3]);
3234 checkGLcall("glBlendColor");
3236 /* And now the default texture color as well */
3237 for (i = 0; i < This->TextureUnits; i++) {
3239 /* Note the D3DRS value applies to all textures, but GL has one
3240 per texture, so apply it now ready to be used! */
3241 if (This->isMultiTexture) {
3242 #if defined(GL_VERSION_1_3)
3243 glActiveTexture(GL_TEXTURE0 + i);
3245 glActiveTextureARB(GL_TEXTURE0_ARB + i);
3247 checkGLcall("Activate texture.. to update const color");
3249 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3252 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
3253 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
3258 case D3DRS_SPECULARENABLE :
3261 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
3262 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
3264 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
3265 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
3270 case D3DRS_STENCILENABLE :
3272 glEnable(GL_STENCIL_TEST);
3273 checkGLcall("glEnable GL_STENCIL_TEST");
3275 glDisable(GL_STENCIL_TEST);
3276 checkGLcall("glDisable GL_STENCIL_TEST");
3280 case D3DRS_STENCILFUNC :
3282 int glParm = GL_ALWAYS;
3284 GLuint mask = 0xFFFFFFFF;
3286 glGetIntegerv(GL_STENCIL_REF, &ref);
3287 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
3288 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
3289 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
3291 switch ((D3DCMPFUNC) Value) {
3292 case D3DCMP_NEVER: glParm=GL_NEVER; break;
3293 case D3DCMP_LESS: glParm=GL_LESS; break;
3294 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
3295 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
3296 case D3DCMP_GREATER: glParm=GL_GREATER; break;
3297 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
3298 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
3299 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
3301 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
3303 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3304 glStencilFunc(glParm, ref, mask);
3305 checkGLcall("glStencilFunc");
3309 case D3DRS_STENCILREF :
3311 int glParm = GL_ALWAYS;
3313 GLuint mask = 0xFFFFFFFF;
3315 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
3316 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
3317 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
3318 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
3321 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3322 glStencilFunc(glParm, ref, mask);
3323 checkGLcall("glStencilFunc");
3327 case D3DRS_STENCILMASK :
3329 int glParm = GL_ALWAYS;
3331 GLuint mask = Value;
3333 glGetIntegerv(GL_STENCIL_REF, &ref);
3334 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
3335 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
3336 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
3338 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3339 glStencilFunc(glParm, ref, mask);
3340 checkGLcall("glStencilFunc");
3344 case D3DRS_STENCILFAIL :
3350 fail = StencilOp(Value);
3351 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
3352 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
3353 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
3354 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
3356 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3357 glStencilOp(fail, zfail, zpass);
3358 checkGLcall("glStencilOp(fail, zfail, zpass);");
3361 case D3DRS_STENCILZFAIL :
3367 glGetIntegerv(GL_STENCIL_FAIL, &fail);
3368 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
3369 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
3370 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
3371 zfail = StencilOp(Value);
3373 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3374 glStencilOp(fail, zfail, zpass);
3375 checkGLcall("glStencilOp(fail, zfail, zpass);");
3378 case D3DRS_STENCILPASS :
3384 glGetIntegerv(GL_STENCIL_FAIL, &fail);
3385 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
3386 zpass = StencilOp(Value);
3387 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
3388 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
3390 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3391 glStencilOp(fail, zfail, zpass);
3392 checkGLcall("glStencilOp(fail, zfail, zpass);");
3396 case D3DRS_STENCILWRITEMASK :
3398 glStencilMask(Value);
3399 TRACE("glStencilMask(%lu)\n", Value);
3400 checkGLcall("glStencilMask");
3404 case D3DRS_FOGENABLE :
3406 if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
3408 checkGLcall("glEnable GL_FOG\n");
3411 checkGLcall("glDisable GL_FOG\n");
3416 case D3DRS_FOGCOLOR :
3420 col[0] = ((Value >> 16) & 0xFF) / 255.0f;
3421 col[1] = ((Value >> 8) & 0xFF) / 255.0f;
3422 col[2] = ((Value >> 0) & 0xFF) / 255.0f;
3423 col[3] = ((Value >> 24) & 0xFF) / 255.0f;
3425 D3DCOLORTOGLFLOAT4(Value, col);
3426 /* Set the default alpha blend color */
3427 glFogfv(GL_FOG_COLOR, &col[0]);
3428 checkGLcall("glFog GL_FOG_COLOR");
3432 case D3DRS_FOGTABLEMODE :
3435 case D3DFOG_NONE: /* I don't know what to do here */ break;
3436 case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
3437 case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
3438 case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
3440 FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value);
3445 case D3DRS_FOGSTART :
3447 float *f = (float*) &Value;
3448 glFogfv(GL_FOG_START, f);
3449 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
3450 TRACE("Fog Start == %f\n", *f);
3456 float *f = (float*) &Value;
3457 glFogfv(GL_FOG_END, f);
3458 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
3459 TRACE("Fog End == %f\n", *f);
3463 case D3DRS_FOGDENSITY :
3465 glFogf(GL_FOG_DENSITY, (float) Value);
3466 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
3470 case D3DRS_VERTEXBLEND :
3472 This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
3473 TRACE("Vertex Blending state to %ld\n", Value);
3477 case D3DRS_TWEENFACTOR :
3479 This->UpdateStateBlock->tween_factor = *((float*) &Value);
3480 TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
3484 case D3DRS_INDEXEDVERTEXBLENDENABLE :
3486 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
3491 case D3DRS_COLORVERTEX :
3492 case D3DRS_DIFFUSEMATERIALSOURCE :
3493 case D3DRS_SPECULARMATERIALSOURCE :
3494 case D3DRS_AMBIENTMATERIALSOURCE :
3495 case D3DRS_EMISSIVEMATERIALSOURCE :
3497 GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
3499 if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
3500 glEnable(GL_COLOR_MATERIAL);
3501 checkGLcall("glEnable GL_GL_COLOR_MATERIAL\n");
3503 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
3504 This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
3505 This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
3506 This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE],
3507 This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]);
3509 if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
3510 if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
3511 Parm = GL_AMBIENT_AND_DIFFUSE;
3515 } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
3517 } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
3519 } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
3526 glDisable(GL_COLOR_MATERIAL);
3527 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
3529 TRACE("glColorMaterial Parm=%d\n", Parm);
3530 glColorMaterial(GL_FRONT_AND_BACK, Parm);
3531 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)\n");
3535 glDisable(GL_COLOR_MATERIAL);
3536 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
3541 /* Unhandled yet...! */
3542 case D3DRS_LINEPATTERN :
3543 case D3DRS_LASTPIXEL :
3544 case D3DRS_ZVISIBLE :
3545 case D3DRS_EDGEANTIALIAS :
3547 case D3DRS_RANGEFOGENABLE :
3556 case D3DRS_FOGVERTEXMODE :
3557 case D3DRS_LOCALVIEWER :
3558 case D3DRS_NORMALIZENORMALS :
3559 case D3DRS_SOFTWAREVERTEXPROCESSING :
3560 case D3DRS_POINTSIZE :
3561 case D3DRS_POINTSIZE_MIN :
3562 case D3DRS_POINTSPRITEENABLE :
3563 case D3DRS_POINTSCALEENABLE :
3564 case D3DRS_POINTSCALE_A :
3565 case D3DRS_POINTSCALE_B :
3566 case D3DRS_POINTSCALE_C :
3567 case D3DRS_MULTISAMPLEANTIALIAS :
3568 case D3DRS_MULTISAMPLEMASK :
3569 case D3DRS_PATCHEDGESTYLE :
3570 case D3DRS_PATCHSEGMENTS :
3571 case D3DRS_DEBUGMONITORTOKEN :
3572 case D3DRS_POINTSIZE_MAX :
3573 case D3DRS_COLORWRITEENABLE :
3574 case D3DRS_POSITIONORDER :
3575 case D3DRS_NORMALORDER :
3576 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
3577 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
3580 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
3585 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
3586 ICOM_THIS(IDirect3DDevice8Impl,iface);
3587 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
3588 *pValue = This->StateBlock->renderstate[State];
3591 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
3592 ICOM_THIS(IDirect3DDevice8Impl,iface);
3594 TRACE("(%p)\n", This);
3596 return IDirect3DDeviceImpl_BeginStateBlock(This);
3598 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
3599 IDirect3DStateBlockImpl* pSB;
3600 ICOM_THIS(IDirect3DDevice8Impl,iface);
3603 TRACE("(%p)\n", This);
3605 res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB);
3606 *pToken = (DWORD) pSB;
3610 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3611 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3612 ICOM_THIS(IDirect3DDevice8Impl,iface);
3614 TRACE("(%p)\n", This);
3616 return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB);
3619 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3620 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3621 ICOM_THIS(IDirect3DDevice8Impl,iface);
3623 TRACE("(%p)\n", This);
3625 return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB);
3627 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3628 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3629 ICOM_THIS(IDirect3DDevice8Impl,iface);
3631 TRACE("(%p)\n", This);
3633 return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB);
3636 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
3637 IDirect3DStateBlockImpl* pSB;
3638 ICOM_THIS(IDirect3DDevice8Impl,iface);
3641 TRACE("(%p) : for type %d\n", This, Type);
3643 res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB);
3644 *pToken = (DWORD) pSB;
3648 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
3649 ICOM_THIS(IDirect3DDevice8Impl,iface);
3650 FIXME("(%p) : stub\n", This); return D3D_OK;
3652 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
3653 ICOM_THIS(IDirect3DDevice8Impl,iface);
3654 FIXME("(%p) : stub\n", This); return D3D_OK;
3656 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
3657 ICOM_THIS(IDirect3DDevice8Impl,iface);
3658 TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage);
3659 *ppTexture = (LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage];
3660 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
3663 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
3665 IDirect3DBaseTexture8 *oldTxt;
3666 BOOL reapplyStates = TRUE;
3668 ICOM_THIS(IDirect3DDevice8Impl,iface);
3669 D3DRESOURCETYPE textureType;
3671 oldTxt = This->UpdateStateBlock->textures[Stage];
3672 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
3674 /* Reject invalid texture units */
3675 if (Stage >= This->TextureUnits) {
3676 TRACE("Attempt to access invalid texture rejected\n");
3677 return D3DERR_INVALIDCALL;
3680 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
3681 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
3682 This->UpdateStateBlock->textures[Stage] = pTexture;
3684 /* Handle recording of state blocks */
3685 if (This->isRecordingState) {
3686 TRACE("Recording... not performing anything\n");
3690 /* Make appropriate texture active */
3691 if (This->isMultiTexture) {
3692 #if defined(GL_VERSION_1_3)
3693 glActiveTexture(GL_TEXTURE0 + Stage);
3695 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3697 checkGLcall("glActiveTextureARB");
3698 } else if (Stage>0) {
3699 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3702 /* Decrement the count of the previous texture */
3703 if (oldTxt != NULL) {
3704 IDirect3DBaseTexture8Impl_Release(oldTxt);
3708 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]);
3710 /* Now setup the texture appropraitly */
3711 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
3713 if (textureType == D3DRTYPE_TEXTURE) {
3714 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl*) pTexture;
3716 if ((void*) oldTxt == (void*) pTexture2 && pTexture2->Dirty == FALSE) {
3717 TRACE("Skipping setting texture as old == new\n");
3718 reapplyStates = FALSE;
3721 /* Standard 2D texture */
3722 TRACE("Standard 2d texture\n");
3723 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D;
3725 /* Load up the texture now */
3726 IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture);
3728 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3730 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3734 /* Standard 3D (volume) texture */
3735 TRACE("Standard 3d texture\n");
3736 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
3738 /* Load up the texture now */
3739 IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture);
3742 for (i=0; i<pTexture2->levels; i++)
3745 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3746 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3747 checkGLcall("glBindTexture");
3748 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3750 /* No need to walk through all mip-map levels, since already all assigned */
3751 i = pTexture2->levels;
3755 if (pTexture2->volumes[i]->textureName == 0) {
3756 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3757 checkGLcall("glGenTextures");
3758 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3761 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3762 checkGLcall("glBindTexture");
3764 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3765 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3768 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3769 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3770 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3771 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3772 pTexture2->volumes[i]->allocatedMemory);
3773 glTexImage3D(GL_TEXTURE_3D, i,
3774 fmt2glintFmt(pTexture2->format),
3775 pTexture2->volumes[i]->myDesc.Width,
3776 pTexture2->volumes[i]->myDesc.Height,
3777 pTexture2->volumes[i]->myDesc.Depth,
3779 fmt2glFmt(pTexture2->format),
3780 fmt2glType(pTexture2->format),
3781 pTexture2->volumes[i]->allocatedMemory
3783 checkGLcall("glTexImage3D");
3785 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3786 pTexture2->Dirty = FALSE;
3791 } else if (textureType == D3DRTYPE_CUBETEXTURE) {
3792 /* Standard Cube texture */
3793 FIXME("Standard Cube texture\n");
3795 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_CUBE_MAP_ARB;
3797 /* Load up the texture now */
3798 IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture);
3800 FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType));
3803 TRACE("Setting to no texture (ie default texture)\n");
3804 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D;
3805 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3806 checkGLcall("glBindTexture");
3807 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3810 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3811 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3812 if (reapplyStates) {
3813 setupTextureStates (iface, Stage);
3819 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3820 ICOM_THIS(IDirect3DDevice8Impl,iface);
3821 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
3822 *pValue = This->UpdateStateBlock->texture_state[Stage][Type];
3826 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
3827 ICOM_THIS(IDirect3DDevice8Impl,iface);
3829 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3831 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value=%ld\n", This, Stage, Type, Value);
3833 /* Reject invalid texture units */
3834 if (Stage >= This->TextureUnits) {
3835 TRACE("Attempt to access invalid texture rejected\n");
3836 return D3DERR_INVALIDCALL;
3839 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3840 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3841 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3843 /* Handle recording of state blocks */
3844 if (This->isRecordingState) {
3845 TRACE("Recording... not performing anything\n");
3849 /* Make appropriate texture active */
3850 VTRACE(("Activating appropriate texture state %ld\n", Stage));
3851 if (This->isMultiTexture) {
3852 #if defined(GL_VERSION_1_3)
3853 glActiveTexture(GL_TEXTURE0 + Stage);
3854 vcheckGLcall("glActiveTexture");
3856 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3857 vcheckGLcall("glActiveTextureARB");
3859 } else if (Stage > 0) {
3860 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3865 case D3DTSS_MINFILTER :
3866 case D3DTSS_MIPFILTER :
3868 DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER];
3869 DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER];
3870 GLint realVal = GL_LINEAR;
3872 if (ValueMIN == D3DTEXF_POINT) {
3874 if (ValueMIP == D3DTEXF_POINT) {
3875 realVal = GL_NEAREST_MIPMAP_NEAREST;
3876 } else if (ValueMIP == D3DTEXF_LINEAR) {
3877 realVal = GL_NEAREST_MIPMAP_LINEAR;
3878 } else if (ValueMIP == D3DTEXF_NONE) {
3879 realVal = GL_NEAREST;
3881 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3882 realVal = GL_NEAREST_MIPMAP_LINEAR;
3884 } else if (ValueMIN == D3DTEXF_LINEAR) {
3886 if (ValueMIP == D3DTEXF_POINT) {
3887 realVal = GL_LINEAR_MIPMAP_NEAREST;
3888 } else if (ValueMIP == D3DTEXF_LINEAR) {
3889 realVal = GL_LINEAR_MIPMAP_LINEAR;
3890 } else if (ValueMIP == D3DTEXF_NONE) {
3891 realVal = GL_LINEAR;
3893 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3894 realVal = GL_LINEAR_MIPMAP_LINEAR;
3896 } else if (ValueMIN == D3DTEXF_NONE) {
3897 /* Doesnt really make sense - Windows just seems to disable
3898 mipmapping when this occurs */
3899 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3900 realVal = GL_LINEAR;
3903 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3904 realVal = GL_LINEAR_MIPMAP_LINEAR;
3907 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3908 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3909 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3914 case D3DTSS_MAGFILTER :
3915 if (Value == D3DTEXF_POINT) {
3916 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3917 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3918 } else if (Value == D3DTEXF_LINEAR) {
3919 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3920 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3922 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3926 case D3DTSS_COLORARG0 :
3927 case D3DTSS_ALPHAARG0 :
3928 /* FIXME: Mesa seems to struggle setting these at the moment */
3929 /*FIXME("COLORARG0/ALPHAARG0 support still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);*/
3932 case D3DTSS_COLORARG1 :
3933 case D3DTSS_COLORARG2 :
3934 case D3DTSS_ALPHAARG1 :
3935 case D3DTSS_ALPHAARG2 :
3937 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3938 int operand = GL_SRC_COLOR;
3939 int source = GL_TEXTURE;
3941 GetSrcAndOpFromValue(Value, isAlphaArg, &source, &operand);
3944 /* From MSDN (D3DTSS_ALPHAARG1) :
3945 The default argument is D3DTA_TEXTURE. If no texture is set for this stage,
3946 then the default argument is D3DTA_DIFFUSE.
3947 FIXME? If texture added/removed, may need to reset back as well? */
3948 if (Type == D3DTSS_ALPHAARG1 && This->StateBlock->textures[Stage] == NULL && Value == D3DTA_TEXTURE) {
3949 GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlphaArg, &source, &operand);
3951 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3952 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3953 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3954 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3955 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3957 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3958 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3959 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3960 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3961 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3966 case D3DTSS_ALPHAOP :
3967 case D3DTSS_COLOROP :
3971 int Parm = (Type == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3973 if (Type == D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3974 /* TODO: Disable by making this and all later levels disabled */
3975 glDisable(GL_TEXTURE_1D);
3976 checkGLcall("Disable GL_TEXTURE_1D");
3977 glDisable(GL_TEXTURE_2D);
3978 checkGLcall("Disable GL_TEXTURE_2D");
3979 glDisable(GL_TEXTURE_3D);
3980 checkGLcall("Disable GL_TEXTURE_3D");
3983 /* Enable only the appropriate texture dimension */
3984 if (Type == D3DTSS_COLOROP) {
3985 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
3986 glEnable(GL_TEXTURE_1D);
3987 checkGLcall("Enable GL_TEXTURE_1D");
3989 glDisable(GL_TEXTURE_1D);
3990 checkGLcall("Disable GL_TEXTURE_1D");
3992 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
3993 glEnable(GL_TEXTURE_2D);
3994 checkGLcall("Enable GL_TEXTURE_2D");
3996 glDisable(GL_TEXTURE_2D);
3997 checkGLcall("Disable GL_TEXTURE_2D");
3999 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
4000 glEnable(GL_TEXTURE_3D);
4001 checkGLcall("Enable GL_TEXTURE_3D");
4003 glDisable(GL_TEXTURE_3D);
4004 checkGLcall("Disable GL_TEXTURE_3D");
4006 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_CUBE_MAP_ARB) {
4007 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
4008 checkGLcall("Enable GL_TEXTURE_CUBE_MAP");
4010 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
4011 checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
4015 /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
4016 if (Value != D3DTOP_DISABLE) {
4017 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
4020 /* Now set up the operand correctly */
4022 case D3DTOP_DISABLE :
4023 /* Contrary to the docs, alpha can be disabled when colorop is enabled
4024 and it works, so ignore this op */
4025 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
4028 case D3DTOP_SELECTARG1 :
4030 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
4031 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
4035 case D3DTOP_SELECTARG2 :
4037 BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP);
4041 /*FIXME("see if D3DTOP_SELECTARG2 behavior is correct now!\n");*/
4042 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
4043 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
4044 /* GL_REPLACE, swap args 0 and 1? */
4045 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2];
4046 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
4048 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_ALPHA_EXT, source, GL_OPERAND0_ALPHA_EXT, operand);
4049 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, source);
4050 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 'source')");
4051 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operand);
4052 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 'operand')");
4054 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_RGB_EXT, source, GL_OPERAND0_RGB_EXT, operand);
4055 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, source);
4056 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')");
4057 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operand);
4058 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 'operand')");
4060 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1];
4061 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
4063 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_ALPHA_EXT, source, GL_OPERAND1_ALPHA_EXT, operand);
4064 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, source);
4065 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 'source')");
4066 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operand);
4067 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 'operand')");
4069 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_RGB_EXT, source, GL_OPERAND1_RGB_EXT, operand);
4070 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, source);
4071 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 'source')");
4072 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operand);
4073 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 'operand')");
4078 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
4079 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
4080 case D3DTOP_MODULATE :
4083 if (Type == D3DTSS_ALPHAOP) {
4084 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
4085 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
4087 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
4088 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
4090 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
4091 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
4095 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
4096 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
4099 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
4100 case D3DTOP_ADDSIGNED :
4101 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
4102 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
4105 case D3DTOP_DOTPRODUCT3 :
4106 #if defined(GL_VERSION_1_3)
4108 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
4109 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
4113 FIXME("DotProduct3 extension requested but not supported via this version of opengl\n");
4117 case D3DTOP_SUBTRACT :
4118 #if defined(GL_VERSION_1_3)
4119 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT);
4120 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT)");
4125 * if ARB_texture_env_combine is supported
4126 * we can use GL_SUBTRACT_ARB here
4129 case D3DTOP_ADDSMOOTH :
4130 case D3DTOP_BLENDDIFFUSEALPHA :
4131 case D3DTOP_BLENDTEXTUREALPHA :
4132 case D3DTOP_BLENDFACTORALPHA :
4133 case D3DTOP_BLENDTEXTUREALPHAPM :
4134 case D3DTOP_BLENDCURRENTALPHA :
4135 case D3DTOP_PREMODULATE :
4136 case D3DTOP_MODULATEALPHA_ADDCOLOR :
4137 case D3DTOP_MODULATECOLOR_ADDALPHA :
4138 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
4139 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
4140 case D3DTOP_BUMPENVMAP :
4141 case D3DTOP_BUMPENVMAPLUMINANCE :
4142 case D3DTOP_MULTIPLYADD :
4145 FIXME("Unhandled texture operation %ld\n", Value);
4151 case D3DTSS_ADDRESSU :
4152 case D3DTSS_ADDRESSV :
4153 case D3DTSS_ADDRESSW :
4155 GLint wrapParm = GL_REPEAT;
4157 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
4158 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break;
4159 case D3DTADDRESS_BORDER: wrapParm = GL_REPEAT; break; /* FIXME: Not right, but better */
4160 #if defined(GL_VERSION_1_4)
4161 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT; break;
4162 #elif defined(GL_ARB_texture_mirrored_repeat)
4163 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT_ARB; break;
4165 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL pre-1.4 */
4167 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL */
4169 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
4170 wrapParm = GL_REPEAT;
4174 case D3DTSS_ADDRESSU:
4175 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
4176 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
4177 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
4179 case D3DTSS_ADDRESSV:
4180 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
4181 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
4182 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
4184 case D3DTSS_ADDRESSW:
4185 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
4186 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
4187 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
4190 break; /** stupic compilator */
4195 case D3DTSS_BORDERCOLOR :
4199 col[0] = ((Value >> 16) & 0xFF) / 255.0;
4200 col[1] = ((Value >> 8) & 0xFF) / 255.0;
4201 col[2] = ((Value >> 0) & 0xFF) / 255.0;
4202 col[3] = ((Value >> 24) & 0xFF) / 255.0;
4204 D3DCOLORTOGLFLOAT4(Value, col);
4205 TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value);
4206 glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
4207 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
4211 case D3DTSS_TEXCOORDINDEX :
4213 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
4215 /* FIXME: From MSDN: The D3DTSS_TCI_* flags are mutually exclusive. If you include
4216 one flag, you can still specify an index value, which the system uses to
4217 determine the texture wrapping mode.
4218 eg. SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 );
4219 means use the vertex position (camera-space) as the input texture coordinates
4220 for this texture stage, and the wrap mode set in the D3DRS_WRAP1 render
4221 state. We do not (yet) support the D3DRENDERSTATE_WRAPx values, nor tie them up
4222 to the TEXCOORDINDEX value */
4225 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
4227 switch (Value & 0xFFFF0000) {
4228 case D3DTSS_TCI_PASSTHRU:
4229 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
4230 glDisable(GL_TEXTURE_GEN_S);
4231 glDisable(GL_TEXTURE_GEN_T);
4232 glDisable(GL_TEXTURE_GEN_R);
4235 case D3DTSS_TCI_CAMERASPACEPOSITION:
4236 /* CameraSpacePosition means use the vertex position, transformed to camera space,
4237 as the input texture coordinates for this stage's texture transformation. This
4238 equates roughly to EYE_LINEAR */
4240 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
4241 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
4242 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
4243 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
4244 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
4246 glMatrixMode(GL_MODELVIEW);
4249 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
4250 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
4251 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
4252 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
4255 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
4256 glEnable(GL_TEXTURE_GEN_S);
4257 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
4258 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
4259 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
4260 glEnable(GL_TEXTURE_GEN_T);
4261 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
4262 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
4263 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
4264 glEnable(GL_TEXTURE_GEN_R);
4265 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
4266 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
4267 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
4271 #if defined(GL_ARB_texture_cube_map) || defined(GL_NV_texgen_reflection)
4272 case D3DTSS_TCI_CAMERASPACENORMAL:
4274 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
4275 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
4276 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
4277 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
4278 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
4280 glMatrixMode(GL_MODELVIEW);
4283 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
4284 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
4285 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
4286 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
4289 glEnable(GL_TEXTURE_GEN_S);
4290 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
4291 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
4292 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
4293 glEnable(GL_TEXTURE_GEN_T);
4294 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
4295 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
4296 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
4297 glEnable(GL_TEXTURE_GEN_R);
4298 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
4299 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
4300 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
4305 #if defined(GL_ARB_texture_cube_map) || defined(GL_NV_texgen_reflection)
4306 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
4309 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
4310 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
4311 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
4312 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
4313 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
4315 glMatrixMode(GL_MODELVIEW);
4318 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
4319 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
4320 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
4321 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
4324 glEnable(GL_TEXTURE_GEN_S);
4325 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
4326 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
4327 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
4328 glEnable(GL_TEXTURE_GEN_T);
4329 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
4330 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
4331 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
4332 glEnable(GL_TEXTURE_GEN_R);
4333 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
4334 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
4335 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
4340 /* Unhandled types: */
4343 /* ? disable GL_TEXTURE_GEN_n ? */
4344 glDisable(GL_TEXTURE_GEN_S);
4345 glDisable(GL_TEXTURE_GEN_T);
4346 glDisable(GL_TEXTURE_GEN_R);
4347 FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value);
4354 case D3DTSS_BUMPENVMAT00 :
4355 case D3DTSS_BUMPENVMAT01 :
4356 TRACE("BUMPENVMAT0%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT00, Stage, Type, Value);
4358 case D3DTSS_BUMPENVMAT10 :
4359 case D3DTSS_BUMPENVMAT11 :
4360 TRACE("BUMPENVMAT1%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT10, Stage, Type, Value);
4363 case D3DTSS_TEXTURETRANSFORMFLAGS :
4365 switch (Value & ~D3DTTFF_PROJECTED)
4367 case D3DTTFF_DISABLE: /* Disable transform matrix for this texture by setting up the identity matrix */
4368 glMatrixMode(GL_TEXTURE);
4370 checkGLcall("Load identity matrix for texture");
4371 glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
4374 default: /* Enable it */
4375 IDirect3DDevice8Impl_SetTransform(iface, D3DTS_TEXTURE0+Stage, &This->UpdateStateBlock->transforms[D3DTS_TEXTURE0+Stage]);
4379 /* From web: <quote source="opengl12.pdf" section="Apendix C, Version 1.1/Other changes"
4380 2. Texture coordinates s, t, and r are divided by q during the rasterization
4381 of points, pixel rectangles, and bitmaps. This division was documented
4382 only for lines and polygons in the 1.0 version. </quote>
4383 I interpret this as we can implement projected transforms in slow vertex mode
4384 by moving the last coord to the 'q' coord and using one less dimension. The only
4385 way to do it in TexCoordPtr would be to massage the data stream to insert extra
4390 case D3DTSS_MIPMAPLODBIAS :
4391 case D3DTSS_MAXMIPLEVEL :
4392 case D3DTSS_MAXANISOTROPY :
4393 case D3DTSS_BUMPENVLSCALE :
4394 case D3DTSS_BUMPENVLOFFSET :
4395 case D3DTSS_RESULTARG :
4397 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
4398 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
4402 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
4403 ICOM_THIS(IDirect3DDevice8Impl,iface);
4404 TRACE("(%p) : stub\n", This); /* FIXME: Needs doing, but called often and is harmless */
4407 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID, void* pDevInfoStruct, DWORD DevInfoStructSize) {
4408 ICOM_THIS(IDirect3DDevice8Impl,iface);
4409 FIXME("(%p) : stub\n", This);
4412 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
4413 ICOM_THIS(IDirect3DDevice8Impl,iface);
4414 FIXME("(%p) : setting p[%u] <= RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber,
4415 pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags);
4416 memcpy(&This->palettes[PaletteNumber], pEntries, 256 * sizeof(PALETTEENTRY));
4419 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
4420 ICOM_THIS(IDirect3DDevice8Impl,iface);
4421 memcpy(pEntries, &This->palettes[PaletteNumber], 256 * sizeof(PALETTEENTRY));
4422 FIXME("(%p) : returning p[%u] => RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber,
4423 pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags);
4426 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
4427 ICOM_THIS(IDirect3DDevice8Impl,iface);
4428 FIXME("(%p) : Setting to (%u)\n", This, PaletteNumber);
4429 This->currentPalette = PaletteNumber;
4430 #if defined(GL_EXT_paletted_texture)
4431 glColorTableEXT(GL_TEXTURE_2D, /* target */
4432 GL_RGBA, /* internal format */
4433 256, /* table size */
4434 GL_RGBA, /* table format */
4435 GL_UNSIGNED_BYTE, /* table type */
4436 &This->palettes[PaletteNumber]);
4437 checkGLcall("glColorTableEXT");
4441 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
4442 ICOM_THIS(IDirect3DDevice8Impl,iface);
4443 *PaletteNumber = This->currentPalette;
4444 FIXME("(%p) : Returning (%u)\n", This, *PaletteNumber);
4447 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
4449 IDirect3DVertexBuffer8 *pVB;
4451 ICOM_THIS(IDirect3DDevice8Impl,iface);
4452 pVB = This->StateBlock->stream_source[0];
4454 TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), StartVertex, PrimitiveCount);
4456 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
4457 This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
4461 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
4462 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
4464 IDirect3DIndexBuffer8 *pIB;
4465 IDirect3DVertexBuffer8 *pVB;
4466 D3DINDEXBUFFER_DESC IdxBufDsc;
4468 ICOM_THIS(IDirect3DDevice8Impl,iface);
4469 pIB = This->StateBlock->pIndexData;
4470 pVB = This->StateBlock->stream_source[0];
4472 TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d \n", This,
4473 PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
4474 minIndex, NumVertices, startIndex, primCount);
4476 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
4477 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
4483 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
4484 This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
4489 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
4490 ICOM_THIS(IDirect3DDevice8Impl,iface);
4492 TRACE("(%p) : Type=(%d,%s), pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
4493 PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
4495 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
4497 This->StateBlock->stream_source[0] = NULL;
4498 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
4499 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock->VertexShader, pVertexStreamZeroData,
4501 This->StateBlock->stream_stride[0] = 0;
4503 /*stream zero settings set to null at end */
4506 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
4507 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
4508 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
4509 UINT VertexStreamZeroStride) {
4511 ICOM_THIS(IDirect3DDevice8Impl,iface);
4512 TRACE("(%p) : Type=(%d,%s), MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
4513 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
4515 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
4516 if (IndexDataFormat == D3DFMT_INDEX16) {
4522 This->StateBlock->stream_source[0] = NULL;
4523 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
4524 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock->VertexShader, pVertexStreamZeroData,
4525 This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
4527 /*stream zero settings set to null at end */
4528 This->StateBlock->stream_stride[0] = 0;
4529 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
4533 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
4534 ICOM_THIS(IDirect3DDevice8Impl,iface);
4535 FIXME("(%p) : stub\n", This); return D3D_OK;
4537 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
4538 ICOM_THIS(IDirect3DDevice8Impl,iface);
4539 IDirect3DVertexShaderImpl* object;
4540 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4544 TRACE_(d3d_shader)("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
4545 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
4546 return D3DERR_INVALIDCALL;
4548 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
4549 if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
4550 return D3DERR_OUTOFVIDEOMEMORY;
4553 /** Create the Vertex Shader */
4554 res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
4555 /** TODO: check FAILED(res) */
4557 /** Create and Bind the Vertex Shader Declaration */
4558 res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
4559 /** TODO: check FAILED(res) */
4561 VertexShaders[i] = object;
4562 VertexShaderDeclarations[i] = attached_decl;
4563 *pHandle = VS_HIGHESTFIXEDFXF + i;
4567 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4568 ICOM_THIS(IDirect3DDevice8Impl,iface);
4570 This->UpdateStateBlock->VertexShader = Handle;
4571 This->UpdateStateBlock->Changed.vertexShader = TRUE;
4572 This->UpdateStateBlock->Set.vertexShader = TRUE;
4574 if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
4575 TRACE_(d3d_shader)("(%p) : Created shader, Handle=%lx\n", This, Handle);
4576 This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
4577 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
4578 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
4579 } else { /* use a fvf, so desactivate the vshader decl */
4580 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
4581 This->UpdateStateBlock->vertexShaderDecl = NULL;
4582 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
4583 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
4585 /* Handle recording of state blocks */
4586 if (This->isRecordingState) {
4587 TRACE("Recording... not performing anything\n");
4591 * TODO: merge HAL shaders context switching from prototype
4595 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4596 ICOM_THIS(IDirect3DDevice8Impl,iface);
4597 TRACE_(d3d_shader)("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
4598 *pHandle = This->StateBlock->VertexShader;
4602 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4603 ICOM_THIS(IDirect3DDevice8Impl,iface);
4604 IDirect3DVertexShaderImpl* object;
4605 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4607 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4608 return D3DERR_INVALIDCALL;
4612 * Delete Vertex Shader
4614 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
4615 if (NULL == object) {
4616 return D3DERR_INVALIDCALL;
4618 TRACE_(d3d_shader)("(%p) : freing VertexShader %p\n", This, object);
4619 /* TODO: check validity of object */
4620 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
4621 HeapFree(GetProcessHeap(), 0, (void *)object->data);
4622 HeapFree(GetProcessHeap(), 0, (void *)object);
4623 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
4626 * Delete Vertex Shader Declaration
4628 attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
4629 if (NULL == attached_decl) {
4630 return D3DERR_INVALIDCALL;
4632 TRACE_(d3d_shader)("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
4633 /* TODO: check validity of object */
4634 HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
4635 HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
4636 VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
4641 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
4642 ICOM_THIS(IDirect3DDevice8Impl,iface);
4644 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
4645 ERR_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);
4646 return D3DERR_INVALIDCALL;
4648 if (NULL == pConstantData) {
4649 return D3DERR_INVALIDCALL;
4651 if (ConstantCount > 1) {
4652 FLOAT* f = (FLOAT*)pConstantData;
4654 TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
4655 for (i = 0; i < ConstantCount; ++i) {
4656 TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
4660 FLOAT* f = (FLOAT*) pConstantData;
4661 TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
4663 This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
4664 memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
4667 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
4668 ICOM_THIS(IDirect3DDevice8Impl,iface);
4670 TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
4671 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
4672 return D3DERR_INVALIDCALL;
4674 if (NULL == pConstantData) {
4675 return D3DERR_INVALIDCALL;
4677 memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
4680 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4681 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
4682 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4684 attached_decl = VERTEX_SHADER_DECL(Handle);
4685 if (NULL == attached_decl) {
4686 return D3DERR_INVALIDCALL;
4688 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
4690 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4691 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
4692 IDirect3DVertexShaderImpl* object;
4694 object = VERTEX_SHADER(Handle);
4695 if (NULL == object) {
4696 return D3DERR_INVALIDCALL;
4698 return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
4701 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
4702 ICOM_THIS(IDirect3DDevice8Impl,iface);
4703 IDirect3DIndexBuffer8 *oldIdxs;
4705 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
4706 oldIdxs = This->StateBlock->pIndexData;
4708 This->UpdateStateBlock->Changed.Indices = TRUE;
4709 This->UpdateStateBlock->Set.Indices = TRUE;
4710 This->UpdateStateBlock->pIndexData = pIndexData;
4711 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
4713 /* Handle recording of state blocks */
4714 if (This->isRecordingState) {
4715 TRACE("Recording... not performing anything\n");
4719 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
4720 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
4723 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
4724 ICOM_THIS(IDirect3DDevice8Impl,iface);
4725 FIXME("(%p) : stub\n", This);
4727 *ppIndexData = This->StateBlock->pIndexData;
4728 /* up ref count on ppindexdata */
4729 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
4730 *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
4734 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
4735 ICOM_THIS(IDirect3DDevice8Impl,iface);
4736 IDirect3DPixelShaderImpl* object;
4739 FIXME("(%p) : PixelShader not fully supported yet\n", This);
4740 if (NULL == pFunction || NULL == pHandle) {
4741 return D3DERR_INVALIDCALL;
4743 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
4744 if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
4745 return D3DERR_OUTOFVIDEOMEMORY;
4747 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
4748 if (NULL == object) {
4749 return D3DERR_OUTOFVIDEOMEMORY;
4752 object->data = NULL; /* TODO */
4754 PixelShaders[i] = object;
4755 *pHandle = VS_HIGHESTFIXEDFXF + i;
4757 object->function = pFunction;
4758 for (i = 0; D3DPS_END() != pFunction[i]; ++i) ;
4759 object->functionLength = i + 1;
4763 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4764 ICOM_THIS(IDirect3DDevice8Impl,iface);
4766 This->UpdateStateBlock->PixelShader = Handle;
4767 This->UpdateStateBlock->Changed.pixelShader = TRUE;
4768 This->UpdateStateBlock->Set.pixelShader = TRUE;
4770 /* Handle recording of state blocks */
4771 if (This->isRecordingState) {
4772 TRACE("Recording... not performing anything\n");
4776 /* FIXME: Quieten when not being used */
4778 FIXME("(%p) : stub %ld\n", This, Handle);
4780 TRACE("(%p) : stub %ld\n", This, Handle);
4785 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4786 ICOM_THIS(IDirect3DDevice8Impl,iface);
4787 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
4788 *pHandle = This->StateBlock->PixelShader;
4792 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4793 ICOM_THIS(IDirect3DDevice8Impl,iface);
4794 IDirect3DPixelShaderImpl* object;
4796 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4797 return D3DERR_INVALIDCALL;
4799 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
4800 TRACE("(%p) : freeing PixelShader %p\n", This, object);
4801 /* TODO: check validity of object before free */
4802 HeapFree(GetProcessHeap(), 0, (void *)object);
4803 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
4807 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
4808 ICOM_THIS(IDirect3DDevice8Impl,iface);
4809 FIXME("(%p) : stub\n", This);
4812 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
4813 ICOM_THIS(IDirect3DDevice8Impl,iface);
4814 FIXME("(%p) : stub\n", This);
4817 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4818 ICOM_THIS(IDirect3DDevice8Impl,iface);
4819 IDirect3DPixelShaderImpl* object;
4821 object = PIXEL_SHADER(Handle);
4822 if (NULL == object) {
4823 return D3DERR_INVALIDCALL;
4825 if (NULL == pData) {
4826 *pSizeOfData = object->functionLength;
4829 if (*pSizeOfData < object->functionLength) {
4830 *pSizeOfData = object->functionLength;
4831 return D3DERR_MOREDATA;
4833 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
4834 memcpy(pData, object->function, object->functionLength);
4837 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
4838 ICOM_THIS(IDirect3DDevice8Impl,iface);
4839 FIXME("(%p) : stub\n", This); return D3D_OK;
4841 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
4842 ICOM_THIS(IDirect3DDevice8Impl,iface);
4843 FIXME("(%p) : stub\n", This); return D3D_OK;
4845 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
4846 ICOM_THIS(IDirect3DDevice8Impl,iface);
4847 FIXME("(%p) : stub\n", This); return D3D_OK;
4850 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
4851 IDirect3DVertexBuffer8 *oldSrc;
4852 ICOM_THIS(IDirect3DDevice8Impl,iface);
4854 oldSrc = This->StateBlock->stream_source[StreamNumber];
4855 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
4857 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
4858 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
4859 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
4860 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
4862 /* Handle recording of state blocks */
4863 if (This->isRecordingState) {
4864 TRACE("Recording... not performing anything\n");
4868 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
4869 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
4872 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
4873 ICOM_THIS(IDirect3DDevice8Impl,iface);
4874 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
4875 *pStream = This->StateBlock->stream_source[StreamNumber];
4876 *pStride = This->StateBlock->stream_stride[StreamNumber];
4877 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
4882 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
4884 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4885 IDirect3DDevice8Impl_QueryInterface,
4886 IDirect3DDevice8Impl_AddRef,
4887 IDirect3DDevice8Impl_Release,
4888 IDirect3DDevice8Impl_TestCooperativeLevel,
4889 IDirect3DDevice8Impl_GetAvailableTextureMem,
4890 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
4891 IDirect3DDevice8Impl_GetDirect3D,
4892 IDirect3DDevice8Impl_GetDeviceCaps,
4893 IDirect3DDevice8Impl_GetDisplayMode,
4894 IDirect3DDevice8Impl_GetCreationParameters,
4895 IDirect3DDevice8Impl_SetCursorProperties,
4896 IDirect3DDevice8Impl_SetCursorPosition,
4897 IDirect3DDevice8Impl_ShowCursor,
4898 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
4899 IDirect3DDevice8Impl_Reset,
4900 IDirect3DDevice8Impl_Present,
4901 IDirect3DDevice8Impl_GetBackBuffer,
4902 IDirect3DDevice8Impl_GetRasterStatus,
4903 IDirect3DDevice8Impl_SetGammaRamp,
4904 IDirect3DDevice8Impl_GetGammaRamp,
4905 IDirect3DDevice8Impl_CreateTexture,
4906 IDirect3DDevice8Impl_CreateVolumeTexture,
4907 IDirect3DDevice8Impl_CreateCubeTexture,
4908 IDirect3DDevice8Impl_CreateVertexBuffer,
4909 IDirect3DDevice8Impl_CreateIndexBuffer,
4910 IDirect3DDevice8Impl_CreateRenderTarget,
4911 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4912 IDirect3DDevice8Impl_CreateImageSurface,
4913 IDirect3DDevice8Impl_CopyRects,
4914 IDirect3DDevice8Impl_UpdateTexture,
4915 IDirect3DDevice8Impl_GetFrontBuffer,
4916 IDirect3DDevice8Impl_SetRenderTarget,
4917 IDirect3DDevice8Impl_GetRenderTarget,
4918 IDirect3DDevice8Impl_GetDepthStencilSurface,
4919 IDirect3DDevice8Impl_BeginScene,
4920 IDirect3DDevice8Impl_EndScene,
4921 IDirect3DDevice8Impl_Clear,
4922 IDirect3DDevice8Impl_SetTransform,
4923 IDirect3DDevice8Impl_GetTransform,
4924 IDirect3DDevice8Impl_MultiplyTransform,
4925 IDirect3DDevice8Impl_SetViewport,
4926 IDirect3DDevice8Impl_GetViewport,
4927 IDirect3DDevice8Impl_SetMaterial,
4928 IDirect3DDevice8Impl_GetMaterial,
4929 IDirect3DDevice8Impl_SetLight,
4930 IDirect3DDevice8Impl_GetLight,
4931 IDirect3DDevice8Impl_LightEnable,
4932 IDirect3DDevice8Impl_GetLightEnable,
4933 IDirect3DDevice8Impl_SetClipPlane,
4934 IDirect3DDevice8Impl_GetClipPlane,
4935 IDirect3DDevice8Impl_SetRenderState,
4936 IDirect3DDevice8Impl_GetRenderState,
4937 IDirect3DDevice8Impl_BeginStateBlock,
4938 IDirect3DDevice8Impl_EndStateBlock,
4939 IDirect3DDevice8Impl_ApplyStateBlock,
4940 IDirect3DDevice8Impl_CaptureStateBlock,
4941 IDirect3DDevice8Impl_DeleteStateBlock,
4942 IDirect3DDevice8Impl_CreateStateBlock,
4943 IDirect3DDevice8Impl_SetClipStatus,
4944 IDirect3DDevice8Impl_GetClipStatus,
4945 IDirect3DDevice8Impl_GetTexture,
4946 IDirect3DDevice8Impl_SetTexture,
4947 IDirect3DDevice8Impl_GetTextureStageState,
4948 IDirect3DDevice8Impl_SetTextureStageState,
4949 IDirect3DDevice8Impl_ValidateDevice,
4950 IDirect3DDevice8Impl_GetInfo,
4951 IDirect3DDevice8Impl_SetPaletteEntries,
4952 IDirect3DDevice8Impl_GetPaletteEntries,
4953 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4954 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4955 IDirect3DDevice8Impl_DrawPrimitive,
4956 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4957 IDirect3DDevice8Impl_DrawPrimitiveUP,
4958 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4959 IDirect3DDevice8Impl_ProcessVertices,
4960 IDirect3DDevice8Impl_CreateVertexShader,
4961 IDirect3DDevice8Impl_SetVertexShader,
4962 IDirect3DDevice8Impl_GetVertexShader,
4963 IDirect3DDevice8Impl_DeleteVertexShader,
4964 IDirect3DDevice8Impl_SetVertexShaderConstant,
4965 IDirect3DDevice8Impl_GetVertexShaderConstant,
4966 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4967 IDirect3DDevice8Impl_GetVertexShaderFunction,
4968 IDirect3DDevice8Impl_SetStreamSource,
4969 IDirect3DDevice8Impl_GetStreamSource,
4970 IDirect3DDevice8Impl_SetIndices,
4971 IDirect3DDevice8Impl_GetIndices,
4972 IDirect3DDevice8Impl_CreatePixelShader,
4973 IDirect3DDevice8Impl_SetPixelShader,
4974 IDirect3DDevice8Impl_GetPixelShader,
4975 IDirect3DDevice8Impl_DeletePixelShader,
4976 IDirect3DDevice8Impl_SetPixelShaderConstant,
4977 IDirect3DDevice8Impl_GetPixelShaderConstant,
4978 IDirect3DDevice8Impl_GetPixelShaderFunction,
4979 IDirect3DDevice8Impl_DrawRectPatch,
4980 IDirect3DDevice8Impl_DrawTriPatch,
4981 IDirect3DDevice8Impl_DeletePatch