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);
82 const char* debug_d3dformat(D3DFORMAT fmt) {
84 #define FMT_TO_STR(fmt) case fmt: return #fmt
85 FMT_TO_STR(D3DFMT_UNKNOWN);
87 FMT_TO_STR(D3DFMT_R8G8B8);
88 FMT_TO_STR(D3DFMT_A8R8G8B8);
89 FMT_TO_STR(D3DFMT_X8R8G8B8);
90 FMT_TO_STR(D3DFMT_R5G6B5);
91 FMT_TO_STR(D3DFMT_X1R5G5B5);
92 FMT_TO_STR(D3DFMT_A1R5G5B5);
93 FMT_TO_STR(D3DFMT_A4R4G4B4);
94 FMT_TO_STR(D3DFMT_R3G3B2);
95 FMT_TO_STR(D3DFMT_A8);
96 FMT_TO_STR(D3DFMT_A8R3G3B2);
97 FMT_TO_STR(D3DFMT_X4R4G4B4);
99 FMT_TO_STR(D3DFMT_A8P8);
100 FMT_TO_STR(D3DFMT_P8);
102 FMT_TO_STR(D3DFMT_L8);
103 FMT_TO_STR(D3DFMT_A8L8);
104 FMT_TO_STR(D3DFMT_A4L4);
106 FMT_TO_STR(D3DFMT_V8U8);
107 FMT_TO_STR(D3DFMT_L6V5U5);
108 FMT_TO_STR(D3DFMT_X8L8V8U8);
109 FMT_TO_STR(D3DFMT_Q8W8V8U8);
110 FMT_TO_STR(D3DFMT_V16U16);
111 FMT_TO_STR(D3DFMT_W11V11U10);
113 FMT_TO_STR(D3DFMT_UYVY);
114 FMT_TO_STR(D3DFMT_YUY2);
115 FMT_TO_STR(D3DFMT_DXT1);
116 FMT_TO_STR(D3DFMT_DXT2);
117 FMT_TO_STR(D3DFMT_DXT3);
118 FMT_TO_STR(D3DFMT_DXT4);
119 FMT_TO_STR(D3DFMT_DXT5);
121 FMT_TO_STR(D3DFMT_D16_LOCKABLE);
122 FMT_TO_STR(D3DFMT_D32);
123 FMT_TO_STR(D3DFMT_D15S1);
124 FMT_TO_STR(D3DFMT_D24S8);
125 FMT_TO_STR(D3DFMT_D16);
126 FMT_TO_STR(D3DFMT_D24X8);
127 FMT_TO_STR(D3DFMT_D24X4S4);
129 FMT_TO_STR(D3DFMT_VERTEXDATA);
130 FMT_TO_STR(D3DFMT_INDEX16);
131 FMT_TO_STR(D3DFMT_INDEX32);
134 FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
135 return "unrecognized";
139 const char* debug_d3dressourcetype(D3DRESOURCETYPE res) {
141 #define RES_TO_STR(res) case res: return #res;
142 RES_TO_STR(D3DRTYPE_SURFACE);
143 RES_TO_STR(D3DRTYPE_VOLUME);
144 RES_TO_STR(D3DRTYPE_TEXTURE);
145 RES_TO_STR(D3DRTYPE_VOLUMETEXTURE);
146 RES_TO_STR(D3DRTYPE_CUBETEXTURE);
147 RES_TO_STR(D3DRTYPE_VERTEXBUFFER);
148 RES_TO_STR(D3DRTYPE_INDEXBUFFER);
151 FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res);
152 return "unrecognized";
156 /* Routine common to the draw primitive and draw indexed primitive routines */
157 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
164 const void *vertexBufData,
167 long StartVertexIndex,
173 int NumVertexes = NumPrimitives;
174 IDirect3DVertexShaderImpl* vertex_shader = NULL;
175 BOOL useVertexShaderFunction = FALSE;
177 ICOM_THIS(IDirect3DDevice8Impl,iface);
179 /* Dont understand how to handle multiple streams, but if a fixed
180 FVF is passed in rather than a handle, it must use stream 0 */
182 if (This->UpdateStateBlock->VertexShader > VS_HIGHESTFIXEDFXF) {
183 vertex_shader = VERTEX_SHADER(This->UpdateStateBlock->VertexShader);
184 if (NULL == vertex_shader) {
185 ERR("trying to use unitialised vertex shader: %lu\n", This->UpdateStateBlock->VertexShader);
188 if (NULL == vertex_shader->function) {
189 TRACE("vertex shader declared without program, using FVF pure mode\n");
191 useVertexShaderFunction = TRUE;
193 fvf = (D3DFORMAT) This->UpdateStateBlock->vertexShaderDecl->fvf;
194 TRACE("vertex shader declared FVF: %lx\n", This->UpdateStateBlock->vertexShaderDecl->fvf);
195 memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8));
197 /** init Constants */
198 if (TRUE == This->UpdateStateBlock->Changed.vertexShaderConstant) {
199 TRACE("vertex shader init Constant\n");
200 IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96);
206 int skip = This->StateBlock->stream_stride[0];
207 GLenum primType = GL_POINTS;
217 const char *curVtx = NULL;
218 const short *pIdxBufS = NULL;
219 const long *pIdxBufL = NULL;
221 BOOL isLightingOn = FALSE;
223 int coordIdxInfo = 0x00; /* Information on number of coords supplied */
224 float s[8], t[8], r[8], q[8]; /* Holding place for tex coords */
225 const char *coordPtr[8]; /* Holding place for the ptr to tex coords */
226 int numCoords[8]; /* Holding place for D3DFVF_TEXTUREFORMATx */
231 z = 0.0f; /* x,y,z coordinates */
234 nz = 0.0f; /* normal x,y,z coordinates */
235 float rhw = 0.0f; /* rhw */
236 float ptSize = 0.0f; /* Point size */
237 DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
238 DWORD specularColor = 0; /* Specular Color */
243 if (idxBytes == 2) pIdxBufS = (short *) idxData;
244 else pIdxBufL = (long *) idxData;
247 /* Check vertex formats expected ? */
249 * FVF parser as seen it
250 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/Reference/CPP/D3D/FlexibleVertexFormatFlags.asp
252 normal = fvf & D3DFVF_NORMAL;
253 isRHW = fvf & D3DFVF_XYZRHW;
254 isLastUByte4 = fvf & D3DFVF_LASTBETA_UBYTE4;
255 numBlends = ((fvf & D3DFVF_POSITION_MASK) >> 1) - 2 + ((FALSE == isLastUByte4) ? 0 : -1); /* WARNING can be < 0 because -2 */
256 isPtSize = fvf & D3DFVF_PSIZE;
257 isDiffuse = fvf & D3DFVF_DIFFUSE;
258 isSpecular = fvf & D3DFVF_SPECULAR;
259 numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
260 coordIdxInfo = (fvf & 0x00FF0000) >> 16; /* 16 is from definition of D3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */
262 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d, coordIdxInfo=%x)\n",
263 fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures, numBlends, coordIdxInfo);
265 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
266 set by the appropriate render state */
268 isLightingOn = glIsEnabled(GL_LIGHTING);
269 glDisable(GL_LIGHTING);
270 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
274 double X, Y, height, width, minZ, maxZ;
276 * Already transformed vertex do not need transform
277 * matrices. Reset all matrices to identity.
278 * Leave the default matrix in world mode.
280 glMatrixMode(GL_MODELVIEW);
281 checkGLcall("glMatrixMode");
283 checkGLcall("glLoadIdentity");
285 * As seen in d3d7 code:
286 * See the OpenGL Red Book for an explanation of the following translation (in the OpenGL
287 * Correctness Tips section).
289 glTranslatef(0.375f, 0.375f, 0.0f);
293 glMatrixMode(GL_PROJECTION);
294 checkGLcall("glMatrixMode");
296 checkGLcall("glLoadIdentity");
297 X = This->StateBlock->viewport.X;
298 Y = This->StateBlock->viewport.Y;
299 height = This->StateBlock->viewport.Height;
300 width = This->StateBlock->viewport.Width;
301 minZ = This->StateBlock->viewport.MinZ;
302 maxZ = This->StateBlock->viewport.MaxZ;
303 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
304 /*glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);*/
305 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
306 checkGLcall("glOrtho");
308 glMatrixMode(GL_MODELVIEW);
309 checkGLcall("glMatrixMode");
310 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
311 checkGLcall("glLoadMatrixf");
312 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
313 checkGLcall("glMultMatrixf");
315 glMatrixMode(GL_PROJECTION);
316 checkGLcall("glMatrixMode");
317 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
318 checkGLcall("glLoadMatrixf");
321 /* Set OpenGL to the appropriate Primitive Type */
322 switch (PrimitiveType) {
323 case D3DPT_POINTLIST:
325 primType = GL_POINTS;
326 NumVertexes = NumPrimitives;
332 NumVertexes = NumPrimitives * 2;
335 case D3DPT_LINESTRIP:
336 TRACE("LINE_STRIP\n");
337 primType = GL_LINE_STRIP;
338 NumVertexes = NumPrimitives + 1;
341 case D3DPT_TRIANGLELIST:
342 TRACE("TRIANGLES\n");
343 primType = GL_TRIANGLES;
344 NumVertexes = NumPrimitives * 3;
347 case D3DPT_TRIANGLESTRIP:
348 TRACE("TRIANGLE_STRIP\n");
349 primType = GL_TRIANGLE_STRIP;
350 NumVertexes = NumPrimitives + 2;
353 case D3DPT_TRIANGLEFAN:
354 TRACE("TRIANGLE_FAN\n");
355 primType = GL_TRIANGLE_FAN;
356 NumVertexes = NumPrimitives + 2;
360 FIXME("Unhandled primitive\n");
364 /* Fixme, Ideally, only use this per-vertex code for software HAL
365 but until opengl supports all the functions returned to setup
366 vertex arrays, we need to drop down to the slow mechanism for
369 if (isPtSize || isDiffuse || useVertexShaderFunction == TRUE || (numBlends > 0)) {
370 TRACE("Using slow per-vertex code\n");
372 /* Enable this one to be able to debug what is going on, but it is slower
373 than the pointer/array version */
374 VTRACE(("glBegin(%x)\n", primType));
377 /* Draw the primitives */
378 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
380 for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
386 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index, pIdxBufS[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
387 curPos = curVtx + ((pIdxBufS[StartIdx+vx_index]) * skip);
389 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index, pIdxBufL[StartIdx+vx_index], (pIdxBufS[StartIdx+vx_index])));
390 curPos = curVtx + ((pIdxBufL[StartIdx+vx_index]) * skip);
394 /* Work through the vertex buffer */
395 x = *(float *)curPos;
396 curPos = curPos + sizeof(float);
397 y = *(float *)curPos;
398 curPos = curPos + sizeof(float);
399 z = *(float *)curPos;
400 curPos = curPos + sizeof(float);
401 VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
403 /* RHW follows, only if transformed */
405 rhw = *(float *)curPos;
406 curPos = curPos + sizeof(float);
407 VTRACE(("rhw=%f\n", rhw));
413 D3DSHADERVECTOR skippedBlend = { 0.0f, 0.0f, 0.0f, 0.0f};
414 DWORD skippedBlendLastUByte4 = 0;
416 for (i = 0; i < ((FALSE == isLastUByte4) ? numBlends : numBlends - 1); ++i) {
417 ((float*)&skippedBlend)[i] = *(float *)curPos;
418 curPos = curPos + sizeof(float);
422 skippedBlendLastUByte4 = *(DWORD*)curPos;
423 curPos = curPos + sizeof(DWORD);
427 /* Vertex Normal Data (untransformed only) */
429 nx = *(float *)curPos;
430 curPos = curPos + sizeof(float);
431 ny = *(float *)curPos;
432 curPos = curPos + sizeof(float);
433 nz = *(float *)curPos;
434 curPos = curPos + sizeof(float);
435 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
439 ptSize = *(float *)curPos;
440 VTRACE(("ptSize=%f\n", ptSize));
441 curPos = curPos + sizeof(float);
445 diffuseColor = *(DWORD *)curPos;
446 VTRACE(("diffuseColor=%lx\n", diffuseColor));
447 curPos = curPos + sizeof(DWORD);
451 specularColor = *(DWORD *)curPos;
452 VTRACE(("specularColor=%lx\n", specularColor));
453 curPos = curPos + sizeof(DWORD);
457 /* numTextures indicates the number of texture coordinates supplied */
458 /* However, the first set may not be for stage 0 texture - it all */
459 /* depends on D3DTSS_TEXCOORDINDEX. */
460 /* The number of bytes for each coordinate set is based off */
461 /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
463 /* Initialize unused coords to unsupplied so we can check later */
464 for (textureNo = numTextures; textureNo < 7; textureNo++) numCoords[textureNo] = -1;
466 /* So, for each supplied texture extract the coords */
467 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
469 numCoords[textureNo] = coordIdxInfo & 0x03;
472 s[textureNo] = *(float *)curPos;
473 curPos = curPos + sizeof(float);
474 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
475 t[textureNo] = *(float *)curPos;
476 curPos = curPos + sizeof(float);
477 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
478 r[textureNo] = *(float *)curPos;
479 curPos = curPos + sizeof(float);
480 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
481 q[textureNo] = *(float *)curPos;
482 curPos = curPos + sizeof(float);
487 coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
490 /* Now use the appropriate set of texture indexes */
491 for (textureNo = 0; textureNo < This->TextureUnits; ++textureNo) {
493 if (!(This->isMultiTexture) && textureNo > 0) {
494 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
498 /* Query tex coords */
499 if ((This->StateBlock->textures[textureNo] != NULL) &&
500 (useVertexShaderFunction == FALSE)) {
502 int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
505 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
506 } else if (coordIdx >= numTextures) {
507 VTRACE(("tex: %d - Skip tex coords, as requested higher than supplied\n", textureNo));
509 switch (numCoords[coordIdx]) { /* Supply the provided texture coords */
510 case D3DFVF_TEXTUREFORMAT1:
511 VTRACE(("tex:%d, s=%f\n", textureNo, s[coordIdx]));
512 if (This->isMultiTexture) {
513 #if defined(GL_VERSION_1_3)
514 glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s[coordIdx]);
516 glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx]);
519 glTexCoord1f(s[coordIdx]);
522 case D3DFVF_TEXTUREFORMAT2:
523 VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s[coordIdx], t[coordIdx]));
524 if (This->isMultiTexture) {
525 #if defined(GL_VERSION_1_3)
526 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx]);
528 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx]);
531 glTexCoord2f(s[coordIdx], t[coordIdx]);
534 case D3DFVF_TEXTUREFORMAT3:
535 VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx]));
536 if (This->isMultiTexture) {
537 #if defined(GL_VERSION_1_3)
538 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
540 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx]);
543 glTexCoord3f(s[coordIdx], t[coordIdx], r[coordIdx]);
546 case D3DFVF_TEXTUREFORMAT4:
547 VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]));
548 if (This->isMultiTexture) {
549 #if defined(GL_VERSION_1_3)
550 glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
552 glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
555 glTexCoord4f(s[coordIdx], t[coordIdx], r[coordIdx], q[coordIdx]);
559 FIXME("Should not get here as numCoords is two bits only (%x)!\n", numCoords[coordIdx]);
566 /** if vertex shader program specified ... using it */
567 if (TRUE == useVertexShaderFunction) {
570 * this code must become the really
571 * vs input params init
573 * because its possible to use input registers for anything
574 * and some samples use registers for other things than they are
579 * no really valid declaration, user defined input register use
580 * so fill input registers as described in vertex shader declaration
582 IDirect3DDeviceImpl_FillVertexShaderInput(This, vertex_shader, vertexBufData, StartVertexIndex,
583 (!isIndexed) ? (vx_index * skip) :
584 (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) :
585 ((pIdxBufL[StartIdx + vx_index]) * skip));
587 memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8));
588 IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
590 TRACE_VECTOR(vertex_shader->output.oPos);
591 TRACE_VECTOR(vertex_shader->output.oD[0]);
592 TRACE_VECTOR(vertex_shader->output.oD[1]);
593 TRACE_VECTOR(vertex_shader->output.oT[0]);
594 TRACE_VECTOR(vertex_shader->output.oT[1]);
595 TRACE_VECTOR(vertex_shader->input.V[0]);
596 TRACE_VECTOR(vertex_shader->data->C[0]);
597 TRACE_VECTOR(vertex_shader->data->C[1]);
598 TRACE_VECTOR(vertex_shader->data->C[2]);
599 TRACE_VECTOR(vertex_shader->data->C[3]);
600 TRACE_VECTOR(vertex_shader->data->C[4]);
601 TRACE_VECTOR(vertex_shader->data->C[5]);
602 TRACE_VECTOR(vertex_shader->data->C[6]);
603 TRACE_VECTOR(vertex_shader->data->C[7]);
605 x = vertex_shader->output.oPos.x;
606 y = vertex_shader->output.oPos.y;
607 z = vertex_shader->output.oPos.z;
609 if (1.0f != vertex_shader->output.oPos.w || isRHW) {
610 rhw = vertex_shader->output.oPos.w;
612 /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
613 glColor4fv((float*) &vertex_shader->output.oD[0]);
615 /* Requires secondary color extensions to compile... */
616 #if defined(GL_VERSION_1_4)
617 glSecondaryColor3fv((float*) &vertex_shader->output.oD[1]);
618 checkGLcall("glSecondaryColor3fv");
620 if (checkGLSupport(EXT_SECONDARY_COLOR)) {
621 /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/
622 /*GLExtCall(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]);*/
623 /*checkGLcall("glSecondaryColor3fvEXT");*/
626 /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
627 for (textureNo = 0; textureNo < 4; ++textureNo) {
630 if (!(This->isMultiTexture) && textureNo > 0) {
631 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
634 /* Query tex coords */
635 if (This->StateBlock->textures[textureNo] != NULL) {
636 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock->textures[textureNo])) {
637 case D3DRTYPE_TEXTURE:
638 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
639 s = vertex_shader->output.oT[textureNo].x;
640 t = vertex_shader->output.oT[textureNo].y;
641 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t));
642 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
643 VTRACE(("Skip tex coords, as being system generated\n"));
645 if (This->isMultiTexture) {
646 #if defined(GL_VERSION_1_3)
647 glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
649 glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
651 /*checkGLcall("glMultiTexCoord2fARB");*/
654 /*checkGLcall("gTexCoord2f");*/
659 case D3DRTYPE_VOLUMETEXTURE:
660 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
661 s = vertex_shader->output.oT[textureNo].x;
662 t = vertex_shader->output.oT[textureNo].y;
663 r = vertex_shader->output.oT[textureNo].z;
664 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r));
665 if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX] > 7) {
666 VTRACE(("Skip tex coords, as being system generated\n"));
668 if (This->isMultiTexture) {
669 #if defined(GL_VERSION_1_3)
670 glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
672 glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
674 /*checkGLcall("glMultiTexCoord2fARB");*/
676 glTexCoord3f(s, t, r);
677 /*checkGLcall("gTexCoord3f");*/
683 /* Avoid compiler warnings, need these vars later for other textures */
685 FIXME("Unhandled texture type\n");
690 if (1.0f == rhw || rhw < 0.01f) {
691 TRACE_(d3d_shader)("Vertex: glVertex:x,y,z=%f,%f,%f\n", x, y, z);
693 /*checkGLcall("glVertex3f");*/
695 GLfloat w = 1.0f / rhw;
696 TRACE_(d3d_shader)("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw);
698 /*glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);*/
699 glVertex4f(x * w, y * w, z * w, 1.0f);
700 /*checkGLcall("glVertex4f");*/
704 * FALSE == useVertexShaderFunction
708 /* Handle these vertexes */
710 glColor4ub((diffuseColor >> 16) & 0xFF,
711 (diffuseColor >> 8) & 0xFF,
712 (diffuseColor >> 0) & 0xFF,
713 (diffuseColor >> 24) & 0xFF);
714 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
715 ((diffuseColor >> 16) & 0xFF) / 255.0f,
716 ((diffuseColor >> 8) & 0xFF) / 255.0f,
717 ((diffuseColor >> 0) & 0xFF) / 255.0f,
718 ((diffuseColor >> 24) & 0xFF) / 255.0f));
722 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x,y,z,nx,ny,nz));
723 glNormal3f(nx, ny, nz);
726 if (1.0f == rhw || rhw < 0.01f) {
727 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
730 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
731 glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
737 curVtx = curVtx + skip;
742 checkGLcall("glEnd and previous calls");
745 TRACE("Using fast vertex array code\n");
747 /* Faster version, harder to debug */
748 /* Shuffle to the beginning of the vertexes to render and index from there */
749 curVtx = (const char *)vertexBufData + (StartVertexIndex * skip);
752 /* Set up the vertex pointers */
754 glVertexPointer(4, GL_FLOAT, skip, curPos);
755 checkGLcall("glVertexPointer(4, ...)");
756 curPos += 4 * sizeof(float);
758 glVertexPointer(3, GL_FLOAT, skip, curPos);
759 checkGLcall("glVertexPointer(3, ...)");
760 curPos += 3 * sizeof(float);
762 glEnableClientState(GL_VERTEX_ARRAY);
763 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
766 /* no such functionality in the fixed function GL pipeline */
767 /* FIXME: Wont get here as will drop to slow method */
768 /* FIXME("Cannot handle blending data here in openGl\n");*/
769 if (checkGLSupport(ARB_VERTEX_BLEND)) {
771 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
774 GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
775 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
776 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
777 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
779 curPos += numBlends * sizeof(float);
781 FIXME("unsupported blending in openGl\n");
784 if (checkGLSupport(ARB_VERTEX_BLEND)) {
786 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
789 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
790 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
797 glNormalPointer(GL_FLOAT, skip, curPos);
798 checkGLcall("glNormalPointer");
799 glEnableClientState(GL_NORMAL_ARRAY);
800 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
801 curPos += 3 * sizeof(float);
803 glDisableClientState(GL_NORMAL_ARRAY);
804 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
806 checkGLcall("glNormal3f(0, 0, 1)");
810 /* no such functionality in the fixed function GL pipeline */
811 /* FIXME: Wont get here as will drop to slow method */
812 FIXME("Cannot change ptSize here in openGl\n");
813 curPos = curPos + sizeof(float);
817 glColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
818 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
819 glEnableClientState(GL_COLOR_ARRAY);
820 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
821 curPos += sizeof(DWORD);
824 glDisableClientState(GL_COLOR_ARRAY);
825 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
826 glColor4f(1, 1, 1, 1);
827 checkGLcall("glColor4f(1, 1, 1, 1)");
830 /* Requires secondary color extensions to compile... */
832 #if defined(GL_VERSION_1_4)
833 glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos);
834 checkGLcall("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, skip, curPos)");
835 glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
836 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY)");
839 /* FIXME: check for GL_EXT_secondary_color */
840 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos);
841 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
842 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
843 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
846 curPos += sizeof(DWORD);
848 #if defined(GL_VERSION_1_4)
849 glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
850 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY)");
851 glSecondaryColor3f(0, 0, 0);
852 checkGLcall("glSecondaryColor3f(0, 0, 0)");
855 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
856 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
857 glSecondaryColor3fEXT(0, 0, 0);
858 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
864 /* numTextures indicates the number of texture coordinates supplied */
865 /* However, the first set may not be for stage 0 texture - it all */
866 /* depends on D3DTSS_TEXCOORDINDEX. */
867 /* The number of bytes for each coordinate set is based off */
868 /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
870 /* Initialize unused coords to unsupplied so we can check later */
871 for (textureNo = numTextures; textureNo < 7; textureNo++) coordPtr[textureNo] = NULL;
873 /* So, for each supplied texture extract the coords */
874 for (textureNo = 0; textureNo < numTextures; ++textureNo) {
876 numCoords[textureNo] = coordIdxInfo & 0x03;
877 coordPtr[textureNo] = curPos;
880 curPos = curPos + sizeof(float);
881 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
882 curPos = curPos + sizeof(float);
883 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
884 curPos = curPos + sizeof(float);
885 if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
886 curPos = curPos + sizeof(float);
890 coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
893 /* Now use the appropriate set of texture indexes */
894 for (textureNo = 0; textureNo < This->TextureUnits; ++textureNo) {
896 if (!(This->isMultiTexture) && textureNo > 0) {
897 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
901 /* Query tex coords */
902 if ((This->StateBlock->textures[textureNo] != NULL) && (useVertexShaderFunction == FALSE)) {
903 int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
906 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
909 #if defined(GL_VERSION_1_3)
910 glClientActiveTexture(GL_TEXTURE0 + textureNo);
912 glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
914 switch (numCoords[coordIdx]) { /* Supply the provided texture coords */
915 case D3DFVF_TEXTUREFORMAT1: numFloats = 1; break;
916 case D3DFVF_TEXTUREFORMAT2: numFloats = 2; break;
917 case D3DFVF_TEXTUREFORMAT3: numFloats = 3; break;
918 case D3DFVF_TEXTUREFORMAT4: numFloats = 4; break;
919 default: numFloats = 0; break;
922 if (numFloats == 0 || coordIdx >= numTextures) {
923 VTRACE(("Skipping as invalid request - numfloats=%d, coordIdx=%d, numTextures=%d\n", numFloats, coordIdx, numTextures));
924 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
925 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
927 VTRACE(("tex: %d, ptr=%p, numcoords=%d\n", textureNo, coordPtr[coordIdx], numFloats));
928 glTexCoordPointer(numFloats, GL_FLOAT, skip, coordPtr[coordIdx]);
929 checkGLcall("glTexCoordPointer(x, ...)");
930 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
931 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
937 /* Finally do the drawing */
940 TRACE("glElements(%x, %d, %d, ...)\n", primType, NumVertexes, minIndex);
942 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
943 glDrawElements(primType, NumVertexes, GL_UNSIGNED_SHORT,
944 (char *)idxData+(2 * StartIdx));
946 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
947 GL_UNSIGNED_SHORT, (char *)idxData+(2 * StartIdx));
950 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
951 glDrawElements(primType, NumVertexes, GL_UNSIGNED_INT,
952 (char *)idxData+(4 * StartIdx));
954 glDrawRangeElements(primType, minIndex, minIndex+NumVertexes-1, NumVertexes,
955 GL_UNSIGNED_INT, (char *)idxData+(2 * StartIdx));
958 checkGLcall("glDrawRangeElements");
962 /* Note first is now zero as we shuffled along earlier */
963 TRACE("glDrawArrays(%x, %ld, %d)\n", primType, StartIdx, NumVertexes);
964 glDrawArrays(primType, 0, NumVertexes);
965 checkGLcall("glDrawArrays");
970 /* If no normals, restore previous lighting state */
972 if (isLightingOn) glEnable(GL_LIGHTING);
973 else glDisable(GL_LIGHTING);
974 TRACE("Restored lighting to original state\n");
984 * Simple utility routines used for dx -> gl mapping of byte formats
986 SHORT bytesPerPixel(D3DFORMAT fmt) {
991 case D3DFMT_A4R4G4B4: retVal = 2; break;
992 case D3DFMT_A8R8G8B8: retVal = 4; break;
993 case D3DFMT_X8R8G8B8: retVal = 4; break;
994 case D3DFMT_R8G8B8: retVal = 3; break;
995 case D3DFMT_R5G6B5: retVal = 2; break;
996 case D3DFMT_A1R5G5B5: retVal = 2; break;
997 /* depth/stencil buffer */
998 case D3DFMT_D16_LOCKABLE: retVal = 2; break;
999 case D3DFMT_D32: retVal = 4; break;
1000 case D3DFMT_D15S1: retVal = 2; break;
1001 case D3DFMT_D24S8: retVal = 4; break;
1002 case D3DFMT_D16: retVal = 2; break;
1003 case D3DFMT_D24X8: retVal = 4; break;
1004 case D3DFMT_D24X4S4: retVal = 4; break;
1006 case D3DFMT_UNKNOWN:
1007 /* Guess at the highest value of the above */
1008 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt);
1013 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1016 TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
1020 GLint fmt2glintFmt(D3DFORMAT fmt) {
1024 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
1025 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
1026 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
1027 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
1028 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
1029 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
1031 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1034 TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
1037 GLenum fmt2glFmt(D3DFORMAT fmt) {
1041 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
1042 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
1043 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
1044 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
1045 case D3DFMT_R5G6B5: retVal = GL_RGB; break;
1046 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
1048 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1051 TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
1054 DWORD fmt2glType(D3DFORMAT fmt) {
1058 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
1059 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
1060 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
1061 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5; break;
1062 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
1063 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
1065 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
1068 TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
1072 int SOURCEx_RGB_EXT(DWORD arg) {
1074 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
1075 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
1076 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
1077 case D3DTSS_ALPHAARG0:
1078 case D3DTSS_ALPHAARG1:
1079 case D3DTSS_ALPHAARG2:
1081 FIXME("Invalid arg %ld\n", arg);
1082 return GL_SOURCE0_RGB_EXT;
1085 int OPERANDx_RGB_EXT(DWORD arg) {
1087 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
1088 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
1089 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
1090 case D3DTSS_ALPHAARG0:
1091 case D3DTSS_ALPHAARG1:
1092 case D3DTSS_ALPHAARG2:
1094 FIXME("Invalid arg %ld\n", arg);
1095 return GL_OPERAND0_RGB_EXT;
1098 int SOURCEx_ALPHA_EXT(DWORD arg) {
1100 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
1101 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
1102 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
1103 case D3DTSS_COLORARG0:
1104 case D3DTSS_COLORARG1:
1105 case D3DTSS_COLORARG2:
1107 FIXME("Invalid arg %ld\n", arg);
1108 return GL_SOURCE0_ALPHA_EXT;
1111 int OPERANDx_ALPHA_EXT(DWORD arg) {
1113 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
1114 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
1115 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
1116 case D3DTSS_COLORARG0:
1117 case D3DTSS_COLORARG1:
1118 case D3DTSS_COLORARG2:
1120 FIXME("Invalid arg %ld\n", arg);
1121 return GL_OPERAND0_ALPHA_EXT;
1124 GLenum StencilOp(DWORD op) {
1126 case D3DSTENCILOP_KEEP : return GL_KEEP;
1127 case D3DSTENCILOP_ZERO : return GL_ZERO;
1128 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
1129 case D3DSTENCILOP_INCRSAT : return GL_INCR;
1130 case D3DSTENCILOP_DECRSAT : return GL_DECR;
1131 case D3DSTENCILOP_INVERT : return GL_INVERT;
1132 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op D3DSTENCILOP_INCR\n");
1133 return GL_INCR; /* Fixme - needs to support wrap */
1134 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op D3DSTENCILOP_DECR\n");
1135 return GL_DECR; /* Fixme - needs to support wrap */
1137 FIXME("Invalid stencil op %ld\n", op);
1145 void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand)
1147 BOOL isAlphaReplicate = FALSE;
1148 BOOL isComplement = FALSE;
1150 *operand = GL_SRC_COLOR;
1151 *source = GL_TEXTURE;
1153 /* Catch alpha replicate */
1154 if (iValue & D3DTA_ALPHAREPLICATE) {
1155 iValue = iValue & ~D3DTA_ALPHAREPLICATE;
1156 isAlphaReplicate = TRUE;
1159 /* Catch Complement */
1160 if (iValue & D3DTA_COMPLEMENT) {
1161 iValue = iValue & ~D3DTA_COMPLEMENT;
1162 isComplement = TRUE;
1165 /* Calculate the operand */
1166 if (isAlphaReplicate && !isComplement) {
1167 *operand = GL_SRC_ALPHA;
1168 } else if (isAlphaReplicate && isComplement) {
1169 *operand = GL_ONE_MINUS_SRC_ALPHA;
1170 } else if (isComplement) {
1172 *operand = GL_ONE_MINUS_SRC_ALPHA;
1174 *operand = GL_ONE_MINUS_SRC_COLOR;
1178 *operand = GL_SRC_ALPHA;
1180 *operand = GL_SRC_COLOR;
1184 /* Calculate the source */
1185 switch (iValue & D3DTA_SELECTMASK) {
1186 case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT;
1188 case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT;
1190 case D3DTA_TEXTURE: *source = GL_TEXTURE;
1192 case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT;
1194 case D3DTA_SPECULAR:
1196 * According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
1197 * isnt supported until base GL supports it
1198 * There is no concept of temp registers as far as I can tell
1202 FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
1203 *source = GL_TEXTURE;
1208 /* Apply the current values to the specified texture stage */
1209 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
1210 ICOM_THIS(IDirect3DDevice8Impl,iface);
1214 /* Make appropriate texture active */
1215 if (This->isMultiTexture) {
1216 #if defined(GL_VERSION_1_3)
1217 glActiveTexture(GL_TEXTURE0 + Stage);
1219 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
1221 checkGLcall("glActiveTextureARB");
1222 } else if (Stage > 0) {
1223 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
1226 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
1227 for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
1228 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
1231 /* Note the D3DRS value applies to all textures, but GL has one
1232 per texture, so apply it now ready to be used! */
1234 col[0] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR]>> 16) & 0xFF) / 255.0;
1235 col[1] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 8 ) & 0xFF) / 255.0;
1236 col[2] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 0 ) & 0xFF) / 255.0;
1237 col[3] = ((This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR] >> 24 ) & 0xFF) / 255.0;
1239 D3DCOLORTOGLFLOAT4(This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR], col);
1240 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
1241 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
1243 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
1246 /* IDirect3D IUnknown parts follow: */
1247 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
1249 ICOM_THIS(IDirect3DDevice8Impl,iface);
1251 if (IsEqualGUID(riid, &IID_IUnknown)
1252 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
1253 IDirect3DDevice8Impl_AddRef(iface);
1258 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
1259 return E_NOINTERFACE;
1262 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
1263 ICOM_THIS(IDirect3DDevice8Impl,iface);
1264 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
1265 return ++(This->ref);
1268 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
1269 ICOM_THIS(IDirect3DDevice8Impl,iface);
1270 ULONG ref = --This->ref;
1271 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
1273 HeapFree(GetProcessHeap(), 0, This);
1278 /* IDirect3DDevice Interface follow: */
1279 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
1280 ICOM_THIS(IDirect3DDevice8Impl,iface);
1281 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
1285 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
1286 ICOM_THIS(IDirect3DDevice8Impl,iface);
1287 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
1289 * pretend we have 32MB of any type of memory queried.
1291 return (1024*1024*32);
1294 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
1295 ICOM_THIS(IDirect3DDevice8Impl,iface);
1296 FIXME("(%p) : stub\n", This); return D3D_OK;
1298 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
1299 ICOM_THIS(IDirect3DDevice8Impl,iface);
1300 TRACE("(%p) : returning %p\n", This, This->direct3d8);
1303 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
1305 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
1308 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
1309 ICOM_THIS(IDirect3DDevice8Impl,iface);
1310 FIXME("(%p) : stub, calling idirect3d for now\n", This);
1311 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
1314 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
1319 ICOM_THIS(IDirect3DDevice8Impl,iface);
1320 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
1321 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
1322 pMode->RefreshRate = 85; /*FIXME: How to identify? */
1324 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1325 bpp = GetDeviceCaps(hdc, BITSPIXEL);
1329 case 8: pMode->Format = D3DFMT_R8G8B8; break;
1330 case 16: pMode->Format = D3DFMT_R5G6B5; break;
1331 case 24: pMode->Format = D3DFMT_R8G8B8; break;
1332 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
1334 FIXME("Unrecognized display mode format\n");
1335 pMode->Format = D3DFMT_UNKNOWN;
1338 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format);
1341 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
1342 ICOM_THIS(IDirect3DDevice8Impl,iface);
1343 TRACE("(%p) copying to %p\n", This, pParameters);
1344 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
1347 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
1348 ICOM_THIS(IDirect3DDevice8Impl,iface);
1349 FIXME("(%p) : stub\n", This); return D3D_OK;
1351 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) {
1352 ICOM_THIS(IDirect3DDevice8Impl,iface);
1353 FIXME("(%p) : stub\n", This); return;
1355 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
1356 ICOM_THIS(IDirect3DDevice8Impl,iface);
1357 FIXME("(%p) : stub\n", This); return D3D_OK;
1359 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
1360 ICOM_THIS(IDirect3DDevice8Impl,iface);
1361 FIXME("(%p) : stub\n", This);
1365 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
1366 ICOM_THIS(IDirect3DDevice8Impl,iface);
1367 FIXME("(%p) : stub\n", This); return D3D_OK;
1369 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
1370 ICOM_THIS(IDirect3DDevice8Impl,iface);
1371 TRACE("(%p) : complete stub!\n", This);
1375 glXSwapBuffers(This->display, This->win);
1376 checkGLcall("glXSwapBuffers");
1382 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
1383 ICOM_THIS(IDirect3DDevice8Impl,iface);
1384 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
1385 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
1387 if (BackBuffer > This->PresentParms.BackBufferCount - 1) {
1388 FIXME("Only one backBuffer currently supported\n");
1389 return D3DERR_INVALIDCALL;
1392 /* Note inc ref on returned surface */
1393 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
1397 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
1398 ICOM_THIS(IDirect3DDevice8Impl,iface);
1399 FIXME("(%p) : stub\n", This);
1402 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags,CONST D3DGAMMARAMP* pRamp) {
1403 ICOM_THIS(IDirect3DDevice8Impl,iface);
1404 FIXME("(%p) : stub\n", This); return;
1406 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
1407 ICOM_THIS(IDirect3DDevice8Impl,iface);
1408 FIXME("(%p) : stub\n", This); return;
1410 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
1411 D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) {
1412 IDirect3DTexture8Impl *object;
1417 ICOM_THIS(IDirect3DDevice8Impl,iface);
1419 /* Allocate the storage for the device */
1420 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, Pool);
1421 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
1422 object->lpVtbl = &Direct3DTexture8_Vtbl;
1423 object->Device = This;
1424 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->device);*/
1425 object->ResourceType = D3DRTYPE_TEXTURE;
1427 object->width = Width;
1428 object->height = Height;
1429 object->levels = Levels;
1430 object->usage = Usage;
1431 object->format = Format;
1434 /* Calculate levels for mip mapping */
1439 while (tmpW > 1 && tmpH > 1) {
1440 tmpW = max(1, tmpW / 2);
1441 tmpH = max(1, tmpH / 2);
1444 TRACE("Calculated levels = %d\n", object->levels);
1447 /* Generate all the surfaces */
1450 for (i = 0; i < object->levels; i++)
1452 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
1453 object->surfaces[i]->Container = (IUnknown*) object;
1454 /*IUnknown_AddRef(object->surfaces[i]->Container);*/
1455 object->surfaces[i]->myDesc.Usage = Usage;
1456 object->surfaces[i]->myDesc.Pool = Pool ;
1458 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
1459 tmpW = max(1, tmpW / 2);
1460 tmpH = max(1, tmpH / 2);
1463 *ppTexture = (LPDIRECT3DTEXTURE8) object;
1466 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) {
1468 IDirect3DVolumeTexture8Impl *object;
1474 ICOM_THIS(IDirect3DDevice8Impl,iface);
1476 /* Allocate the storage for it */
1477 TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, Width, Height, Depth, Levels, Usage, Format, Pool);
1478 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
1479 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
1480 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
1481 object->Device = This;
1482 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1485 object->width = Width;
1486 object->height = Height;
1487 object->depth = Depth;
1488 object->levels = Levels;
1489 object->usage = Usage;
1490 object->format = Format;
1492 /* Calculate levels for mip mapping */
1498 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
1499 tmpW = max(1, tmpW / 2);
1500 tmpH = max(1, tmpH / 2);
1501 tmpD = max(1, tmpD / 2);
1504 TRACE("Calculated levels = %d\n", object->levels);
1507 /* Generate all the surfaces */
1512 for (i = 0; i < object->levels; i++)
1514 IDirect3DVolume8Impl *volume;
1516 /* Create the volume - No entry point for this seperately?? */
1517 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
1518 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
1520 volume->lpVtbl = &Direct3DVolume8_Vtbl;
1521 volume->Device = This;
1522 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) volume->Device);*/
1523 volume->ResourceType = D3DRTYPE_VOLUME;
1524 volume->Container = (IUnknown*) object;
1525 /*IUnknown_AddRef(volume->Container);*/
1528 volume->myDesc.Width = Width;
1529 volume->myDesc.Height = Height;
1530 volume->myDesc.Depth = Depth;
1531 volume->myDesc.Format = Format;
1532 volume->myDesc.Type = D3DRTYPE_VOLUME;
1533 volume->myDesc.Pool = Pool;
1534 volume->myDesc.Usage = Usage;
1535 volume->bytesPerPixel = bytesPerPixel(Format);
1536 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
1537 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
1539 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Depth, Format,
1540 volume, volume->allocatedMemory, volume->myDesc.Size);
1542 tmpW = max(1, tmpW / 2);
1543 tmpH = max(1, tmpH / 2);
1544 tmpD = max(1, tmpD / 2);
1547 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8) object;
1550 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
1552 IDirect3DCubeTexture8Impl *object;
1553 ICOM_THIS(IDirect3DDevice8Impl,iface);
1557 /* Allocate the storage for it */
1558 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This, EdgeLength, Levels, Usage, Format, Pool);
1559 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
1560 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
1562 object->Device = This;
1563 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1564 object->ResourceType = D3DRTYPE_CUBETEXTURE;
1566 object->edgeLength = EdgeLength;
1567 object->levels = Levels;
1568 object->usage = Usage;
1569 object->format = Format;
1571 /* Calculate levels for mip mapping */
1576 tmpW = max(1, tmpW / 2);
1579 TRACE("Calculated levels = %d\n", object->levels);
1582 /* Generate all the surfaces */
1584 for (i = 0; i < object->levels; i++) {
1585 /* Create the 6 faces */
1586 for (j = 0; j < 6; j++) {
1587 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
1588 object->surfaces[j][i]->Container = (IUnknown*) object;
1589 /*IUnknown_AddRef(object->surfaces[j][i]->Container);*/
1590 object->surfaces[j][i]->myDesc.Usage = Usage;
1591 object->surfaces[j][i]->myDesc.Pool = Pool;
1592 /*object->surfaces[j][i]->myDesc.Format = Format;*/
1594 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
1595 tmpW = max(1, tmpW / 2);
1599 TRACE("(%p) : Iface@%p\n", This, object);
1600 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8)object;
1603 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
1604 IDirect3DVertexBuffer8Impl *object;
1606 ICOM_THIS(IDirect3DDevice8Impl,iface);
1608 /* Allocate the storage for the device */
1609 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
1610 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
1611 object->Device = This;
1612 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1613 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
1615 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
1616 object->currentDesc.Usage = Usage;
1617 object->currentDesc.Pool = Pool;
1618 object->currentDesc.FVF = FVF;
1619 object->currentDesc.Size = Size;
1621 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
1623 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8)object;
1627 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) {
1628 IDirect3DIndexBuffer8Impl *object;
1630 ICOM_THIS(IDirect3DDevice8Impl,iface);
1631 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This, Length, Usage, Format, Pool);
1633 /* Allocate the storage for the device */
1634 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
1635 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
1636 object->Device = This;
1637 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1639 object->ResourceType = D3DRTYPE_INDEXBUFFER;
1641 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
1642 object->currentDesc.Usage = Usage;
1643 object->currentDesc.Pool = Pool;
1644 object->currentDesc.Format = Format;
1645 object->currentDesc.Size = Length;
1647 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
1649 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
1651 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
1655 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
1656 IDirect3DSurface8Impl *object;
1658 ICOM_THIS(IDirect3DDevice8Impl,iface);
1660 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1661 if (NULL == object) {
1663 return D3DERR_OUTOFVIDEOMEMORY;
1665 *ppSurface = (LPDIRECT3DSURFACE8) object;
1666 object->lpVtbl = &Direct3DSurface8_Vtbl;
1667 object->Device = This;
1668 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1669 object->ResourceType = D3DRTYPE_SURFACE;
1670 object->Container = (IUnknown*) This;
1671 /*IUnknown_AddRef(object->Container);*/
1674 object->myDesc.Width = Width;
1675 object->myDesc.Height = Height;
1676 object->myDesc.Format = Format;
1677 object->myDesc.Type = D3DRTYPE_SURFACE;
1678 object->myDesc.Usage = D3DUSAGE_RENDERTARGET;
1679 object->myDesc.Pool = D3DPOOL_DEFAULT;
1680 object->myDesc.MultiSampleType = MultiSample;
1681 object->bytesPerPixel = bytesPerPixel(Format);
1682 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1683 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1684 object->lockable = Lockable;
1685 object->locked = FALSE;
1687 TRACE("(%p) : w(%d) h(%d) fmt(%d) lockable(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, Lockable, *ppSurface, object->allocatedMemory, object->myDesc.Size);
1690 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
1691 IDirect3DSurface8Impl *object;
1693 ICOM_THIS(IDirect3DDevice8Impl,iface);
1695 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1696 if (NULL == object) {
1698 return D3DERR_OUTOFVIDEOMEMORY;
1700 *ppSurface = (LPDIRECT3DSURFACE8) object;
1701 object->lpVtbl = &Direct3DSurface8_Vtbl;
1702 object->Device = This;
1703 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1704 object->ResourceType = D3DRTYPE_SURFACE;
1705 object->Container = (IUnknown*) This;
1706 /*IUnknown_AddRef(object->Container);*/
1709 object->myDesc.Width = Width;
1710 object->myDesc.Height = Height;
1711 object->myDesc.Format = Format;
1712 object->myDesc.Type = D3DRTYPE_SURFACE;
1713 object->myDesc.Usage = D3DUSAGE_DEPTHSTENCIL;
1714 object->myDesc.Pool = D3DPOOL_DEFAULT;
1715 object->myDesc.MultiSampleType = MultiSample;
1716 object->bytesPerPixel = bytesPerPixel(Format);
1717 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1718 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1719 object->lockable = TRUE;
1720 object->locked = FALSE;
1722 TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, *ppSurface, object->allocatedMemory, object->myDesc.Size);
1725 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
1726 IDirect3DSurface8Impl *object;
1728 ICOM_THIS(IDirect3DDevice8Impl,iface);
1730 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
1731 *ppSurface = (LPDIRECT3DSURFACE8) object;
1732 object->lpVtbl = &Direct3DSurface8_Vtbl;
1733 object->Device = This;
1734 /*IDirect3DDevice8Impl_AddRef((LPDIRECT3DDEVICE8) object->Device);*/
1735 object->ResourceType = D3DRTYPE_SURFACE;
1736 object->Container = (IUnknown*) This;
1737 /*IUnknown_AddRef(object->Container);*/
1740 object->myDesc.Width = Width;
1741 object->myDesc.Height = Height;
1742 object->myDesc.Format = Format;
1743 object->myDesc.Type = D3DRTYPE_SURFACE;
1744 object->myDesc.Usage = 0;
1745 object->myDesc.Pool = D3DPOOL_SYSTEMMEM;
1746 object->bytesPerPixel = bytesPerPixel(Format);
1747 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
1748 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
1749 object->lockable = TRUE;
1750 object->locked = FALSE;
1752 TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, *ppSurface, object->allocatedMemory, object->myDesc.Size);
1755 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,
1756 IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) {
1758 HRESULT rc = D3D_OK;
1759 IDirect3DBaseTexture8* texture = NULL;
1762 IDirect3DSurface8Impl* src = (IDirect3DSurface8Impl*) pSourceSurface;
1763 IDirect3DSurface8Impl* dst = (IDirect3DSurface8Impl*) pDestinationSurface;
1765 ICOM_THIS(IDirect3DDevice8Impl,iface);
1766 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
1767 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
1769 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1770 a sample and doesnt seem to break anything as far as I can tell */
1771 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
1772 TRACE("Formats do not match %x / %x\n", src->myDesc.Format, dst->myDesc.Format);
1773 rc = D3DERR_INVALIDCALL;
1775 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
1776 TRACE("Converting dest to same format as source, since dest was unknown\n");
1777 dst->myDesc.Format = src->myDesc.Format;
1779 /* Convert container as well */
1780 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1781 if (texture != NULL) {
1783 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1784 case D3DRTYPE_TEXTURE:
1785 ((IDirect3DTexture8Impl *)texture)->format = src->myDesc.Format;
1787 case D3DRTYPE_VOLUMETEXTURE:
1788 ((IDirect3DVolumeTexture8Impl *)texture)->format = src->myDesc.Format;
1790 case D3DRTYPE_CUBETEXTURE:
1791 ((IDirect3DCubeTexture8Impl *)texture)->format = src->myDesc.Format;
1794 FIXME("Unhandled texture type\n");
1797 /** Releasing texture after GetContainer */
1798 IDirect3DBaseTexture8_Release(texture);
1802 /* Quick if complete copy ... */
1803 if (rc == D3D_OK && cRects == 0 && pSourceRectsArray == NULL && pDestPointsArray == NULL) {
1805 if (src->myDesc.Width == dst->myDesc.Width && src->myDesc.Height == dst->myDesc.Height) {
1807 D3DLOCKED_RECT lrSrc;
1808 D3DLOCKED_RECT lrDst;
1809 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, NULL, D3DLOCK_READONLY);
1810 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, NULL, 0L);
1811 TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
1813 /*memcpy(dst->allocatedMemory, src->allocatedMemory, src->myDesc.Size);*/
1814 memcpy(lrDst.pBits, lrSrc.pBits, src->myDesc.Size);
1816 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
1817 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
1818 TRACE("Unlocked src and dst\n");
1822 FIXME("Wanted to copy all surfaces but size not compatible\n");
1823 rc = D3DERR_INVALIDCALL;
1829 if (NULL != pSourceRectsArray && NULL != pDestPointsArray) {
1831 int bytesPerPixel = ((IDirect3DSurface8Impl *)pSourceSurface)->bytesPerPixel;
1833 int pitchFrom = ((IDirect3DSurface8Impl *)pSourceSurface)->myDesc.Width * bytesPerPixel;
1834 int pitchTo = ((IDirect3DSurface8Impl *)pDestinationSurface)->myDesc.Width * bytesPerPixel;
1835 char *copyfrom = ((IDirect3DSurface8Impl *)pSourceSurface)->allocatedMemory;
1836 char *copyto = ((IDirect3DSurface8Impl *)pDestinationSurface)->allocatedMemory;
1841 /* Copy rect by rect */
1842 for (i = 0; i < cRects; i++) {
1843 CONST RECT* r = &pSourceRectsArray[i];
1844 CONST POINT* p = &pDestPointsArray[i];
1845 int copyperline = (r->right - r->left) * bytesPerPixel;
1847 D3DLOCKED_RECT lrSrc;
1848 D3DLOCKED_RECT lrDst;
1852 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top, r->right, r->bottom, p->x, p->y);
1854 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, r, D3DLOCK_READONLY);
1855 dest_rect.left = p->x;
1856 dest_rect.top = p->y;
1857 dest_rect.right = p->x + (r->right - r->left);
1858 dest_rect.left = p->y + (r->bottom - r->top);
1859 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, &dest_rect, 0L);
1860 TRACE("Locked src and dst\n");
1862 /* Find where to start */
1864 from = copyfrom + (r->top * pitchFrom) + (r->left * bytesPerPixel);
1865 to = copyto + (p->y * pitchTo) + (p->x * bytesPerPixel);
1866 /* Copy line by line */
1867 for (j = 0; j < (r->bottom - r->top); j++) {
1868 memcpy(to + (j * pitchTo), from + (j * pitchFrom), copyperline);
1872 for (j = 0; j < (r->bottom - r->top); j++) {
1873 memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline);
1876 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
1877 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
1878 TRACE("Unlocked src and dst\n");
1883 FIXME("Wanted to copy partial surfaces not implemented\n");
1884 rc = D3DERR_INVALIDCALL;
1891 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
1892 if (texture != NULL) {
1894 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) texture)) {
1895 case D3DRTYPE_TEXTURE:
1897 IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)texture;
1898 pTexture->Dirty = TRUE;
1901 case D3DRTYPE_VOLUMETEXTURE:
1903 IDirect3DVolumeTexture8Impl *pTexture = (IDirect3DVolumeTexture8Impl *)texture;
1904 pTexture->Dirty = TRUE;
1907 case D3DRTYPE_CUBETEXTURE:
1909 IDirect3DCubeTexture8Impl *pTexture = (IDirect3DCubeTexture8Impl *)texture;
1910 pTexture->Dirty = TRUE;
1914 FIXME("Unhandled texture type\n");
1917 /** Releasing texture after GetContainer */
1918 IDirect3DBaseTexture8_Release(texture);
1924 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
1925 ICOM_THIS(IDirect3DDevice8Impl,iface);
1926 FIXME("(%p) : stub\n", This);
1929 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1931 D3DLOCKED_RECT lockedRect;
1936 ICOM_THIS(IDirect3DDevice8Impl,iface);
1938 FIXME("(%p) : see if behavior correct\n", This);
1940 if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) {
1941 ERR("(%p) : surface(%p) have a invalid format\n", This, pDestSurface);
1942 return D3DERR_INVALIDCALL;
1945 wantedRect.left = 0;
1947 wantedRect.right = This->PresentParms.BackBufferWidth;
1948 wantedRect.bottom = This->PresentParms.BackBufferHeight;
1950 hr = IDirect3DSurface8Impl_LockRect(pDestSurface, &lockedRect, &wantedRect, 0);
1952 ERR("(%p) : cannot lock surface\n", This);
1953 return D3DERR_INVALIDCALL;
1960 IDirect3DSurface8Impl* tmp = ((IDirect3DSurface8Impl*) pDestSurface);
1961 FIXME("dest:%u,%u,bpp:%u\n", tmp->myDesc.Width, tmp->myDesc.Height, tmp->bytesPerPixel);
1962 FIXME("dest2:pitch%u\n", lockedRect.Pitch);
1963 FIXME("src:%u,%u\n", This->PresentParms.BackBufferWidth, This->PresentParms.BackBufferHeight);
1964 tmp = This->frontBuffer;
1965 FIXME("src2:%u,%u,bpp:%u\n", tmp->myDesc.Width, tmp->myDesc.Height, tmp->bytesPerPixel);
1970 vcheckGLcall("glFlush");
1971 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1972 vcheckGLcall("glIntegerv");
1973 glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
1974 vcheckGLcall("glIntegerv");
1976 glReadBuffer(GL_FRONT);
1977 vcheckGLcall("glReadBuffer");
1978 glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
1979 vcheckGLcall("glPixelStorei");
1983 for (j = 0; j < This->PresentParms.BackBufferHeight; ++j) {
1984 /*memcpy(lockedRect.pBits + (j * lockedRect.Pitch), This->frontBuffer->allocatedMemory + (j * i), i);*/
1985 glReadPixels(0, This->PresentParms.BackBufferHeight - j - 1, This->PresentParms.BackBufferWidth, 1,
1986 GL_BGRA, GL_UNSIGNED_BYTE, ((char*) lockedRect.pBits) + (j * lockedRect.Pitch));
1987 vcheckGLcall("glReadPixels");
1991 glReadPixels(0, 0, This->PresentParms.BackBufferWidth, This->PresentParms.BackBufferHeight,
1992 GL_BGRA, GL_UNSIGNED_BYTE, lockedRect.pBits);
1994 glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
1995 vcheckGLcall("glPixelStorei");
1996 glReadBuffer(prev_read);
1997 vcheckGLcall("glReadBuffer");
2001 hr = IDirect3DSurface8Impl_UnlockRect(pDestSurface);
2004 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
2005 ICOM_THIS(IDirect3DDevice8Impl,iface);
2007 if ((IDirect3DSurface8Impl*) pRenderTarget == This->frontBuffer && (IDirect3DSurface8Impl*) pNewZStencil == This->depthStencilBuffer) {
2008 TRACE("Trying to do a NOP SetRenderTarget operation\n");
2012 FIXME("(%p) : invalid stub expect crash newRender@%p newZStencil@%p\n", This, pRenderTarget, pNewZStencil);
2016 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
2017 ICOM_THIS(IDirect3DDevice8Impl,iface);
2019 TRACE("(%p)->(%p)\n", This, This->frontBuffer);
2021 *ppRenderTarget = (LPDIRECT3DSURFACE8) This->frontBuffer;
2022 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
2026 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
2027 ICOM_THIS(IDirect3DDevice8Impl,iface);
2029 TRACE("(%p)->(%p)\n", This, ppZStencilSurface);
2031 /* Note inc ref on returned surface */
2032 *ppZStencilSurface = (LPDIRECT3DSURFACE8) This->depthStencilBuffer;
2033 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppZStencilSurface);
2038 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
2039 ICOM_THIS(IDirect3DDevice8Impl,iface);
2040 TRACE("(%p) : stub\n", This);
2043 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
2044 ICOM_THIS(IDirect3DDevice8Impl,iface);
2045 TRACE("(%p)\n", This);
2050 checkGLcall("glFlush");
2052 /* Useful for debugging sometimes!
2053 printf("Hit Enter ...\n");
2059 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
2060 ICOM_THIS(IDirect3DDevice8Impl,iface);
2062 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
2063 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
2064 when the depth-buffer format does not contain stencil buffer information, this method fails. */
2065 GLbitfield glMask = 0;
2066 GLboolean old_ztest;
2067 GLfloat old_z_clear_value;
2068 GLint old_stencil_clear_value;
2069 GLfloat old_color_clear_value[4];
2071 CONST D3DRECT* curRect;
2073 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
2074 Count, pRects, Flags, Z, Stencil);
2077 if (Count > 0 && pRects) {
2078 glEnable(GL_SCISSOR_TEST);
2079 checkGLcall("glEnable GL_SCISSOR_TEST");
2085 for (i = 0; i < Count || i == 0; i++) {
2088 /* Note gl uses lower left, width/height */
2089 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
2090 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
2091 curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2),
2092 curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
2093 glScissor(curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2),
2094 curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
2095 checkGLcall("glScissor");
2098 /* Clear the whole screen */
2099 if (Flags & D3DCLEAR_STENCIL) {
2100 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
2101 glClearStencil(Stencil);
2102 checkGLcall("glClearStencil");
2103 glMask = glMask | GL_STENCIL_BUFFER_BIT;
2106 if (Flags & D3DCLEAR_ZBUFFER) {
2107 glGetBooleanv(GL_DEPTH_WRITEMASK, &old_ztest);
2108 glDepthMask(GL_TRUE);
2109 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
2111 checkGLcall("glClearDepth");
2112 glMask = glMask | GL_DEPTH_BUFFER_BIT;
2115 if (Flags & D3DCLEAR_TARGET) {
2116 TRACE("Clearing screen with glClear to color %lx\n", Color);
2117 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
2118 glClearColor(((Color >> 16) & 0xFF) / 255.0,
2119 ((Color >> 8) & 0xFF) / 255.0,
2120 ((Color >> 0) & 0xFF) / 255.0,
2121 ((Color >> 24) & 0xFF) / 255.0);
2122 checkGLcall("glClearColor");
2123 glMask = glMask | GL_COLOR_BUFFER_BIT;
2127 checkGLcall("glClear");
2129 if (Flags & D3DCLEAR_STENCIL) {
2130 glClearStencil(old_stencil_clear_value);
2132 if (Flags & D3DCLEAR_ZBUFFER) {
2133 glDepthMask(old_ztest);
2134 glClearDepth(old_z_clear_value);
2136 if (Flags & D3DCLEAR_TARGET) {
2137 glClearColor(old_color_clear_value[0],
2138 old_color_clear_value[1],
2139 old_color_clear_value[2],
2140 old_color_clear_value[3]);
2143 if (curRect) curRect = curRect + sizeof(D3DRECT);
2146 if (Count > 0 && pRects) {
2147 glDisable(GL_SCISSOR_TEST);
2148 checkGLcall("glDisable");
2154 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts, CONST D3DMATRIX* lpmatrix) {
2155 ICOM_THIS(IDirect3DDevice8Impl,iface);
2159 BOOL viewChanged = TRUE;
2162 /* Most of this routine, comments included copied from ddraw tree initially: */
2163 TRACE("(%p) : State=%d\n", This, d3dts);
2165 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
2166 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
2167 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
2169 /* Handle recording of state blocks */
2170 if (This->isRecordingState) {
2171 TRACE("Recording... not performing anything\n");
2176 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
2178 where ViewMat = Camera space, WorldMat = world space.
2180 In OpenGL, camera and world space is combined into GL_MODELVIEW
2181 matrix. The Projection matrix stay projection matrix. */
2183 /* After reading through both OpenGL and Direct3D documentations, I
2184 thought that D3D matrices were written in 'line major mode' transposed
2185 from OpenGL's 'column major mode'. But I found out that a simple memcpy
2186 works fine to transfer one matrix format to the other (it did not work
2187 when transposing)....
2190 1) are the documentations wrong
2191 2) does the matrix work even if they are not read correctly
2192 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
2193 loading using glLoadMatrix ?
2195 Anyway, I always use 'conv_mat' to transfer the matrices from one format
2196 to the other so that if I ever find out that I need to transpose them, I
2197 will able to do it quickly, only by changing the macro conv_mat. */
2202 case D3DTS_WORLDMATRIX(0): /* WORLDMATRIX(0) == 256! so not here */
2203 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)]);
2208 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_VIEW]);
2211 case D3DTS_PROJECTION:
2212 conv_mat(lpmatrix, &This->StateBlock->transforms[D3DTS_PROJECTION]);
2215 case D3DTS_TEXTURE0:
2216 case D3DTS_TEXTURE1:
2217 case D3DTS_TEXTURE2:
2218 case D3DTS_TEXTURE3:
2219 case D3DTS_TEXTURE4:
2220 case D3DTS_TEXTURE5:
2221 case D3DTS_TEXTURE6:
2222 case D3DTS_TEXTURE7:
2223 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
2227 FIXME("Unhandled transform state!!\n");
2232 * Indexed Vertex Blending Matrices 256 -> 511
2235 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts]);
2236 if (checkGLSupport(ARB_VERTEX_BLEND)) {
2238 } else if (checkGLSupport(EXT_VERTEX_WEIGHTING)) {
2244 * Move the GL operation to outside of switch to make it work
2245 * regardless of transform set order.
2248 if (memcmp(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX))) {
2249 glMatrixMode(GL_PROJECTION);
2250 checkGLcall("glMatrixMode");
2251 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
2252 checkGLcall("glLoadMatrixf");
2253 memcpy(&This->lastProj, &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0], sizeof(D3DMATRIX));
2255 TRACE("Skipping as projection already correct\n");
2258 glMatrixMode(GL_MODELVIEW);
2259 checkGLcall("glMatrixMode");
2260 viewChanged = FALSE;
2261 if (memcmp(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX))) {
2262 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2263 checkGLcall("glLoadMatrixf");
2264 memcpy(&This->lastView, &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0], sizeof(D3DMATRIX));
2267 /* If we are changing the View matrix, reset the light and clipping planes to the new view */
2268 if (d3dts == D3DTS_VIEW) {
2270 /* NOTE: We have to reset the positions even if the light/plane is not currently
2271 enabled, since the call to enable it will not reset the position. */
2274 for (k = 0; k < This->maxLights; k++) {
2275 glLightfv(GL_LIGHT0 + k, GL_POSITION, &This->lightPosn[k][0]);
2276 checkGLcall("glLightfv posn");
2277 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, &This->lightDirn[k][0]);
2278 checkGLcall("glLightfv dirn");
2281 /* Reset Clipping Planes if clipping is enabled */
2282 for (k = 0; k < This->clipPlanes; k++) {
2283 glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
2284 checkGLcall("glClipPlane");
2287 /* Reapply texture transforms as based off modelview when applied */
2288 for (Stage = 0; Stage < This->TextureUnits; Stage++) {
2290 /* Now apply texture transforms if not applying to the dummy textures */
2291 #if defined(GL_VERSION_1_3)
2292 glActiveTexture(GL_TEXTURE0 + Stage);
2294 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2296 checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage);");
2298 glMatrixMode(GL_TEXTURE);
2299 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
2303 conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
2304 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
2306 checkGLcall("Load matrix for texture");
2308 glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
2310 } else if (d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) {
2311 /* Now apply texture transforms if not applying to the dummy textures */
2312 Stage = d3dts - D3DTS_TEXTURE0;
2314 if (memcmp(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], sizeof(D3DMATRIX))) {
2315 memcpy(&This->lastTexTrans[Stage], &This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], sizeof(D3DMATRIX));
2317 #if defined(GL_VERSION_1_3)
2318 glActiveTexture(GL_TEXTURE0 + Stage);
2320 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2322 checkGLcall("glActiveTexture(GL_TEXTURE0 + Stage)");
2324 glMatrixMode(GL_TEXTURE);
2325 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
2329 conv_mat(&This->StateBlock->transforms[D3DTS_TEXTURE0+Stage], &fred);
2330 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_TEXTURE0+Stage].u.m[0][0]);
2332 checkGLcall("Load matrix for texture");
2333 glMatrixMode(GL_MODELVIEW); /* Always leave in model view */
2335 TRACE("Skipping texture transform as already correct\n");
2339 TRACE("Skipping view setup as view already correct\n");
2343 * Vertex Blending as described
2344 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/enums/d3dvertexblendflags.asp
2346 switch (This->UpdateStateBlock->vertex_blend) {
2347 case D3DVBF_DISABLE:
2349 if (viewChanged == TRUE ||
2350 (memcmp(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX)))) {
2351 memcpy(&This->lastWorld0, &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0], sizeof(D3DMATRIX));
2352 if (viewChanged == FALSE) {
2353 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2354 checkGLcall("glLoadMatrixf");
2356 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
2357 checkGLcall("glMultMatrixf");
2359 TRACE("Skipping as world already correct\n");
2363 case D3DVBF_1WEIGHTS:
2364 case D3DVBF_2WEIGHTS:
2365 case D3DVBF_3WEIGHTS:
2367 FIXME("valid/correct D3DVBF_[1..3]WEIGHTS\n");
2369 * doc seems to say that the weight values must be in vertex data (specified in FVF by D3DFVF_XYZB*)
2370 * so waiting for the values before matrix work
2371 for (k = 0; k < This->UpdateStateBlock->vertex_blend; ++k) {
2372 glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(k)].u.m[0][0]);
2373 checkGLcall("glMultMatrixf");
2378 case D3DVBF_TWEENING:
2380 FIXME("valid/correct D3DVBF_TWEENING\n");
2381 f = This->UpdateStateBlock->tween_factor;
2382 m.u.s._11 = f; m.u.s._12 = f; m.u.s._13 = f; m.u.s._14 = f;
2383 m.u.s._21 = f; m.u.s._22 = f; m.u.s._23 = f; m.u.s._24 = f;
2384 m.u.s._31 = f; m.u.s._32 = f; m.u.s._33 = f; m.u.s._34 = f;
2385 m.u.s._41 = f; m.u.s._42 = f; m.u.s._43 = f; m.u.s._44 = f;
2386 if (viewChanged == FALSE) {
2387 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2388 checkGLcall("glLoadMatrixf");
2390 glMultMatrixf((float *) &m.u.m[0][0]);
2391 checkGLcall("glMultMatrixf");
2394 case D3DVBF_0WEIGHTS:
2396 FIXME("valid/correct D3DVBF_0WEIGHTS\n");
2397 /* single matrix of weight 1.0f */
2398 m.u.s._11 = 1.0f; m.u.s._12 = 1.0f; m.u.s._13 = 1.0f; m.u.s._14 = 1.0f;
2399 m.u.s._21 = 1.0f; m.u.s._22 = 1.0f; m.u.s._23 = 1.0f; m.u.s._24 = 1.0f;
2400 m.u.s._31 = 1.0f; m.u.s._32 = 1.0f; m.u.s._33 = 1.0f; m.u.s._34 = 1.0f;
2401 m.u.s._41 = 1.0f; m.u.s._42 = 1.0f; m.u.s._43 = 1.0f; m.u.s._44 = 1.0f;
2402 if (viewChanged == FALSE) {
2403 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2404 checkGLcall("glLoadMatrixf");
2406 glMultMatrixf((float *) &m.u.m[0][0]);
2407 checkGLcall("glMultMatrixf");
2411 break; /* stupid compilator */
2419 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
2420 ICOM_THIS(IDirect3DDevice8Impl,iface);
2421 TRACE("(%p) : for State %d\n", This, State);
2422 memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX));
2426 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
2427 D3DMATRIX *mat = NULL;
2430 /* Note: Using UpdateStateBlock means it would be recorded in a state block change,
2431 but works regardless of recording being on.
2432 If this is found to be wrong, change to StateBlock. */
2433 ICOM_THIS(IDirect3DDevice8Impl,iface);
2434 TRACE("(%p) : For state %u\n", This, State);
2436 if (State < HIGHEST_TRANSFORMSTATE)
2438 mat = &This->UpdateStateBlock->transforms[State];
2440 FIXME("Unhandled transform state!!\n");
2443 /* Copied from ddraw code: */
2444 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);
2445 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);
2446 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);
2447 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);
2449 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);
2450 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);
2451 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);
2452 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);
2454 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);
2455 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);
2456 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);
2457 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);
2459 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);
2460 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);
2461 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);
2462 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);
2464 /* Apply change via set transform - will reapply to eg. lights this way */
2465 IDirect3DDevice8Impl_SetTransform(iface, State, &temp);
2468 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
2469 ICOM_THIS(IDirect3DDevice8Impl,iface);
2471 TRACE("(%p)\n", This);
2472 This->UpdateStateBlock->Changed.viewport = TRUE;
2473 This->UpdateStateBlock->Set.viewport = TRUE;
2474 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
2476 /* Handle recording of state blocks */
2477 if (This->isRecordingState) {
2478 TRACE("Recording... not performing anything\n");
2482 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
2483 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
2485 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
2486 checkGLcall("glDepthRange");
2487 /* Note: GL requires lower left, DirectX supplies upper left */
2488 glViewport(pViewport->X, (This->PresentParms.BackBufferHeight - (pViewport->Y + pViewport->Height)),
2489 pViewport->Width, pViewport->Height);
2490 checkGLcall("glViewport");
2496 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
2497 ICOM_THIS(IDirect3DDevice8Impl,iface);
2498 TRACE("(%p)\n", This);
2499 memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8));
2503 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
2504 ICOM_THIS(IDirect3DDevice8Impl,iface);
2506 This->UpdateStateBlock->Changed.material = TRUE;
2507 This->UpdateStateBlock->Set.material = TRUE;
2508 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
2510 /* Handle recording of state blocks */
2511 if (This->isRecordingState) {
2512 TRACE("Recording... not performing anything\n");
2517 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
2518 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
2519 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
2520 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
2521 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
2523 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->UpdateStateBlock->material.Ambient);
2524 checkGLcall("glMaterialfv");
2525 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->UpdateStateBlock->material.Diffuse);
2526 checkGLcall("glMaterialfv");
2528 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular);
2529 checkGLcall("glMaterialfv");
2530 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->UpdateStateBlock->material.Emissive);
2531 checkGLcall("glMaterialfv");
2532 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
2533 checkGLcall("glMaterialf");
2538 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
2539 ICOM_THIS(IDirect3DDevice8Impl,iface);
2540 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
2541 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
2542 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
2543 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
2544 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
2545 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
2549 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) {
2550 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
2554 ICOM_THIS(IDirect3DDevice8Impl,iface);
2555 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2557 if (Index > This->maxLights) {
2558 FIXME("Cannot handle more lights than device supports\n");
2559 return D3DERR_INVALIDCALL;
2562 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,
2563 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
2564 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
2565 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
2566 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
2567 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
2568 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
2570 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
2571 This->UpdateStateBlock->Set.lights[Index] = TRUE;
2572 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
2574 /* Handle recording of state blocks */
2575 if (This->isRecordingState) {
2576 TRACE("Recording... not performing anything\n");
2581 colRGBA[0] = pLight->Diffuse.r;
2582 colRGBA[1] = pLight->Diffuse.g;
2583 colRGBA[2] = pLight->Diffuse.b;
2584 colRGBA[3] = pLight->Diffuse.a;
2585 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
2586 checkGLcall("glLightfv");
2589 colRGBA[0] = pLight->Specular.r;
2590 colRGBA[1] = pLight->Specular.g;
2591 colRGBA[2] = pLight->Specular.b;
2592 colRGBA[3] = pLight->Specular.a;
2593 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
2594 checkGLcall("glLightfv");
2597 colRGBA[0] = pLight->Ambient.r;
2598 colRGBA[1] = pLight->Ambient.g;
2599 colRGBA[2] = pLight->Ambient.b;
2600 colRGBA[3] = pLight->Ambient.a;
2601 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
2602 checkGLcall("glLightfv");
2604 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2605 glMatrixMode(GL_MODELVIEW);
2607 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2609 /* Attenuation - Are these right? guessing... */
2610 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
2611 checkGLcall("glLightf");
2612 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
2613 checkGLcall("glLightf");
2615 quad_att = 1.4/(pLight->Range*pLight->Range);
2616 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
2617 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
2618 checkGLcall("glLightf");
2620 switch (pLight->Type) {
2621 case D3DLIGHT_POINT:
2623 This->lightPosn[Index][0] = pLight->Position.x;
2624 This->lightPosn[Index][1] = pLight->Position.y;
2625 This->lightPosn[Index][2] = pLight->Position.z;
2626 This->lightPosn[Index][3] = 1.0;
2627 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2628 checkGLcall("glLightfv");
2630 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
2631 checkGLcall("glLightf");
2638 This->lightPosn[Index][0] = pLight->Position.x;
2639 This->lightPosn[Index][1] = pLight->Position.y;
2640 This->lightPosn[Index][2] = pLight->Position.z;
2641 This->lightPosn[Index][3] = 1.0;
2642 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
2643 checkGLcall("glLightfv");
2646 This->lightDirn[Index][0] = pLight->Direction.x;
2647 This->lightDirn[Index][1] = pLight->Direction.y;
2648 This->lightDirn[Index][2] = pLight->Direction.z;
2649 This->lightDirn[Index][3] = 1.0;
2650 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
2651 checkGLcall("glLightfv");
2654 * opengl-ish and d3d-ish spot lights use too different models for the
2655 * light "intensity" as a function of the angle towards the main light direction,
2656 * so we only can approximate very roughly.
2657 * however spot lights are rather rarely used in games (if ever used at all).
2658 * furthermore if still used, probably nobody pays attention to such details.
2660 if (pLight->Falloff == 0) {
2663 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
2665 if (rho < 0.0001) rho = 0.0001f;
2666 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
2667 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
2671 case D3DLIGHT_DIRECTIONAL:
2673 This->lightPosn[Index][0] = -pLight->Direction.x;
2674 This->lightPosn[Index][1] = -pLight->Direction.y;
2675 This->lightPosn[Index][2] = -pLight->Direction.z;
2676 This->lightPosn[Index][3] = 0.0;
2677 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
2678 checkGLcall("glLightfv");
2680 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
2681 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
2686 FIXME("Unrecognized light type %d\n", pLight->Type);
2689 /* Restore the modelview matrix */
2694 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
2695 ICOM_THIS(IDirect3DDevice8Impl,iface);
2696 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
2698 if (Index > This->maxLights) {
2699 FIXME("Cannot handle more lights than device supports\n");
2700 return D3DERR_INVALIDCALL;
2703 memcpy(pLight, &This->StateBlock->lights[Index], sizeof(D3DLIGHT8));
2706 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
2707 ICOM_THIS(IDirect3DDevice8Impl,iface);
2708 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
2710 if (Index > This->maxLights) {
2711 FIXME("Cannot handle more lights than device supports\n");
2712 return D3DERR_INVALIDCALL;
2715 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
2716 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
2717 This->UpdateStateBlock->lightEnable[Index] = Enable;
2719 /* Handle recording of state blocks */
2720 if (This->isRecordingState) {
2721 TRACE("Recording... not performing anything\n");
2726 glEnable(GL_LIGHT0 + Index);
2727 checkGLcall("glEnable GL_LIGHT0+Index");
2729 glDisable(GL_LIGHT0 + Index);
2730 checkGLcall("glDisable GL_LIGHT0+Index");
2734 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
2735 ICOM_THIS(IDirect3DDevice8Impl,iface);
2736 TRACE("(%p) : for idx(%ld)\n", This, Index);
2738 if (Index > This->maxLights) {
2739 FIXME("Cannot handle more lights than device supports\n");
2740 return D3DERR_INVALIDCALL;
2743 *pEnable = This->StateBlock->lightEnable[Index];
2746 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
2747 ICOM_THIS(IDirect3DDevice8Impl,iface);
2748 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
2750 /* Validate Index */
2751 if (Index >= This->clipPlanes ) {
2752 TRACE("Application has requested clipplane this device doesnt support\n");
2753 return D3DERR_INVALIDCALL;
2756 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
2757 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
2758 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
2759 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
2760 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
2761 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
2763 /* Handle recording of state blocks */
2764 if (This->isRecordingState) {
2765 TRACE("Recording... not performing anything\n");
2771 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2772 glMatrixMode(GL_MODELVIEW);
2774 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
2776 TRACE("Clipplane [%f,%f,%f,%f]\n", This->UpdateStateBlock->clipplane[Index][0], This->UpdateStateBlock->clipplane[Index][1],
2777 This->UpdateStateBlock->clipplane[Index][2], This->UpdateStateBlock->clipplane[Index][3]);
2778 glClipPlane(GL_CLIP_PLANE0 + Index, This->UpdateStateBlock->clipplane[Index]);
2781 checkGLcall("glClipPlane");
2785 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
2786 ICOM_THIS(IDirect3DDevice8Impl,iface);
2787 TRACE("(%p) : for idx %ld\n", This, Index);
2789 /* Validate Index */
2790 if (Index >= This->clipPlanes ) {
2791 TRACE("Application has requested clipplane this device doesnt support\n");
2792 return D3DERR_INVALIDCALL;
2795 pPlane[0] = This->StateBlock->clipplane[Index][0];
2796 pPlane[1] = This->StateBlock->clipplane[Index][0];
2797 pPlane[2] = This->StateBlock->clipplane[Index][0];
2798 pPlane[3] = This->StateBlock->clipplane[Index][0];
2801 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
2802 ICOM_THIS(IDirect3DDevice8Impl,iface);
2803 DWORD OldValue = This->StateBlock->renderstate[State];
2805 TRACE("(%p)->state = %d, value = %ld\n", This, State, Value);
2806 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
2807 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
2808 This->UpdateStateBlock->renderstate[State] = Value;
2810 /* Handle recording of state blocks */
2811 if (This->isRecordingState) {
2812 TRACE("Recording... not performing anything\n");
2817 case D3DRS_FILLMODE :
2818 switch ((D3DFILLMODE) Value) {
2819 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
2820 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
2821 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
2823 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
2825 checkGLcall("glPolygonMode (fillmode)");
2828 case D3DRS_LIGHTING :
2830 glEnable(GL_LIGHTING);
2831 checkGLcall("glEnable GL_LIGHTING");
2833 glDisable(GL_LIGHTING);
2834 checkGLcall("glDisable GL_LIGHTING");
2838 case D3DRS_ZENABLE :
2839 switch ((D3DZBUFFERTYPE) Value) {
2841 glDisable(GL_DEPTH_TEST);
2842 checkGLcall("glDisable GL_DEPTH_TEST");
2845 glEnable(GL_DEPTH_TEST);
2846 checkGLcall("glEnable GL_DEPTH_TEST");
2851 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
2855 case D3DRS_CULLMODE :
2857 /* If we are culling "back faces with clockwise vertices" then
2858 set front faces to be counter clockwise and enable culling
2860 switch ((D3DCULL) Value) {
2862 glDisable(GL_CULL_FACE);
2863 checkGLcall("glDisable GL_CULL_FACE");
2866 glEnable(GL_CULL_FACE);
2867 checkGLcall("glEnable GL_CULL_FACE");
2868 glFrontFace(GL_CCW);
2869 checkGLcall("glFrontFace GL_CCW");
2870 glCullFace(GL_BACK);
2873 glEnable(GL_CULL_FACE);
2874 checkGLcall("glEnable GL_CULL_FACE");
2876 checkGLcall("glFrontFace GL_CW");
2877 glCullFace(GL_BACK);
2880 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
2884 case D3DRS_SHADEMODE :
2885 switch ((D3DSHADEMODE) Value) {
2887 glShadeModel(GL_FLAT);
2888 checkGLcall("glShadeModel");
2890 case D3DSHADE_GOURAUD:
2891 glShadeModel(GL_SMOOTH);
2892 checkGLcall("glShadeModel");
2894 case D3DSHADE_PHONG:
2895 FIXME("D3DSHADE_PHONG isnt supported?\n");
2896 return D3DERR_INVALIDCALL;
2898 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
2902 case D3DRS_DITHERENABLE :
2904 glEnable(GL_DITHER);
2905 checkGLcall("glEnable GL_DITHER");
2907 glDisable(GL_DITHER);
2908 checkGLcall("glDisable GL_DITHER");
2912 case D3DRS_ZWRITEENABLE :
2915 checkGLcall("glDepthMask");
2918 checkGLcall("glDepthMask");
2924 int glParm = GL_LESS;
2926 switch ((D3DCMPFUNC) Value) {
2927 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2928 case D3DCMP_LESS: glParm=GL_LESS; break;
2929 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2930 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2931 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2932 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2933 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2934 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2936 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2938 glDepthFunc(glParm);
2939 checkGLcall("glDepthFunc");
2943 case D3DRS_AMBIENT :
2947 col[0] = ((Value >> 16) & 0xFF) / 255.0;
2948 col[1] = ((Value >> 8) & 0xFF) / 255.0;
2949 col[2] = ((Value >> 0) & 0xFF) / 255.0;
2950 col[3] = ((Value >> 24) & 0xFF) / 255.0;
2952 D3DCOLORTOGLFLOAT4(Value, col);
2953 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
2954 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2955 checkGLcall("glLightModel for MODEL_AMBIENT");
2960 case D3DRS_ALPHABLENDENABLE :
2963 checkGLcall("glEnable GL_BLEND");
2965 glDisable(GL_BLEND);
2966 checkGLcall("glDisable GL_BLEND");
2970 case D3DRS_SRCBLEND :
2971 case D3DRS_DESTBLEND :
2973 int newVal = GL_ZERO;
2975 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2976 case D3DBLEND_ONE : newVal = GL_ONE; break;
2977 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2978 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2979 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2980 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2981 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2982 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2983 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2984 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2985 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2987 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2988 This->srcBlend = newVal;
2989 This->dstBlend = newVal;
2992 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2993 This->srcBlend = newVal;
2994 This->dstBlend = newVal;
2997 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
3000 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
3001 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
3002 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
3003 glBlendFunc(This->srcBlend, This->dstBlend);
3005 checkGLcall("glBlendFunc");
3009 case D3DRS_ALPHATESTENABLE :
3011 glEnable(GL_ALPHA_TEST);
3012 checkGLcall("glEnable GL_ALPHA_TEST");
3014 glDisable(GL_ALPHA_TEST);
3015 checkGLcall("glDisable GL_ALPHA_TEST");
3019 case D3DRS_ALPHAFUNC :
3021 int glParm = GL_LESS;
3024 glGetFloatv(GL_ALPHA_TEST_REF, &ref);
3025 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
3027 switch ((D3DCMPFUNC) Value) {
3028 case D3DCMP_NEVER: glParm=GL_NEVER; break;
3029 case D3DCMP_LESS: glParm=GL_LESS; break;
3030 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
3031 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
3032 case D3DCMP_GREATER: glParm=GL_GREATER; break;
3033 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
3034 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
3035 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
3037 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
3039 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
3040 glAlphaFunc(glParm, ref);
3041 checkGLcall("glAlphaFunc");
3045 case D3DRS_ALPHAREF :
3047 int glParm = GL_LESS;
3050 glGetIntegerv(GL_ALPHA_TEST_FUNC, &glParm);
3051 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
3053 ref = ((float) Value) / 255.0f;
3054 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
3055 glAlphaFunc(glParm, ref);
3056 checkGLcall("glAlphaFunc");
3060 case D3DRS_CLIPPLANEENABLE :
3061 case D3DRS_CLIPPING :
3063 /* Ensure we only do the changed clip planes */
3064 DWORD enable = 0xFFFFFFFF;
3065 DWORD disable = 0x00000000;
3067 /* If enabling / disabling all */
3068 if (State == D3DRS_CLIPPING) {
3070 enable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
3073 disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
3077 enable = Value & ~OldValue;
3078 disable = ~Value & OldValue;
3081 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
3082 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
3083 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
3084 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
3085 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
3086 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
3088 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
3089 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
3090 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
3091 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
3092 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
3093 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
3097 case D3DRS_BLENDOP :
3099 int glParm = GL_FUNC_ADD;
3101 switch ((D3DBLENDOP) Value) {
3102 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
3103 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
3104 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
3105 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
3106 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
3108 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
3110 TRACE("glBlendEquation(%x)\n", glParm);
3111 glBlendEquation(glParm);
3112 checkGLcall("glBlendEquation");
3116 case D3DRS_TEXTUREFACTOR :
3120 /* Note the texture color applies to all textures whereas
3121 GL_TEXTURE_ENV_COLOR applies to active only */
3124 col[0] = ((Value >> 16) & 0xFF) / 255.0f;
3125 col[1] = ((Value >> 8) & 0xFF) / 255.0f;
3126 col[2] = ((Value >> 0) & 0xFF) / 255.0f;
3127 col[3] = ((Value >> 24) & 0xFF) / 255.0f;
3129 D3DCOLORTOGLFLOAT4(Value, col);
3130 /* Set the default alpha blend color */
3131 glBlendColor(col[0], col[1], col[2], col[3]);
3132 checkGLcall("glBlendColor");
3134 /* And now the default texture color as well */
3135 for (i = 0; i < This->TextureUnits; i++) {
3137 /* Note the D3DRS value applies to all textures, but GL has one
3138 per texture, so apply it now ready to be used! */
3139 if (This->isMultiTexture) {
3140 #if defined(GL_VERSION_1_3)
3141 glActiveTexture(GL_TEXTURE0 + i);
3143 glActiveTextureARB(GL_TEXTURE0_ARB + i);
3145 checkGLcall("Activate texture.. to update const color");
3147 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3150 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
3151 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
3156 case D3DRS_SPECULARENABLE :
3159 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
3160 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
3162 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);
3163 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
3168 case D3DRS_STENCILENABLE :
3170 glEnable(GL_STENCIL_TEST);
3171 checkGLcall("glEnable GL_STENCIL_TEST");
3173 glDisable(GL_STENCIL_TEST);
3174 checkGLcall("glDisable GL_STENCIL_TEST");
3178 case D3DRS_STENCILFUNC :
3180 int glParm = GL_ALWAYS;
3182 GLuint mask = 0xFFFFFFFF;
3184 glGetIntegerv(GL_STENCIL_REF, &ref);
3185 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
3186 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
3187 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
3189 switch ((D3DCMPFUNC) Value) {
3190 case D3DCMP_NEVER: glParm=GL_NEVER; break;
3191 case D3DCMP_LESS: glParm=GL_LESS; break;
3192 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
3193 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
3194 case D3DCMP_GREATER: glParm=GL_GREATER; break;
3195 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
3196 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
3197 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
3199 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
3201 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3202 glStencilFunc(glParm, ref, mask);
3203 checkGLcall("glStencilFunc");
3207 case D3DRS_STENCILREF :
3209 int glParm = GL_ALWAYS;
3211 GLuint mask = 0xFFFFFFFF;
3213 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
3214 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
3215 glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask);
3216 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
3219 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3220 glStencilFunc(glParm, ref, mask);
3221 checkGLcall("glStencilFunc");
3225 case D3DRS_STENCILMASK :
3227 int glParm = GL_ALWAYS;
3229 GLuint mask = Value;
3231 glGetIntegerv(GL_STENCIL_REF, &ref);
3232 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
3233 glGetIntegerv(GL_STENCIL_FUNC, &glParm);
3234 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
3236 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
3237 glStencilFunc(glParm, ref, mask);
3238 checkGLcall("glStencilFunc");
3242 case D3DRS_STENCILFAIL :
3248 fail = StencilOp(Value);
3249 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
3250 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
3251 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
3252 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
3254 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3255 glStencilOp(fail, zfail, zpass);
3256 checkGLcall("glStencilOp(fail, zfail, zpass);");
3259 case D3DRS_STENCILZFAIL :
3265 glGetIntegerv(GL_STENCIL_FAIL, &fail);
3266 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
3267 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
3268 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
3269 zfail = StencilOp(Value);
3271 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3272 glStencilOp(fail, zfail, zpass);
3273 checkGLcall("glStencilOp(fail, zfail, zpass);");
3276 case D3DRS_STENCILPASS :
3282 glGetIntegerv(GL_STENCIL_FAIL, &fail);
3283 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
3284 zpass = StencilOp(Value);
3285 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
3286 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
3288 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
3289 glStencilOp(fail, zfail, zpass);
3290 checkGLcall("glStencilOp(fail, zfail, zpass);");
3294 case D3DRS_STENCILWRITEMASK :
3296 glStencilMask(Value);
3297 TRACE("glStencilMask(%lu)\n", Value);
3298 checkGLcall("glStencilMask");
3302 case D3DRS_FOGENABLE :
3304 if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
3306 checkGLcall("glEnable GL_FOG\n");
3309 checkGLcall("glDisable GL_FOG\n");
3314 case D3DRS_FOGCOLOR :
3318 col[0] = ((Value >> 16) & 0xFF) / 255.0f;
3319 col[1] = ((Value >> 8) & 0xFF) / 255.0f;
3320 col[2] = ((Value >> 0) & 0xFF) / 255.0f;
3321 col[3] = ((Value >> 24) & 0xFF) / 255.0f;
3323 D3DCOLORTOGLFLOAT4(Value, col);
3324 /* Set the default alpha blend color */
3325 glFogfv(GL_FOG_COLOR, &col[0]);
3326 checkGLcall("glFog GL_FOG_COLOR");
3330 case D3DRS_FOGTABLEMODE :
3333 case D3DFOG_NONE: /* I don't know what to do here */ break;
3334 case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
3335 case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
3336 case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
3338 FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value);
3343 case D3DRS_FOGSTART :
3345 float *f = (float*) &Value;
3346 glFogfv(GL_FOG_START, f);
3347 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
3348 TRACE("Fog Start == %f\n", *f);
3354 float *f = (float*) &Value;
3355 glFogfv(GL_FOG_END, f);
3356 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
3357 TRACE("Fog End == %f\n", *f);
3361 case D3DRS_FOGDENSITY :
3363 glFogf(GL_FOG_DENSITY, (float) Value);
3364 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
3368 case D3DRS_VERTEXBLEND :
3370 This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
3371 TRACE("Vertex Blending state to %ld\n", Value);
3375 case D3DRS_TWEENFACTOR :
3377 This->UpdateStateBlock->tween_factor = *((float*) &Value);
3378 TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
3382 case D3DRS_INDEXEDVERTEXBLENDENABLE :
3384 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
3389 case D3DRS_COLORVERTEX :
3390 case D3DRS_DIFFUSEMATERIALSOURCE :
3391 case D3DRS_SPECULARMATERIALSOURCE :
3392 case D3DRS_AMBIENTMATERIALSOURCE :
3393 case D3DRS_EMISSIVEMATERIALSOURCE :
3395 GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
3397 if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
3398 glEnable(GL_COLOR_MATERIAL);
3399 checkGLcall("glEnable GL_GL_COLOR_MATERIAL\n");
3401 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
3402 This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
3403 This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
3404 This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE],
3405 This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]);
3407 if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
3408 if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
3409 Parm = GL_AMBIENT_AND_DIFFUSE;
3413 } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
3415 } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
3417 } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
3424 glDisable(GL_COLOR_MATERIAL);
3425 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
3427 TRACE("glColorMaterial Parm=%d\n", Parm);
3428 glColorMaterial(GL_FRONT_AND_BACK, Parm);
3429 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)\n");
3433 glDisable(GL_COLOR_MATERIAL);
3434 checkGLcall("glDisable GL_GL_COLOR_MATERIAL\n");
3439 /* Unhandled yet...! */
3440 case D3DRS_LINEPATTERN :
3441 case D3DRS_LASTPIXEL :
3442 case D3DRS_ZVISIBLE :
3443 case D3DRS_EDGEANTIALIAS :
3445 case D3DRS_RANGEFOGENABLE :
3454 case D3DRS_FOGVERTEXMODE :
3455 case D3DRS_LOCALVIEWER :
3456 case D3DRS_NORMALIZENORMALS :
3457 case D3DRS_SOFTWAREVERTEXPROCESSING :
3458 case D3DRS_POINTSIZE :
3459 case D3DRS_POINTSIZE_MIN :
3460 case D3DRS_POINTSPRITEENABLE :
3461 case D3DRS_POINTSCALEENABLE :
3462 case D3DRS_POINTSCALE_A :
3463 case D3DRS_POINTSCALE_B :
3464 case D3DRS_POINTSCALE_C :
3465 case D3DRS_MULTISAMPLEANTIALIAS :
3466 case D3DRS_MULTISAMPLEMASK :
3467 case D3DRS_PATCHEDGESTYLE :
3468 case D3DRS_PATCHSEGMENTS :
3469 case D3DRS_DEBUGMONITORTOKEN :
3470 case D3DRS_POINTSIZE_MAX :
3471 case D3DRS_COLORWRITEENABLE :
3472 case D3DRS_POSITIONORDER :
3473 case D3DRS_NORMALORDER :
3474 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
3475 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
3478 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
3483 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
3484 ICOM_THIS(IDirect3DDevice8Impl,iface);
3485 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
3486 *pValue = This->StateBlock->renderstate[State];
3489 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
3490 ICOM_THIS(IDirect3DDevice8Impl,iface);
3492 TRACE("(%p)\n", This);
3494 return IDirect3DDeviceImpl_BeginStateBlock(This);
3496 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
3497 IDirect3DStateBlockImpl* pSB;
3498 ICOM_THIS(IDirect3DDevice8Impl,iface);
3501 TRACE("(%p)\n", This);
3503 res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB);
3504 *pToken = (DWORD) pSB;
3508 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3509 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3510 ICOM_THIS(IDirect3DDevice8Impl,iface);
3512 TRACE("(%p)\n", This);
3514 return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB);
3517 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3518 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3519 ICOM_THIS(IDirect3DDevice8Impl,iface);
3521 TRACE("(%p)\n", This);
3523 return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB);
3525 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
3526 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
3527 ICOM_THIS(IDirect3DDevice8Impl,iface);
3529 TRACE("(%p)\n", This);
3531 return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB);
3534 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
3535 IDirect3DStateBlockImpl* pSB;
3536 ICOM_THIS(IDirect3DDevice8Impl,iface);
3539 TRACE("(%p) : for type %d\n", This, Type);
3541 res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB);
3542 *pToken = (DWORD) pSB;
3546 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
3547 ICOM_THIS(IDirect3DDevice8Impl,iface);
3548 FIXME("(%p) : stub\n", This); return D3D_OK;
3550 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
3551 ICOM_THIS(IDirect3DDevice8Impl,iface);
3552 FIXME("(%p) : stub\n", This); return D3D_OK;
3554 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
3555 ICOM_THIS(IDirect3DDevice8Impl,iface);
3556 TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage);
3557 *ppTexture = (LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage];
3558 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
3561 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
3563 IDirect3DBaseTexture8 *oldTxt;
3564 BOOL reapplyStates = TRUE;
3566 ICOM_THIS(IDirect3DDevice8Impl,iface);
3567 D3DRESOURCETYPE textureType;
3569 oldTxt = This->UpdateStateBlock->textures[Stage];
3570 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
3572 /* Reject invalid texture units */
3573 if (Stage >= This->TextureUnits) {
3574 TRACE("Attempt to access invalid texture rejected\n");
3575 return D3DERR_INVALIDCALL;
3578 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
3579 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
3580 This->UpdateStateBlock->textures[Stage] = pTexture;
3582 /* Handle recording of state blocks */
3583 if (This->isRecordingState) {
3584 TRACE("Recording... not performing anything\n");
3588 /* Make appropriate texture active */
3589 if (This->isMultiTexture) {
3590 #if defined(GL_VERSION_1_3)
3591 glActiveTexture(GL_TEXTURE0 + Stage);
3593 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3595 checkGLcall("glActiveTextureARB");
3596 } else if (Stage>0) {
3597 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3600 /* Decrement the count of the previous texture */
3601 if (oldTxt != NULL) {
3602 IDirect3DBaseTexture8Impl_Release(oldTxt);
3606 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]);
3608 /* Now setup the texture appropraitly */
3609 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
3611 if (textureType == D3DRTYPE_TEXTURE) {
3612 IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl*) pTexture;
3614 if ((void*) oldTxt == (void*) pTexture2 && pTexture2->Dirty == FALSE) {
3615 TRACE("Skipping setting texture as old == new\n");
3616 reapplyStates = FALSE;
3619 /* Standard 2D texture */
3620 TRACE("Standard 2d texture\n");
3621 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D;
3623 /* Load up the texture now */
3624 IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture);
3626 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
3628 IDirect3DVolumeTexture8Impl *pTexture2 = (IDirect3DVolumeTexture8Impl *) pTexture;
3632 /* Standard 3D (volume) texture */
3633 TRACE("Standard 3d texture\n");
3634 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
3636 /* Load up the texture now */
3637 IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture);
3640 for (i=0; i<pTexture2->levels; i++)
3643 if (i==0 && pTexture2->volumes[i]->textureName != 0 && pTexture2->Dirty == FALSE) {
3644 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3645 checkGLcall("glBindTexture");
3646 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3648 /* No need to walk through all mip-map levels, since already all assigned */
3649 i = pTexture2->levels;
3653 if (pTexture2->volumes[i]->textureName == 0) {
3654 glGenTextures(1, &pTexture2->volumes[i]->textureName);
3655 checkGLcall("glGenTextures");
3656 TRACE("Texture %p given name %d\n", pTexture2->volumes[i], pTexture2->volumes[i]->textureName);
3659 glBindTexture(GL_TEXTURE_3D, pTexture2->volumes[i]->textureName);
3660 checkGLcall("glBindTexture");
3662 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1);
3663 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3666 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3667 GL_TEXTURE_3D, i, fmt2glintFmt(pTexture2->format), pTexture2->volumes[i]->myDesc.Width,
3668 pTexture2->volumes[i]->myDesc.Height, pTexture2->volumes[i]->myDesc.Depth,
3669 0, fmt2glFmt(pTexture2->format),fmt2glType(pTexture2->format),
3670 pTexture2->volumes[i]->allocatedMemory);
3671 glTexImage3D(GL_TEXTURE_3D, i,
3672 fmt2glintFmt(pTexture2->format),
3673 pTexture2->volumes[i]->myDesc.Width,
3674 pTexture2->volumes[i]->myDesc.Height,
3675 pTexture2->volumes[i]->myDesc.Depth,
3677 fmt2glFmt(pTexture2->format),
3678 fmt2glType(pTexture2->format),
3679 pTexture2->volumes[i]->allocatedMemory
3681 checkGLcall("glTexImage3D");
3683 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3684 pTexture2->Dirty = FALSE;
3689 } else if (textureType == D3DRTYPE_CUBETEXTURE) {
3690 /* Standard Cube texture */
3691 FIXME("Standard Cube texture\n");
3692 /*This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_4D;*/
3694 /* Load up the texture now */
3695 IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture);
3697 FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType));
3700 TRACE("Setting to no texture (ie default texture)\n");
3701 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D;
3702 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
3703 checkGLcall("glBindTexture");
3704 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
3707 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3708 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3709 if (reapplyStates) {
3710 setupTextureStates (iface, Stage);
3716 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
3717 ICOM_THIS(IDirect3DDevice8Impl,iface);
3718 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
3719 *pValue = This->UpdateStateBlock->texture_state[Stage][Type];
3723 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
3724 ICOM_THIS(IDirect3DDevice8Impl,iface);
3726 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3728 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value=%ld\n", This, Stage, Type, Value);
3730 /* Reject invalid texture units */
3731 if (Stage >= This->TextureUnits) {
3732 TRACE("Attempt to access invalid texture rejected\n");
3733 return D3DERR_INVALIDCALL;
3736 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
3737 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
3738 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
3740 /* Handle recording of state blocks */
3741 if (This->isRecordingState) {
3742 TRACE("Recording... not performing anything\n");
3746 /* Make appropriate texture active */
3747 VTRACE(("Activating appropriate texture state %ld\n", Stage));
3748 if (This->isMultiTexture) {
3749 #if defined(GL_VERSION_1_3)
3750 glActiveTexture(GL_TEXTURE0 + Stage);
3751 vcheckGLcall("glActiveTexture");
3753 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
3754 vcheckGLcall("glActiveTextureARB");
3756 } else if (Stage > 0) {
3757 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3762 case D3DTSS_MINFILTER :
3763 case D3DTSS_MIPFILTER :
3765 DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER];
3766 DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER];
3767 GLint realVal = GL_LINEAR;
3769 if (ValueMIN == D3DTEXF_POINT) {
3771 if (ValueMIP == D3DTEXF_POINT) {
3772 realVal = GL_NEAREST_MIPMAP_NEAREST;
3773 } else if (ValueMIP == D3DTEXF_LINEAR) {
3774 realVal = GL_NEAREST_MIPMAP_LINEAR;
3775 } else if (ValueMIP == D3DTEXF_NONE) {
3776 realVal = GL_NEAREST;
3778 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3779 realVal = GL_NEAREST_MIPMAP_LINEAR;
3781 } else if (ValueMIN == D3DTEXF_LINEAR) {
3783 if (ValueMIP == D3DTEXF_POINT) {
3784 realVal = GL_LINEAR_MIPMAP_NEAREST;
3785 } else if (ValueMIP == D3DTEXF_LINEAR) {
3786 realVal = GL_LINEAR_MIPMAP_LINEAR;
3787 } else if (ValueMIP == D3DTEXF_NONE) {
3788 realVal = GL_LINEAR;
3790 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
3791 realVal = GL_LINEAR_MIPMAP_LINEAR;
3793 } else if (ValueMIN == D3DTEXF_NONE) {
3794 /* Doesnt really make sense - Windows just seems to disable
3795 mipmapping when this occurs */
3796 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3797 realVal = GL_LINEAR;
3800 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
3801 realVal = GL_LINEAR_MIPMAP_LINEAR;
3804 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
3805 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
3806 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3811 case D3DTSS_MAGFILTER :
3812 if (Value == D3DTEXF_POINT) {
3813 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3814 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3815 } else if (Value == D3DTEXF_LINEAR) {
3816 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3817 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3819 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
3823 case D3DTSS_COLORARG0 :
3824 case D3DTSS_ALPHAARG0 :
3825 /* FIXME: Mesa seems to struggle setting these at the moment */
3826 /*FIXME("COLORARG0/ALPHAARG0 support still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);*/
3829 case D3DTSS_COLORARG1 :
3830 case D3DTSS_COLORARG2 :
3831 case D3DTSS_ALPHAARG1 :
3832 case D3DTSS_ALPHAARG2 :
3834 BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3835 int operand = GL_SRC_COLOR;
3836 int source = GL_TEXTURE;
3838 GetSrcAndOpFromValue(Value, isAlphaArg, &source, &operand);
3841 /* From MSDN (D3DTSS_ALPHAARG1) :
3842 The default argument is D3DTA_TEXTURE. If no texture is set for this stage,
3843 then the default argument is D3DTA_DIFFUSE.
3844 FIXME? If texture added/removed, may need to reset back as well? */
3845 if (Type == D3DTSS_ALPHAARG1 && This->StateBlock->textures[Stage] == NULL && Value == D3DTA_TEXTURE) {
3846 GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlphaArg, &source, &operand);
3848 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
3849 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
3850 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3851 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
3852 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3854 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
3855 glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
3856 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3857 glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
3858 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3863 case D3DTSS_ALPHAOP :
3864 case D3DTSS_COLOROP :
3868 int Parm = (Type == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
3870 if (Type == D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
3871 /* TODO: Disable by making this and all later levels disabled */
3872 glDisable(GL_TEXTURE_1D);
3873 checkGLcall("Disable GL_TEXTURE_1D");
3874 glDisable(GL_TEXTURE_2D);
3875 checkGLcall("Disable GL_TEXTURE_2D");
3876 glDisable(GL_TEXTURE_3D);
3877 checkGLcall("Disable GL_TEXTURE_3D");
3880 /* Enable only the appropriate texture dimension */
3881 if (Type == D3DTSS_COLOROP) {
3882 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
3883 glEnable(GL_TEXTURE_1D);
3884 checkGLcall("Enable GL_TEXTURE_1D");
3886 glDisable(GL_TEXTURE_1D);
3887 checkGLcall("Disable GL_TEXTURE_1D");
3889 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
3890 glEnable(GL_TEXTURE_2D);
3891 checkGLcall("Enable GL_TEXTURE_2D");
3893 glDisable(GL_TEXTURE_2D);
3894 checkGLcall("Disable GL_TEXTURE_2D");
3896 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
3897 glEnable(GL_TEXTURE_3D);
3898 checkGLcall("Enable GL_TEXTURE_3D");
3900 glDisable(GL_TEXTURE_3D);
3901 checkGLcall("Disable GL_TEXTURE_3D");
3905 /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
3906 if (Value != D3DTOP_DISABLE) {
3907 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
3910 /* Now set up the operand correctly */
3912 case D3DTOP_DISABLE :
3913 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3914 and it works, so ignore this op */
3915 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3918 case D3DTOP_SELECTARG1 :
3920 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3921 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3925 case D3DTOP_SELECTARG2 :
3927 BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP);
3931 /*FIXME("see if D3DTOP_SELECTARG2 behavior is correct now!\n");*/
3932 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
3933 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3934 /* GL_REPLACE, swap args 0 and 1? */
3935 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2];
3936 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
3938 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_ALPHA_EXT, source, GL_OPERAND0_ALPHA_EXT, operand);
3939 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, source);
3940 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 'source')");
3941 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operand);
3942 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 'operand')");
3944 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_RGB_EXT, source, GL_OPERAND0_RGB_EXT, operand);
3945 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, source);
3946 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')");
3947 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operand);
3948 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 'operand')");
3950 dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1];
3951 GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
3953 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_ALPHA_EXT, source, GL_OPERAND1_ALPHA_EXT, operand);
3954 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, source);
3955 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 'source')");
3956 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operand);
3957 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 'operand')");
3959 TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_RGB_EXT, source, GL_OPERAND1_RGB_EXT, operand);
3960 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, source);
3961 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 'source')");
3962 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operand);
3963 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 'operand')");
3968 case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
3969 case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
3970 case D3DTOP_MODULATE :
3973 if (Type == D3DTSS_ALPHAOP) {
3974 glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
3975 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3977 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
3978 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3980 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
3981 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3985 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
3986 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3989 case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
3990 case D3DTOP_ADDSIGNED :
3991 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
3992 vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3995 case D3DTOP_DOTPRODUCT3 :
3996 #if defined(GL_VERSION_1_3)
3998 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3999 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
4003 FIXME("DotProduct3 extension requested but not supported via this version of opengl\n");
4006 case D3DTOP_SUBTRACT :
4007 #if defined(GL_VERSION_1_3)
4008 glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT);
4009 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT)");
4014 * if ARB_texture_env_combine is supported
4015 * we can use GL_SUBTRACT_ARB here
4018 case D3DTOP_ADDSMOOTH :
4019 case D3DTOP_BLENDDIFFUSEALPHA :
4020 case D3DTOP_BLENDTEXTUREALPHA :
4021 case D3DTOP_BLENDFACTORALPHA :
4022 case D3DTOP_BLENDTEXTUREALPHAPM :
4023 case D3DTOP_BLENDCURRENTALPHA :
4024 case D3DTOP_PREMODULATE :
4025 case D3DTOP_MODULATEALPHA_ADDCOLOR :
4026 case D3DTOP_MODULATECOLOR_ADDALPHA :
4027 case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
4028 case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
4029 case D3DTOP_BUMPENVMAP :
4030 case D3DTOP_BUMPENVMAPLUMINANCE :
4031 case D3DTOP_MULTIPLYADD :
4034 FIXME("Unhandled texture operation %ld\n", Value);
4040 case D3DTSS_ADDRESSU :
4041 case D3DTSS_ADDRESSV :
4042 case D3DTSS_ADDRESSW :
4044 GLint wrapParm = GL_REPEAT;
4046 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
4047 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break;
4048 case D3DTADDRESS_BORDER: wrapParm = GL_REPEAT; break; /* FIXME: Not right, but better */
4049 #if defined(GL_VERSION_1_4)
4050 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT; break;
4051 #elif defined(GL_ARB_texture_mirrored_repeat)
4052 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT_ARB; break;
4054 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL pre-1.4 */
4056 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL */
4058 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
4059 wrapParm = GL_REPEAT;
4063 case D3DTSS_ADDRESSU:
4064 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
4065 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
4066 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
4068 case D3DTSS_ADDRESSV:
4069 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
4070 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
4071 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
4073 case D3DTSS_ADDRESSW:
4074 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
4075 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
4076 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
4079 break; /** stupic compilator */
4084 case D3DTSS_BORDERCOLOR :
4088 col[0] = ((Value >> 16) & 0xFF) / 255.0;
4089 col[1] = ((Value >> 8) & 0xFF) / 255.0;
4090 col[2] = ((Value >> 0) & 0xFF) / 255.0;
4091 col[3] = ((Value >> 24) & 0xFF) / 255.0;
4093 D3DCOLORTOGLFLOAT4(Value, col);
4094 TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value);
4095 glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
4096 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
4100 case D3DTSS_TEXCOORDINDEX :
4102 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
4105 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
4107 switch (Value & 0xFFFFFF00) {
4108 case D3DTSS_TCI_PASSTHRU:
4109 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
4112 case D3DTSS_TCI_CAMERASPACEPOSITION:
4113 /* CameraSpacePosition means use the vertex position, transformed to camera space,
4114 as the input texture coordinates for this stage's texture transformation. This
4115 equates roughly to EYE_LINEAR */
4117 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
4118 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
4119 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
4120 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
4121 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
4123 glMatrixMode(GL_MODELVIEW);
4126 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
4127 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
4128 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
4129 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
4132 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
4133 glEnable(GL_TEXTURE_GEN_S);
4134 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
4135 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
4136 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
4137 glEnable(GL_TEXTURE_GEN_T);
4138 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
4139 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
4140 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
4141 glEnable(GL_TEXTURE_GEN_R);
4142 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
4143 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
4144 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
4150 /* ? disable GL_TEXTURE_GEN_n ? */
4151 FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value);
4158 case D3DTSS_BUMPENVMAT00 :
4159 case D3DTSS_BUMPENVMAT01 :
4160 TRACE("BUMPENVMAT0%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT00, Stage, Type, Value);
4162 case D3DTSS_BUMPENVMAT10 :
4163 case D3DTSS_BUMPENVMAT11 :
4164 TRACE("BUMPENVMAT1%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT10, Stage, Type, Value);
4167 case D3DTSS_MIPMAPLODBIAS :
4168 case D3DTSS_MAXMIPLEVEL :
4169 case D3DTSS_MAXANISOTROPY :
4170 case D3DTSS_BUMPENVLSCALE :
4171 case D3DTSS_BUMPENVLOFFSET :
4172 case D3DTSS_TEXTURETRANSFORMFLAGS :
4173 case D3DTSS_RESULTARG :
4175 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
4176 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
4180 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
4181 ICOM_THIS(IDirect3DDevice8Impl,iface);
4182 TRACE("(%p) : stub\n", This); /* FIXME: Needs doing, but called often and is harmless */
4185 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) {
4186 ICOM_THIS(IDirect3DDevice8Impl,iface);
4187 FIXME("(%p) : stub\n", This); return D3D_OK;
4189 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,CONST PALETTEENTRY* pEntries) {
4190 ICOM_THIS(IDirect3DDevice8Impl,iface);
4191 FIXME("(%p) : stub\n", This); return D3D_OK;
4193 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber,PALETTEENTRY* pEntries) {
4194 ICOM_THIS(IDirect3DDevice8Impl,iface);
4195 FIXME("(%p) : stub\n", This); return D3D_OK;
4197 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
4198 ICOM_THIS(IDirect3DDevice8Impl,iface);
4199 FIXME("(%p) : stub\n", This); return D3D_OK;
4201 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
4202 ICOM_THIS(IDirect3DDevice8Impl,iface);
4203 FIXME("(%p) : stub\n", This); return D3D_OK;
4205 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) {
4207 IDirect3DVertexBuffer8 *pVB;
4209 ICOM_THIS(IDirect3DDevice8Impl,iface);
4210 pVB = This->StateBlock->stream_source[0];
4212 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This, PrimitiveType, StartVertex, PrimitiveCount);
4214 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE,
4215 This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory, StartVertex, -1, 0, NULL, 0);
4219 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
4220 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
4222 IDirect3DIndexBuffer8 *pIB;
4223 IDirect3DVertexBuffer8 *pVB;
4224 D3DINDEXBUFFER_DESC IdxBufDsc;
4226 ICOM_THIS(IDirect3DDevice8Impl,iface);
4227 pIB = This->StateBlock->pIndexData;
4228 pVB = This->StateBlock->stream_source[0];
4230 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, PrimitiveType,
4231 minIndex, NumVertices, startIndex, primCount);
4233 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
4234 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
4240 DrawPrimitiveI(iface, PrimitiveType, primCount, TRUE, This->StateBlock->VertexShader, ((IDirect3DVertexBuffer8Impl *)pVB)->allocatedMemory,
4241 This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
4246 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
4247 ICOM_THIS(IDirect3DDevice8Impl,iface);
4249 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
4251 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
4253 This->StateBlock->stream_source[0] = NULL;
4254 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
4255 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, FALSE, This->StateBlock->VertexShader, pVertexStreamZeroData,
4257 This->StateBlock->stream_stride[0] = 0;
4259 /*stream zero settings set to null at end */
4262 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
4263 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
4264 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
4265 UINT VertexStreamZeroStride) {
4267 ICOM_THIS(IDirect3DDevice8Impl,iface);
4268 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType,
4269 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
4271 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
4272 if (IndexDataFormat == D3DFMT_INDEX16) {
4278 This->StateBlock->stream_source[0] = NULL;
4279 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
4280 DrawPrimitiveI(iface, PrimitiveType, PrimitiveCount, TRUE, This->StateBlock->VertexShader, pVertexStreamZeroData,
4281 This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
4283 /*stream zero settings set to null at end */
4284 This->StateBlock->stream_stride[0] = 0;
4285 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
4289 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
4290 ICOM_THIS(IDirect3DDevice8Impl,iface);
4291 FIXME("(%p) : stub\n", This); return D3D_OK;
4293 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
4294 ICOM_THIS(IDirect3DDevice8Impl,iface);
4295 IDirect3DVertexShaderImpl* object;
4296 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4300 TRACE_(d3d_shader)("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction);
4301 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
4302 return D3DERR_INVALIDCALL;
4304 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
4305 if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
4306 return D3DERR_OUTOFVIDEOMEMORY;
4309 /** Create the Vertex Shader */
4310 res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
4311 /** TODO: check FAILED(res) */
4313 /** Create and Bind the Vertex Shader Declaration */
4314 res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
4315 /** TODO: check FAILED(res) */
4317 VertexShaders[i] = object;
4318 VertexShaderDeclarations[i] = attached_decl;
4319 *pHandle = VS_HIGHESTFIXEDFXF + i;
4323 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4324 ICOM_THIS(IDirect3DDevice8Impl,iface);
4326 This->UpdateStateBlock->VertexShader = Handle;
4327 This->UpdateStateBlock->Changed.vertexShader = TRUE;
4328 This->UpdateStateBlock->Set.vertexShader = TRUE;
4330 if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
4331 TRACE_(d3d_shader)("(%p) : Created shader, Handle=%lx\n", This, Handle);
4332 This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
4333 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
4334 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
4335 } else { /* use a fvf, so desactivate the vshader decl */
4336 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
4337 This->UpdateStateBlock->vertexShaderDecl = NULL;
4338 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
4339 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
4341 /* Handle recording of state blocks */
4342 if (This->isRecordingState) {
4343 TRACE("Recording... not performing anything\n");
4347 * TODO: merge HAL shaders context switching from prototype
4351 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4352 ICOM_THIS(IDirect3DDevice8Impl,iface);
4353 TRACE_(d3d_shader)("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
4354 *pHandle = This->StateBlock->VertexShader;
4358 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4359 ICOM_THIS(IDirect3DDevice8Impl,iface);
4360 IDirect3DVertexShaderImpl* object;
4361 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4363 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4364 return D3DERR_INVALIDCALL;
4368 * Delete Vertex Shader
4370 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
4371 if (NULL == object) {
4372 return D3DERR_INVALIDCALL;
4374 TRACE_(d3d_shader)("(%p) : freing VertexShader %p\n", This, object);
4375 /* TODO: check validity of object */
4376 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
4377 HeapFree(GetProcessHeap(), 0, (void *)object->data);
4378 HeapFree(GetProcessHeap(), 0, (void *)object);
4379 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
4382 * Delete Vertex Shader Declaration
4384 attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
4385 if (NULL == attached_decl) {
4386 return D3DERR_INVALIDCALL;
4388 TRACE_(d3d_shader)("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
4389 /* TODO: check validity of object */
4390 HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
4391 HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
4392 VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
4397 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
4398 ICOM_THIS(IDirect3DDevice8Impl,iface);
4400 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
4401 ERR_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);
4402 return D3DERR_INVALIDCALL;
4404 if (NULL == pConstantData) {
4405 return D3DERR_INVALIDCALL;
4407 if (ConstantCount > 1) {
4408 FLOAT* f = (FLOAT*)pConstantData;
4410 TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
4411 for (i = 0; i < ConstantCount; ++i) {
4412 TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
4416 FLOAT* f = (FLOAT*) pConstantData;
4417 TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
4419 This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
4420 memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
4423 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
4424 ICOM_THIS(IDirect3DDevice8Impl,iface);
4426 TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
4427 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
4428 return D3DERR_INVALIDCALL;
4430 if (NULL == pConstantData) {
4431 return D3DERR_INVALIDCALL;
4433 memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
4436 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4437 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
4438 IDirect3DVertexShaderDeclarationImpl* attached_decl;
4440 attached_decl = VERTEX_SHADER_DECL(Handle);
4441 if (NULL == attached_decl) {
4442 return D3DERR_INVALIDCALL;
4444 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
4446 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4447 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
4448 IDirect3DVertexShaderImpl* object;
4450 object = VERTEX_SHADER(Handle);
4451 if (NULL == object) {
4452 return D3DERR_INVALIDCALL;
4454 return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
4457 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
4458 ICOM_THIS(IDirect3DDevice8Impl,iface);
4459 IDirect3DIndexBuffer8 *oldIdxs;
4461 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
4462 oldIdxs = This->StateBlock->pIndexData;
4464 This->UpdateStateBlock->Changed.Indices = TRUE;
4465 This->UpdateStateBlock->Set.Indices = TRUE;
4466 This->UpdateStateBlock->pIndexData = pIndexData;
4467 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
4469 /* Handle recording of state blocks */
4470 if (This->isRecordingState) {
4471 TRACE("Recording... not performing anything\n");
4475 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
4476 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
4479 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
4480 ICOM_THIS(IDirect3DDevice8Impl,iface);
4481 FIXME("(%p) : stub\n", This);
4483 *ppIndexData = This->StateBlock->pIndexData;
4484 /* up ref count on ppindexdata */
4485 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
4486 *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
4490 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
4491 ICOM_THIS(IDirect3DDevice8Impl,iface);
4492 IDirect3DPixelShaderImpl* object;
4495 FIXME("(%p) : PixelShader not fully supported yet\n", This);
4496 if (NULL == pFunction || NULL == pHandle) {
4497 return D3DERR_INVALIDCALL;
4499 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
4500 if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
4501 return D3DERR_OUTOFVIDEOMEMORY;
4503 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
4504 if (NULL == object) {
4505 return D3DERR_OUTOFVIDEOMEMORY;
4508 object->data = NULL; /* TODO */
4510 PixelShaders[i] = object;
4511 *pHandle = VS_HIGHESTFIXEDFXF + i;
4513 object->function = pFunction;
4514 for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ;
4515 object->functionLength = i + 1;
4519 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4520 ICOM_THIS(IDirect3DDevice8Impl,iface);
4522 This->UpdateStateBlock->PixelShader = Handle;
4523 This->UpdateStateBlock->Changed.pixelShader = TRUE;
4524 This->UpdateStateBlock->Set.pixelShader = TRUE;
4526 /* Handle recording of state blocks */
4527 if (This->isRecordingState) {
4528 TRACE("Recording... not performing anything\n");
4532 /* FIXME: Quieten when not being used */
4534 FIXME("(%p) : stub %ld\n", This, Handle);
4536 TRACE("(%p) : stub %ld\n", This, Handle);
4541 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
4542 ICOM_THIS(IDirect3DDevice8Impl,iface);
4543 TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
4544 *pHandle = This->StateBlock->PixelShader;
4548 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
4549 ICOM_THIS(IDirect3DDevice8Impl,iface);
4550 IDirect3DPixelShaderImpl* object;
4552 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
4553 return D3DERR_INVALIDCALL;
4555 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
4556 TRACE("(%p) : freeing PixelShader %p\n", This, object);
4557 /* TODO: check validity of object before free */
4558 HeapFree(GetProcessHeap(), 0, (void *)object);
4559 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
4563 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
4564 ICOM_THIS(IDirect3DDevice8Impl,iface);
4565 FIXME("(%p) : stub\n", This);
4568 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
4569 ICOM_THIS(IDirect3DDevice8Impl,iface);
4570 FIXME("(%p) : stub\n", This);
4573 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
4574 ICOM_THIS(IDirect3DDevice8Impl,iface);
4575 IDirect3DPixelShaderImpl* object;
4577 object = PIXEL_SHADER(Handle);
4578 if (NULL == object) {
4579 return D3DERR_INVALIDCALL;
4581 if (NULL == pData) {
4582 *pSizeOfData = object->functionLength;
4585 if (*pSizeOfData < object->functionLength) {
4586 *pSizeOfData = object->functionLength;
4587 return D3DERR_MOREDATA;
4589 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
4590 memcpy(pData, object->function, object->functionLength);
4593 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
4594 ICOM_THIS(IDirect3DDevice8Impl,iface);
4595 FIXME("(%p) : stub\n", This); return D3D_OK;
4597 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
4598 ICOM_THIS(IDirect3DDevice8Impl,iface);
4599 FIXME("(%p) : stub\n", This); return D3D_OK;
4601 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
4602 ICOM_THIS(IDirect3DDevice8Impl,iface);
4603 FIXME("(%p) : stub\n", This); return D3D_OK;
4606 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
4607 IDirect3DVertexBuffer8 *oldSrc;
4608 ICOM_THIS(IDirect3DDevice8Impl,iface);
4610 oldSrc = This->StateBlock->stream_source[StreamNumber];
4611 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
4613 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
4614 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
4615 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
4616 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
4618 /* Handle recording of state blocks */
4619 if (This->isRecordingState) {
4620 TRACE("Recording... not performing anything\n");
4624 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
4625 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
4628 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
4629 ICOM_THIS(IDirect3DDevice8Impl,iface);
4630 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
4631 *pStream = This->StateBlock->stream_source[StreamNumber];
4632 *pStride = This->StateBlock->stream_stride[StreamNumber];
4633 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
4638 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
4640 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4641 IDirect3DDevice8Impl_QueryInterface,
4642 IDirect3DDevice8Impl_AddRef,
4643 IDirect3DDevice8Impl_Release,
4644 IDirect3DDevice8Impl_TestCooperativeLevel,
4645 IDirect3DDevice8Impl_GetAvailableTextureMem,
4646 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
4647 IDirect3DDevice8Impl_GetDirect3D,
4648 IDirect3DDevice8Impl_GetDeviceCaps,
4649 IDirect3DDevice8Impl_GetDisplayMode,
4650 IDirect3DDevice8Impl_GetCreationParameters,
4651 IDirect3DDevice8Impl_SetCursorProperties,
4652 IDirect3DDevice8Impl_SetCursorPosition,
4653 IDirect3DDevice8Impl_ShowCursor,
4654 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
4655 IDirect3DDevice8Impl_Reset,
4656 IDirect3DDevice8Impl_Present,
4657 IDirect3DDevice8Impl_GetBackBuffer,
4658 IDirect3DDevice8Impl_GetRasterStatus,
4659 IDirect3DDevice8Impl_SetGammaRamp,
4660 IDirect3DDevice8Impl_GetGammaRamp,
4661 IDirect3DDevice8Impl_CreateTexture,
4662 IDirect3DDevice8Impl_CreateVolumeTexture,
4663 IDirect3DDevice8Impl_CreateCubeTexture,
4664 IDirect3DDevice8Impl_CreateVertexBuffer,
4665 IDirect3DDevice8Impl_CreateIndexBuffer,
4666 IDirect3DDevice8Impl_CreateRenderTarget,
4667 IDirect3DDevice8Impl_CreateDepthStencilSurface,
4668 IDirect3DDevice8Impl_CreateImageSurface,
4669 IDirect3DDevice8Impl_CopyRects,
4670 IDirect3DDevice8Impl_UpdateTexture,
4671 IDirect3DDevice8Impl_GetFrontBuffer,
4672 IDirect3DDevice8Impl_SetRenderTarget,
4673 IDirect3DDevice8Impl_GetRenderTarget,
4674 IDirect3DDevice8Impl_GetDepthStencilSurface,
4675 IDirect3DDevice8Impl_BeginScene,
4676 IDirect3DDevice8Impl_EndScene,
4677 IDirect3DDevice8Impl_Clear,
4678 IDirect3DDevice8Impl_SetTransform,
4679 IDirect3DDevice8Impl_GetTransform,
4680 IDirect3DDevice8Impl_MultiplyTransform,
4681 IDirect3DDevice8Impl_SetViewport,
4682 IDirect3DDevice8Impl_GetViewport,
4683 IDirect3DDevice8Impl_SetMaterial,
4684 IDirect3DDevice8Impl_GetMaterial,
4685 IDirect3DDevice8Impl_SetLight,
4686 IDirect3DDevice8Impl_GetLight,
4687 IDirect3DDevice8Impl_LightEnable,
4688 IDirect3DDevice8Impl_GetLightEnable,
4689 IDirect3DDevice8Impl_SetClipPlane,
4690 IDirect3DDevice8Impl_GetClipPlane,
4691 IDirect3DDevice8Impl_SetRenderState,
4692 IDirect3DDevice8Impl_GetRenderState,
4693 IDirect3DDevice8Impl_BeginStateBlock,
4694 IDirect3DDevice8Impl_EndStateBlock,
4695 IDirect3DDevice8Impl_ApplyStateBlock,
4696 IDirect3DDevice8Impl_CaptureStateBlock,
4697 IDirect3DDevice8Impl_DeleteStateBlock,
4698 IDirect3DDevice8Impl_CreateStateBlock,
4699 IDirect3DDevice8Impl_SetClipStatus,
4700 IDirect3DDevice8Impl_GetClipStatus,
4701 IDirect3DDevice8Impl_GetTexture,
4702 IDirect3DDevice8Impl_SetTexture,
4703 IDirect3DDevice8Impl_GetTextureStageState,
4704 IDirect3DDevice8Impl_SetTextureStageState,
4705 IDirect3DDevice8Impl_ValidateDevice,
4706 IDirect3DDevice8Impl_GetInfo,
4707 IDirect3DDevice8Impl_SetPaletteEntries,
4708 IDirect3DDevice8Impl_GetPaletteEntries,
4709 IDirect3DDevice8Impl_SetCurrentTexturePalette,
4710 IDirect3DDevice8Impl_GetCurrentTexturePalette,
4711 IDirect3DDevice8Impl_DrawPrimitive,
4712 IDirect3DDevice8Impl_DrawIndexedPrimitive,
4713 IDirect3DDevice8Impl_DrawPrimitiveUP,
4714 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
4715 IDirect3DDevice8Impl_ProcessVertices,
4716 IDirect3DDevice8Impl_CreateVertexShader,
4717 IDirect3DDevice8Impl_SetVertexShader,
4718 IDirect3DDevice8Impl_GetVertexShader,
4719 IDirect3DDevice8Impl_DeleteVertexShader,
4720 IDirect3DDevice8Impl_SetVertexShaderConstant,
4721 IDirect3DDevice8Impl_GetVertexShaderConstant,
4722 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
4723 IDirect3DDevice8Impl_GetVertexShaderFunction,
4724 IDirect3DDevice8Impl_SetStreamSource,
4725 IDirect3DDevice8Impl_GetStreamSource,
4726 IDirect3DDevice8Impl_SetIndices,
4727 IDirect3DDevice8Impl_GetIndices,
4728 IDirect3DDevice8Impl_CreatePixelShader,
4729 IDirect3DDevice8Impl_SetPixelShader,
4730 IDirect3DDevice8Impl_GetPixelShader,
4731 IDirect3DDevice8Impl_DeletePixelShader,
4732 IDirect3DDevice8Impl_SetPixelShaderConstant,
4733 IDirect3DDevice8Impl_GetPixelShaderConstant,
4734 IDirect3DDevice8Impl_GetPixelShaderFunction,
4735 IDirect3DDevice8Impl_DrawRectPatch,
4736 IDirect3DDevice8Impl_DrawTriPatch,
4737 IDirect3DDevice8Impl_DeletePatch