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 #include "d3d8_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
37 /* Some #defines for additional diagnostics */
39 /* Per-vertex trace: */
41 #define VTRACE(A) TRACE A
47 static VERTEXSHADER8
* VertexShaders
[64];
48 static PIXELSHADER8
* PixelShaders
[64];
50 /* CreateVertexShader can return > 0xFFFF */
51 #define VS_HIGHESTFIXEDFXF 0xF0000000
53 /* Used for CreateStateBlock */
54 #define NUM_SAVEDPIXELSTATES_R 38
55 #define NUM_SAVEDPIXELSTATES_T 27
56 #define NUM_SAVEDVERTEXSTATES_R 33
57 #define NUM_SAVEDVERTEXSTATES_T 2
60 * Utility functions or macros
62 #define conv_mat(mat,gl_mat) \
64 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
65 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
66 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
67 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
68 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
71 #define VERTEX_SHADER(Handle) \
72 ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF])
74 #define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
79 extern DWORD SavedPixelStates_R
[NUM_SAVEDPIXELSTATES_R
];
80 extern DWORD SavedPixelStates_T
[NUM_SAVEDPIXELSTATES_T
];
81 extern DWORD SavedVertexStates_R
[NUM_SAVEDVERTEXSTATES_R
];
82 extern DWORD SavedVertexStates_T
[NUM_SAVEDVERTEXSTATES_T
];
84 static const float idmatrix
[16] = {
92 /* Routine common to the draw primitive and draw indexed primitive routines */
93 void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface
,
100 const void *vertexBufData
,
103 long StartVertexIndex
,
109 int NumVertexes
= NumPrimitives
;
110 VERTEXSHADER8
* vertex_shader
= NULL
;
111 BOOL useVertexShaderFunction
= FALSE
;
113 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
115 /* Dont understand how to handle multiple streams, but if a fixed
116 FVF is passed in rather than a handle, it must use stream 0 */
118 if (This
->StateBlock
.VertexShader
> VS_HIGHESTFIXEDFXF
) {
119 vertex_shader
= VERTEX_SHADER(This
->StateBlock
.VertexShader
);
120 if (NULL
== vertex_shader
) {
121 ERR("trying to use unitialised vertex shader: %lu\n", This
->StateBlock
.VertexShader
);
124 if (NULL
== vertex_shader
->function
) {
125 TRACE("vertex shader declared without program, using FVF pure mode\n");
127 useVertexShaderFunction
= TRUE
;
129 fvf
= (D3DFORMAT
) vertex_shader
->fvf
;
130 TRACE("vertex shader declared FVF: %lx\n", vertex_shader
->fvf
);
131 memset(&vertex_shader
->input
, 0, sizeof(VSHADERINPUTDATA8
));
135 int skip
= This
->StateBlock
.stream_stride
[0];
136 GLenum primType
= GL_POINTS
;
146 const void *curVtx
= NULL
;
147 const short *pIdxBufS
= NULL
;
148 const long *pIdxBufL
= NULL
;
150 BOOL isLightingOn
= FALSE
;
151 BOOL enableTexture
= FALSE
;
154 float x
=0.0, y
=0.0, z
=0.0; /* x,y,z coordinates */
155 float nx
=0.0, ny
=0.0, nz
=0.0; /* normal x,y,z coordinates */
156 float rhw
=0.0; /* rhw */
157 float ptSize
=0.0; /* Point size */
158 DWORD diffuseColor
=0; /* Diffusre Color */
159 DWORD specularColor
=0; /* Specular Color */
164 if (idxBytes
== 2) pIdxBufS
= (short *) idxData
;
165 else pIdxBufL
= (long *) idxData
;
168 /* Check vertex formats expected ? */
169 normal
= fvf
& D3DFVF_NORMAL
;
170 isRHW
= fvf
& D3DFVF_XYZRHW
;
171 numBlends
= ((fvf
& D3DFVF_POSITION_MASK
) >> 1) - 2; /* WARNING can be < 0 because -2 */
172 isLastUByte4
= fvf
& D3DFVF_LASTBETA_UBYTE4
;
173 isPtSize
= fvf
& D3DFVF_PSIZE
;
174 isDiffuse
= fvf
& D3DFVF_DIFFUSE
;
175 isSpecular
= fvf
& D3DFVF_SPECULAR
;
176 numTextures
= (fvf
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
;
178 TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d, numBlends=%d)\n",
179 fvf
, normal
, isRHW
, isPtSize
, isDiffuse
, isSpecular
, numTextures
, numBlends
);
181 /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
182 set by the appropriate render state */
184 isLightingOn
= glIsEnabled(GL_LIGHTING
);
185 glDisable(GL_LIGHTING
);
186 TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn
);
190 double height
, width
, minZ
, maxZ
;
192 * Already transformed vertex do not need transform
193 * matrices. Reset all matrices to identity.
194 * Leave the default matrix in world mode.
196 glMatrixMode(GL_PROJECTION
);
197 checkGLcall("glMatrixMode");
199 checkGLcall("glLoadIdentity");
200 glMatrixMode(GL_MODELVIEW
);
201 checkGLcall("glMatrixMode");
203 checkGLcall("glLoadIdentity");
204 height
= This
->StateBlock
.viewport
.Height
;
205 width
= This
->StateBlock
.viewport
.Width
;
206 minZ
= This
->StateBlock
.viewport
.MinZ
;
207 maxZ
= This
->StateBlock
.viewport
.MaxZ
;
208 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width
, height
, -minZ
, -maxZ
);
209 glOrtho(0.0, width
, height
, 0.0, -minZ
, -maxZ
);
210 checkGLcall("glOrtho");
212 glMatrixMode(GL_PROJECTION
);
213 checkGLcall("glMatrixMode");
214 glLoadMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_PROJECTION
].u
.m
[0][0]);
215 checkGLcall("glLoadMatrixf");
216 glMatrixMode(GL_MODELVIEW
);
217 checkGLcall("glMatrixMode");
218 glLoadMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_VIEW
].u
.m
[0][0]);
219 checkGLcall("glLoadMatrixf");
220 glMultMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_WORLDMATRIX(0)].u
.m
[0][0]);
221 checkGLcall("glMultMatrixf");
224 /* Set OpenGL to the appropriate Primitive Type */
225 switch (PrimitiveType
) {
226 case D3DPT_POINTLIST
:
228 primType
= GL_POINTS
;
229 NumVertexes
= NumPrimitives
;
235 NumVertexes
= NumPrimitives
* 2;
238 case D3DPT_LINESTRIP
:
239 TRACE("LINE_STRIP\n");
240 primType
= GL_LINE_STRIP
;
241 NumVertexes
= NumPrimitives
+ 1;
244 case D3DPT_TRIANGLELIST
:
245 TRACE("TRIANGLES\n");
246 primType
= GL_TRIANGLES
;
247 NumVertexes
= NumPrimitives
* 3;
250 case D3DPT_TRIANGLESTRIP
:
251 TRACE("TRIANGLE_STRIP\n");
252 primType
= GL_TRIANGLE_STRIP
;
253 NumVertexes
= NumPrimitives
+ 2;
256 case D3DPT_TRIANGLEFAN
:
257 TRACE("TRIANGLE_FAN\n");
258 primType
= GL_TRIANGLE_FAN
;
259 NumVertexes
= NumPrimitives
+ 2;
263 FIXME("Unhandled primitive\n");
267 /* Fixme, Ideally, only use this per-vertex code for software HAL
268 but until opengl supports all the functions returned to setup
269 vertex arrays, we need to drop down to the slow mechanism for
272 if (isPtSize
|| isDiffuse
|| useVertexShaderFunction
==TRUE
|| (numBlends
> 0)) {
273 TRACE("Using slow per-vertex code\n");
275 /* Enable this one to be able to debug what is going on, but it is slower
276 than the pointer/array version */
277 VTRACE(("glBegin(%x)\n", primType
));
280 /* Draw the primitives */
281 curVtx
= vertexBufData
+ (StartVertexIndex
* skip
);
283 for (vx_index
= 0; vx_index
< NumVertexes
; vx_index
++) {
289 VTRACE(("Idx for vertex %d = %d = %d\n", vx_index
, pIdxBufS
[StartIdx
+vx_index
], (pIdxBufS
[StartIdx
+vx_index
])));
290 curPos
= curVtx
+ ((pIdxBufS
[StartIdx
+vx_index
]) * skip
);
292 VTRACE(("Idx for vertex %d = %ld = %d\n", vx_index
, pIdxBufL
[StartIdx
+vx_index
], (pIdxBufS
[StartIdx
+vx_index
])));
293 curPos
= curVtx
+ ((pIdxBufL
[StartIdx
+vx_index
]) * skip
);
297 /* Work through the vertex buffer */
298 x
= *(float *)curPos
;
299 curPos
= curPos
+ sizeof(float);
300 y
= *(float *)curPos
;
301 curPos
= curPos
+ sizeof(float);
302 z
= *(float *)curPos
;
303 curPos
= curPos
+ sizeof(float);
304 VTRACE(("x,y,z=%f,%f,%f\n", x
,y
,z
));
306 /* RHW follows, only if transformed */
308 rhw
= *(float *)curPos
;
309 curPos
= curPos
+ sizeof(float);
310 VTRACE(("rhw=%f\n", rhw
));
316 D3DSHADERVECTOR skippedBlend
= { 0.0f
, 0.0f
, 0.0f
, 0.0f
};
317 DWORD skippedBlendLastUByte4
= 0;
319 for (i
= 0; i
< ((FALSE
== isLastUByte4
) ? numBlends
: numBlends
- 1); ++i
) {
320 ((float*)&skippedBlend
)[i
] = *(float *)curPos
;
321 curPos
= curPos
+ sizeof(float);
325 skippedBlendLastUByte4
= *(DWORD
*)curPos
;
326 curPos
= curPos
+ sizeof(DWORD
);
330 /* Vertex Normal Data (untransformed only) */
332 nx
= *(float *)curPos
;
333 curPos
= curPos
+ sizeof(float);
334 ny
= *(float *)curPos
;
335 curPos
= curPos
+ sizeof(float);
336 nz
= *(float *)curPos
;
337 curPos
= curPos
+ sizeof(float);
338 VTRACE(("nx,ny,nz=%f,%f,%f\n", nx
,ny
,nz
));
342 ptSize
= *(float *)curPos
;
343 VTRACE(("ptSize=%f\n", ptSize
));
344 curPos
= curPos
+ sizeof(float);
348 diffuseColor
= *(DWORD
*)curPos
;
349 VTRACE(("diffuseColor=%lx\n", diffuseColor
));
350 curPos
= curPos
+ sizeof(DWORD
);
354 specularColor
= *(DWORD
*)curPos
;
355 VTRACE(("specularColor=%lx\n", specularColor
));
356 curPos
= curPos
+ sizeof(DWORD
);
359 /* ToDo: Texture coords */
360 for (textureNo
= 0; textureNo
< numTextures
; ++textureNo
) {
363 if (!(This
->isMultiTexture
) && textureNo
> 0) {
364 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
367 if (textureNo
> This
->TextureUnits
) {
368 FIXME("Program using more concurrent textures than this opengl implementation support\n");
372 /* Query tex coords */
373 if (This
->StateBlock
.textures
[textureNo
] != NULL
) {
374 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8
) This
->StateBlock
.textures
[textureNo
])) {
375 case D3DRTYPE_TEXTURE
:
376 s
= *(float *)curPos
;
377 curPos
= curPos
+ sizeof(float);
378 t
= *(float *)curPos
;
379 curPos
= curPos
+ sizeof(float);
380 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo
, s
,t
));
382 if (TRUE
== useVertexShaderFunction
) {
385 if (This
->isMultiTexture
) {
386 glMultiTexCoord2fARB(GL_TEXTURE0_ARB
+ textureNo
, s
, t
);
393 case D3DRTYPE_VOLUMETEXTURE
:
394 s
= *(float *)curPos
;
395 curPos
= curPos
+ sizeof(float);
396 t
= *(float *)curPos
;
397 curPos
= curPos
+ sizeof(float);
398 r
= *(float *)curPos
;
399 curPos
= curPos
+ sizeof(float);
400 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo
, s
,t
,r
));
402 if (TRUE
== useVertexShaderFunction
) {
405 if (This
->isMultiTexture
) {
406 glMultiTexCoord3fARB(GL_TEXTURE0_ARB
+ textureNo
, s
, t
, r
);
408 glTexCoord3f(s
, t
, r
);
414 r
= 0.0f
; q
= 0.0f
; /* Avoid compiler warnings, need these vars later for other textures */
415 FIXME("Unhandled texture type\n");
418 /* Note I have seen a program actually do this, so just hide it and continue */
419 VTRACE(("Very odd - texture requested in FVF but not bound!\n"));
424 /** if vertex shader program specified ... using it */
425 if (TRUE
== useVertexShaderFunction
) {
428 * this code must become the really
429 * vs input params init
431 * because its possible to use input registers for anything
432 * and some samples use registers for other things than they are
437 * no really valid declaration, user defined input register use
438 * so fill input registers as described in vertex shader declaration
440 vshader_fill_input(vertex_shader
, This
, vertexBufData
, StartVertexIndex
,
441 (!isIndexed
) ? (vx_index
* skip
) :
442 (idxBytes
== 2) ? ((pIdxBufS
[StartIdx
+ vx_index
]) * skip
) :
443 ((pIdxBufL
[StartIdx
+ vx_index
]) * skip
));
445 memset(&vertex_shader
->output
, 0, sizeof(VSHADEROUTPUTDATA8
));
446 vshader_program_execute_SW(vertex_shader
, &vertex_shader
->input
, &vertex_shader
->output
);
448 TRACE_VECTOR(vertex_shader->output.oPos);
449 TRACE_VECTOR(vertex_shader->output.oD[0]);
450 TRACE_VECTOR(vertex_shader->output.oD[1]);
451 TRACE_VECTOR(vertex_shader->output.oT[0]);
452 TRACE_VECTOR(vertex_shader->output.oT[1]);
454 x
= vertex_shader
->output
.oPos
.x
;
455 y
= vertex_shader
->output
.oPos
.y
;
456 z
= vertex_shader
->output
.oPos
.z
;
458 if (1.0f
!= vertex_shader
->output
.oPos
.w
|| isRHW
) {
459 rhw
= vertex_shader
->output
.oPos
.w
;
461 /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/
462 glColor4fv((float*) &vertex_shader
->output
.oD
[0]);
464 /* Requires secondary color extensions to compile... */
465 if (checkGLSupport(EXT_SECONDARY_COLOR
)) {
466 /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/
467 GLExtCall(glSecondaryColor3fvEXT
)((float*) &vertex_shader
->output
.oD
[1]);
468 /*checkGLcall("glSecondaryColor3fvEXT");*/
471 /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */
472 for (textureNo
= 0; textureNo
< 4; ++textureNo
) {
475 if (!(This
->isMultiTexture
) && textureNo
> 0) {
476 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
479 /* Query tex coords */
480 if (This
->StateBlock
.textures
[textureNo
] != NULL
) {
481 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8
) This
->StateBlock
.textures
[textureNo
])) {
482 case D3DRTYPE_TEXTURE
:
483 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
484 s
= vertex_shader
->output
.oT
[textureNo
].x
;
485 t
= vertex_shader
->output
.oT
[textureNo
].y
;
486 VTRACE(("tex:%d, s,t=%f,%f\n", textureNo
, s
, t
));
487 if (This
->isMultiTexture
) {
488 glMultiTexCoord2fARB(GL_TEXTURE0_ARB
+ textureNo
, s
, t
);
489 /*checkGLcall("glMultiTexCoord2fARB");*/
492 /*checkGLcall("gTexCoord2f");*/
496 case D3DRTYPE_VOLUMETEXTURE
:
497 /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/
498 s
= vertex_shader
->output
.oT
[textureNo
].x
;
499 t
= vertex_shader
->output
.oT
[textureNo
].y
;
500 r
= vertex_shader
->output
.oT
[textureNo
].z
;
501 VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo
, s
, t
, r
));
502 if (This
->isMultiTexture
) {
503 glMultiTexCoord3fARB(GL_TEXTURE0_ARB
+ textureNo
, s
, t
, r
);
504 /*checkGLcall("glMultiTexCoord2fARB");*/
506 glTexCoord3f(s
, t
, r
);
507 /*checkGLcall("gTexCoord3f");*/
512 /* Avoid compiler warnings, need these vars later for other textures */
514 FIXME("Unhandled texture type\n");
519 if (1.0f
== rhw
|| rhw
< 0.01f
) {
520 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x
,y
,z
));
522 /*checkGLcall("glVertex3f");*/
524 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x
,y
,z
,rhw
));
525 glVertex4f(x
/ rhw
, y
/ rhw
, z
/ rhw
, 1.0f
/ rhw
);
526 /*checkGLcall("glVertex4f");*/
530 * FALSE == useVertexShaderFunction
534 /* Handle these vertexes */
536 glColor4ub((diffuseColor
>> 16) & 0xFF,
537 (diffuseColor
>> 8) & 0xFF,
538 (diffuseColor
>> 0) & 0xFF,
539 (diffuseColor
>> 24) & 0xFF);
540 VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
541 ((diffuseColor
>> 16) & 0xFF) / 255.0f
,
542 ((diffuseColor
>> 8) & 0xFF) / 255.0f
,
543 ((diffuseColor
>> 0) & 0xFF) / 255.0f
,
544 ((diffuseColor
>> 24) & 0xFF) / 255.0f
));
548 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / glNormal:nx,ny,nz=%f,%f,%f\n", x
,y
,z
,nx
,ny
,nz
));
549 glNormal3f(nx
, ny
, nz
);
552 if (1.0f
== rhw
|| rhw
< 0.01f
) {
553 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x
,y
,z
));
556 VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x
,y
,z
,rhw
));
557 glVertex4f(x
/ rhw
, y
/ rhw
, z
/ rhw
, 1.0f
/ rhw
);
563 curVtx
= curVtx
+ skip
;
568 checkGLcall("glEnd and previous calls");
571 TRACE("Using fast vertex array code\n");
573 /* Faster version, harder to debug */
574 /* Shuffle to the beginning of the vertexes to render and index from there */
575 curVtx
= vertexBufData
+ (StartVertexIndex
* skip
);
578 /* Set up the vertex pointers */
580 glVertexPointer(4, GL_FLOAT
, skip
, curPos
);
581 checkGLcall("glVertexPointer(4, ...)");
582 curPos
+= 4*sizeof(float);
584 glVertexPointer(3, GL_FLOAT
, skip
, curPos
);
585 checkGLcall("glVertexPointer(3, ...)");
586 curPos
+= 3*sizeof(float);
588 glEnableClientState(GL_VERTEX_ARRAY
);
589 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
592 /* no such functionality in the fixed function GL pipeline */
593 /* FIXME: Wont get here as will drop to slow method */
594 FIXME("Cannot handle blending data here in openGl\n");
599 glNormalPointer(GL_FLOAT
, skip
, curPos
);
600 checkGLcall("glNormalPointer");
601 glEnableClientState(GL_NORMAL_ARRAY
);
602 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
603 curPos
+= 3*sizeof(float);
605 glDisableClientState(GL_NORMAL_ARRAY
);
606 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
608 checkGLcall("glNormal3f(0, 0, 1)");
612 /* no such functionality in the fixed function GL pipeline */
613 /* FIXME: Wont get here as will drop to slow method */
614 FIXME("Cannot change ptSize here in openGl\n");
615 curPos
= curPos
+ sizeof(float);
619 glColorPointer(4, GL_UNSIGNED_BYTE
, skip
, curPos
);
620 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
621 glEnableClientState(GL_COLOR_ARRAY
);
622 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
623 curPos
+= sizeof(DWORD
);
626 glDisableClientState(GL_COLOR_ARRAY
);
627 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
628 glColor4f(1, 1, 1, 1);
629 checkGLcall("glColor4f(1, 1, 1, 1)");
632 /* Requires secondary color extensions to compile... */
635 /* FIXME: check for GL_EXT_secondary_color */
636 glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE
, skip
, curPos
);
637 checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, skip, curPos)");
638 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT
);
639 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
640 curPos
+= sizeof(DWORD
);
642 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT
);
643 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
644 glSecondaryColor3fEXT(0, 0, 0);
645 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
649 /* ToDo: Texture coords */
650 for (textureNo
= 0;textureNo
<numTextures
; textureNo
++) {
652 /* Query tex coords */
653 glClientActiveTextureARB(GL_TEXTURE0_ARB
+ textureNo
);
654 if (This
->StateBlock
.textures
[textureNo
] != NULL
) {
655 enableTexture
= TRUE
;
656 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8
) This
->StateBlock
.textures
[textureNo
])) {
657 case D3DRTYPE_TEXTURE
:
658 glTexCoordPointer(2, GL_FLOAT
, skip
, curPos
);
659 checkGLcall("glTexCoordPointer(2, ...)");
660 curPos
+= 2*sizeof(float);
661 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
662 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
665 case D3DRTYPE_VOLUMETEXTURE
:
666 glTexCoordPointer(3, GL_FLOAT
, skip
, curPos
);
667 checkGLcall("glTexCoordPointer(3, ...)");
668 curPos
+= 3*sizeof(float);
669 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
670 checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
674 FIXME("Unhandled texture type\n");
675 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
676 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
681 /* Note I have seen a program actually do this, so just hide it and continue */
682 TRACE("Very odd - texture requested in FVF but not bound!\n");
683 glMultiTexCoord4fARB(GL_TEXTURE0_ARB
+ textureNo
, 0, 0, 0, 1);
684 checkGLcall("glMultiTexCoord4f(... , 0, 0, 0, 1)");
685 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
686 checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
692 /* Finally do the drawing */
695 TRACE("glElements(%x, %d, %d, ...)\n", primType
, NumVertexes
, minIndex
);
697 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
698 glDrawElements(primType
, NumVertexes
, GL_UNSIGNED_SHORT
, idxData
+(2 * StartIdx
));
700 glDrawRangeElements(primType
, minIndex
, minIndex
+NumVertexes
-1, NumVertexes
,
701 GL_UNSIGNED_SHORT
, idxData
+(2 * StartIdx
));
704 #if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
705 glDrawElements(primType
, NumVertexes
, GL_UNSIGNED_INT
, idxData
+(4 * StartIdx
));
707 glDrawRangeElements(primType
, minIndex
, minIndex
+NumVertexes
-1, NumVertexes
,
708 GL_UNSIGNED_INT
, idxData
+(2 * StartIdx
));
711 checkGLcall("glDrawRangeElements");
715 /* Note first is now zero as we shuffled along earlier */
716 TRACE("glDrawArrays(%x, %ld, %d)\n", primType
, StartIdx
, NumVertexes
);
717 glDrawArrays(primType
, 0, NumVertexes
);
718 checkGLcall("glDrawArrays");
723 /* If no normals, restore previous lighting state */
725 if (isLightingOn
) glEnable(GL_LIGHTING
);
726 else glDisable(GL_LIGHTING
);
727 TRACE("Restored lighting to original state\n");
737 Simple utility routines used for dx -> gl mapping of byte formats
739 SHORT
bytesPerPixel(D3DFORMAT fmt
) {
743 case D3DFMT_A4R4G4B4
: retVal
= 2; break;
744 case D3DFMT_A8R8G8B8
: retVal
= 4; break;
745 case D3DFMT_X8R8G8B8
: retVal
= 4; break;
746 case D3DFMT_R8G8B8
: retVal
= 3; break;
747 case D3DFMT_R5G6B5
: retVal
= 2; break;
748 case D3DFMT_A1R5G5B5
: retVal
= 2; break;
750 /* Guess at the highest value of the above */
751 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %d\n", fmt
);
755 FIXME("Unhandled fmt %d\n", fmt
);
758 TRACE("bytes/Pxl for fmt %d = %d\n", fmt
, retVal
);
762 GLint
fmt2glintFmt(D3DFORMAT fmt
) {
766 case D3DFMT_A4R4G4B4
: retVal
= GL_RGBA4
; break;
767 case D3DFMT_A8R8G8B8
: retVal
= GL_RGBA8
; break;
768 case D3DFMT_X8R8G8B8
: retVal
= GL_RGB8
; break;
769 case D3DFMT_R8G8B8
: retVal
= GL_RGB8
; break;
770 case D3DFMT_R5G6B5
: retVal
= GL_RGB5
; break; /* fixme: internal format 6 for g? */
771 case D3DFMT_A1R5G5B5
: retVal
= GL_RGB5_A1
; break;
773 FIXME("Unhandled fmt %d\n", fmt
);
776 TRACE("fmt2glintFmt for fmt %d = %x\n", fmt
, retVal
);
779 GLenum
fmt2glFmt(D3DFORMAT fmt
) {
783 case D3DFMT_A4R4G4B4
: retVal
= GL_BGRA
; break;
784 case D3DFMT_A8R8G8B8
: retVal
= GL_BGRA
; break;
785 case D3DFMT_X8R8G8B8
: retVal
= GL_BGRA
; break;
786 case D3DFMT_R8G8B8
: retVal
= GL_BGR
; break;
787 case D3DFMT_R5G6B5
: retVal
= GL_BGR
; break;
788 case D3DFMT_A1R5G5B5
: retVal
= GL_BGRA
; break;
790 FIXME("Unhandled fmt %d\n", fmt
);
793 TRACE("fmt2glFmt for fmt %d = %x\n", fmt
, retVal
);
796 DWORD
fmt2glType(D3DFORMAT fmt
) {
800 case D3DFMT_A4R4G4B4
: retVal
= GL_UNSIGNED_SHORT_4_4_4_4_REV
; break;
801 case D3DFMT_A8R8G8B8
: retVal
= GL_UNSIGNED_BYTE
; break;
802 case D3DFMT_X8R8G8B8
: retVal
= GL_UNSIGNED_BYTE
; break;
803 case D3DFMT_R5G6B5
: retVal
= GL_UNSIGNED_SHORT_5_6_5_REV
; break;
804 case D3DFMT_R8G8B8
: retVal
= GL_UNSIGNED_BYTE
; break;
805 case D3DFMT_A1R5G5B5
: retVal
= GL_UNSIGNED_SHORT_1_5_5_5_REV
; break;
807 FIXME("Unhandled fmt %d\n", fmt
);
810 TRACE("fmt2glType for fmt %d = %x\n", fmt
, retVal
);
814 int SOURCEx_RGB_EXT(DWORD arg
) {
816 case D3DTSS_COLORARG0
: return GL_SOURCE2_RGB_EXT
;
817 case D3DTSS_COLORARG1
: return GL_SOURCE0_RGB_EXT
;
818 case D3DTSS_COLORARG2
: return GL_SOURCE1_RGB_EXT
;
819 case D3DTSS_ALPHAARG0
:
820 case D3DTSS_ALPHAARG1
:
821 case D3DTSS_ALPHAARG2
:
823 FIXME("Invalid arg %ld\n", arg
);
824 return GL_SOURCE0_RGB_EXT
;
827 int OPERANDx_RGB_EXT(DWORD arg
) {
829 case D3DTSS_COLORARG0
: return GL_OPERAND2_RGB_EXT
;
830 case D3DTSS_COLORARG1
: return GL_OPERAND0_RGB_EXT
;
831 case D3DTSS_COLORARG2
: return GL_OPERAND1_RGB_EXT
;
832 case D3DTSS_ALPHAARG0
:
833 case D3DTSS_ALPHAARG1
:
834 case D3DTSS_ALPHAARG2
:
836 FIXME("Invalid arg %ld\n", arg
);
837 return GL_OPERAND0_RGB_EXT
;
840 int SOURCEx_ALPHA_EXT(DWORD arg
) {
842 case D3DTSS_ALPHAARG0
: return GL_SOURCE2_ALPHA_EXT
;
843 case D3DTSS_ALPHAARG1
: return GL_SOURCE0_ALPHA_EXT
;
844 case D3DTSS_ALPHAARG2
: return GL_SOURCE1_ALPHA_EXT
;
845 case D3DTSS_COLORARG0
:
846 case D3DTSS_COLORARG1
:
847 case D3DTSS_COLORARG2
:
849 FIXME("Invalid arg %ld\n", arg
);
850 return GL_SOURCE0_ALPHA_EXT
;
853 int OPERANDx_ALPHA_EXT(DWORD arg
) {
855 case D3DTSS_ALPHAARG0
: return GL_OPERAND2_ALPHA_EXT
;
856 case D3DTSS_ALPHAARG1
: return GL_OPERAND0_ALPHA_EXT
;
857 case D3DTSS_ALPHAARG2
: return GL_OPERAND1_ALPHA_EXT
;
858 case D3DTSS_COLORARG0
:
859 case D3DTSS_COLORARG1
:
860 case D3DTSS_COLORARG2
:
862 FIXME("Invalid arg %ld\n", arg
);
863 return GL_OPERAND0_ALPHA_EXT
;
866 GLenum
StencilOp(DWORD op
) {
868 case D3DSTENCILOP_KEEP
: return GL_KEEP
;
869 case D3DSTENCILOP_ZERO
: return GL_ZERO
;
870 case D3DSTENCILOP_REPLACE
: return GL_REPLACE
;
871 case D3DSTENCILOP_INCRSAT
: return GL_INCR
;
872 case D3DSTENCILOP_DECRSAT
: return GL_DECR
;
873 case D3DSTENCILOP_INVERT
: return GL_INVERT
;
874 case D3DSTENCILOP_INCR
: FIXME("Unsupported stencil op %ld\n", op
);
875 return GL_INCR
; /* Fixme - needs to support wrap */
876 case D3DSTENCILOP_DECR
: FIXME("Unsupported stencil op %ld\n", op
);
877 return GL_DECR
; /* Fixme - needs to support wrap */
879 FIXME("Invalid stencil op %ld\n", op
);
884 /* Apply the current values to the specified texture stage */
885 void setupTextureStates(LPDIRECT3DDEVICE8 iface
, DWORD Stage
) {
886 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
890 /* Make appropriate texture active */
891 if (This
->isMultiTexture
) {
892 glActiveTextureARB(GL_TEXTURE0_ARB
+ Stage
);
893 checkGLcall("glActiveTextureARB");
894 } else if (Stage
> 0) {
895 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
898 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage
);
899 for (i
=1; i
<HIGHEST_TEXTURE_STATE
; i
++) {
900 IDirect3DDevice8Impl_SetTextureStageState(iface
, Stage
, i
, This
->StateBlock
.texture_state
[Stage
][i
]);
903 /* Note the D3DRS value applies to all textures, but GL has one
904 per texture, so apply it now ready to be used! */
905 col
[0] = ((This
->StateBlock
.renderstate
[D3DRS_TEXTUREFACTOR
]>> 16) & 0xFF) / 255.0;
906 col
[1] = ((This
->StateBlock
.renderstate
[D3DRS_TEXTUREFACTOR
] >> 8 ) & 0xFF) / 255.0;
907 col
[2] = ((This
->StateBlock
.renderstate
[D3DRS_TEXTUREFACTOR
] >> 0 ) & 0xFF) / 255.0;
908 col
[3] = ((This
->StateBlock
.renderstate
[D3DRS_TEXTUREFACTOR
] >> 24 ) & 0xFF) / 255.0;
909 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, &col
[0]);
910 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
912 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage
);
915 /* IDirect3D IUnknown parts follow: */
916 HRESULT WINAPI
IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface
,REFIID riid
,LPVOID
*ppobj
)
918 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
920 if (IsEqualGUID(riid
, &IID_IUnknown
)
921 || IsEqualGUID(riid
, &IID_IDirect3DDevice8
)) {
922 IDirect3DDevice8Impl_AddRef(iface
);
927 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppobj
);
928 return E_NOINTERFACE
;
931 ULONG WINAPI
IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface
) {
932 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
933 TRACE("(%p) : AddRef from %ld\n", This
, This
->ref
);
934 return ++(This
->ref
);
937 ULONG WINAPI
IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface
) {
938 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
939 ULONG ref
= --This
->ref
;
940 TRACE("(%p) : ReleaseRef to %ld\n", This
, This
->ref
);
942 HeapFree(GetProcessHeap(), 0, This
);
947 /* IDirect3DDevice Interface follow: */
948 HRESULT WINAPI
IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface
) {
949 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
950 TRACE("(%p) : stub\n", This
); /* No way of notifying yet! */
954 UINT WINAPI
IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface
) {
955 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
956 TRACE("(%p) : stub, emulating 32Mb for now\n", This
);
958 * pretend we have 32MB of any type of memory queried.
960 return (1024*1024*32);
963 HRESULT WINAPI
IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface
, DWORD Bytes
) {
964 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
965 FIXME("(%p) : stub\n", This
); return D3D_OK
;
967 HRESULT WINAPI
IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface
, IDirect3D8
** ppD3D8
) {
968 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
969 TRACE("(%p) : returning %p\n", This
, This
->direct3d8
);
972 IDirect3D8_AddRef((LPDIRECT3D8
) This
->direct3d8
);
974 *ppD3D8
= (IDirect3D8
*)This
->direct3d8
;
977 HRESULT WINAPI
IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface
, D3DCAPS8
* pCaps
) {
978 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
979 FIXME("(%p) : stub, calling idirect3d for now\n", This
);
980 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8
) This
->direct3d8
, This
->adapterNo
, This
->devType
, pCaps
);
983 HRESULT WINAPI
IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface
, D3DDISPLAYMODE
* pMode
) {
988 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
989 pMode
->Width
= GetSystemMetrics(SM_CXSCREEN
);
990 pMode
->Height
= GetSystemMetrics(SM_CYSCREEN
);
991 pMode
->RefreshRate
= 85; /*FIXME: How to identify? */
993 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
994 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
998 case 8: pMode
->Format
= D3DFMT_R8G8B8
; break;
999 case 16: pMode
->Format
= D3DFMT_R5G6B5
; break;
1000 case 24: pMode
->Format
= D3DFMT_R8G8B8
; break;
1001 case 32: pMode
->Format
= D3DFMT_A8R8G8B8
; break;
1003 FIXME("Unrecognized display mode format\n");
1004 pMode
->Format
= D3DFMT_UNKNOWN
;
1007 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%d)\n", This
, pMode
->Width
, pMode
->Height
, pMode
->RefreshRate
, pMode
->Format
);
1010 HRESULT WINAPI
IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface
, D3DDEVICE_CREATION_PARAMETERS
*pParameters
) {
1011 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1012 TRACE("(%p) copying to %p\n", This
, pParameters
);
1013 memcpy(pParameters
, &This
->CreateParms
, sizeof(D3DDEVICE_CREATION_PARAMETERS
));
1016 HRESULT WINAPI
IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface
, UINT XHotSpot
, UINT YHotSpot
, IDirect3DSurface8
* pCursorBitmap
) {
1017 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1018 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1020 void WINAPI
IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface
, UINT XScreenSpace
, UINT YScreenSpace
,DWORD Flags
) {
1021 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1022 FIXME("(%p) : stub\n", This
); return;
1024 BOOL WINAPI
IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface
, BOOL bShow
) {
1025 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1026 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1028 HRESULT WINAPI
IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
, IDirect3DSwapChain8
** pSwapChain
) {
1029 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1030 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1032 HRESULT WINAPI
IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
) {
1033 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1034 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1036 HRESULT WINAPI
IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface
, CONST RECT
* pSourceRect
,CONST RECT
* pDestRect
,HWND hDestWindowOverride
,CONST RGNDATA
* pDirtyRegion
) {
1037 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1038 TRACE("(%p) : complete stub!\n", This
);
1042 glXSwapBuffers(This
->display
, This
->win
);
1043 checkGLcall("glXSwapBuffers");
1049 HRESULT WINAPI
IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface
, UINT BackBuffer
,D3DBACKBUFFER_TYPE Type
,IDirect3DSurface8
** ppBackBuffer
) {
1050 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1051 *ppBackBuffer
= (LPDIRECT3DSURFACE8
) This
->backBuffer
;
1052 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This
, BackBuffer
, Type
, *ppBackBuffer
);
1054 /* Note inc ref on returned surface */
1055 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) *ppBackBuffer
);
1059 HRESULT WINAPI
IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface
, D3DRASTER_STATUS
* pRasterStatus
) {
1060 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1061 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1063 void WINAPI
IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface
, DWORD Flags
,CONST D3DGAMMARAMP
* pRamp
) {
1064 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1065 FIXME("(%p) : stub\n", This
); return;
1067 void WINAPI
IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface
, D3DGAMMARAMP
* pRamp
) {
1068 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1069 FIXME("(%p) : stub\n", This
); return;
1071 HRESULT WINAPI
IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface
, UINT Width
, UINT Height
, UINT Levels
, DWORD Usage
,
1072 D3DFORMAT Format
,D3DPOOL Pool
,IDirect3DTexture8
** ppTexture
) {
1073 IDirect3DTexture8Impl
*object
;
1078 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1080 /* Allocate the storage for the device */
1081 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This
, Width
, Height
, Levels
, Usage
, Format
, Pool
);
1082 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DTexture8Impl
));
1083 object
->lpVtbl
= &Direct3DTexture8_Vtbl
;
1084 object
->Device
= This
; /* FIXME: AddRef(This) */
1085 object
->ResourceType
= D3DRTYPE_TEXTURE
;
1087 object
->width
= Width
;
1088 object
->height
= Height
;
1089 object
->levels
= Levels
;
1090 object
->usage
= Usage
;
1091 object
->format
= Format
;
1092 object
->device
= This
;
1094 /* Calculate levels for mip mapping */
1099 while (tmpW
> 1 && tmpH
> 1) {
1100 tmpW
= max(1,tmpW
/ 2);
1101 tmpH
= max(1, tmpH
/ 2);
1104 TRACE("Calculated levels = %d\n", object
->levels
);
1107 /* Generate all the surfaces */
1110 for (i
=0; i
<object
->levels
; i
++)
1112 IDirect3DDevice8Impl_CreateImageSurface(iface
, tmpW
, tmpH
, Format
, (LPDIRECT3DSURFACE8
*) &object
->surfaces
[i
]);
1113 object
->surfaces
[i
]->Container
= (IUnknown
*) object
; /* FIXME: AddRef(object) */
1114 object
->surfaces
[i
]->myDesc
.Usage
= Usage
;
1115 object
->surfaces
[i
]->myDesc
.Pool
= Pool
;
1117 TRACE("Created surface level %d @ %p, memory at %p\n", i
, object
->surfaces
[i
], object
->surfaces
[i
]->allocatedMemory
);
1118 tmpW
= max(1, tmpW
/ 2);
1119 tmpH
= max(1, tmpH
/ 2);
1122 *ppTexture
= (LPDIRECT3DTEXTURE8
)object
;
1125 HRESULT WINAPI
IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface
, UINT Width
,UINT Height
,UINT Depth
,UINT Levels
,DWORD Usage
,D3DFORMAT Format
,D3DPOOL Pool
,IDirect3DVolumeTexture8
** ppVolumeTexture
) {
1127 IDirect3DVolumeTexture8Impl
*object
;
1133 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1135 /* Allocate the storage for it */
1136 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
);
1137 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVolumeTexture8Impl
));
1138 object
->lpVtbl
= &Direct3DVolumeTexture8_Vtbl
;
1139 object
->ResourceType
= D3DRTYPE_VOLUMETEXTURE
;
1143 object
->width
= Width
;
1144 object
->height
= Height
;
1145 object
->depth
= Depth
;
1146 object
->levels
= Levels
;
1147 object
->usage
= Usage
;
1148 object
->format
= Format
;
1149 object
->device
= This
;
1151 /* Calculate levels for mip mapping */
1157 while (tmpW
> 1 && tmpH
> 1 && tmpD
> 1) {
1158 tmpW
= max(1,tmpW
/ 2);
1159 tmpH
= max(1, tmpH
/ 2);
1160 tmpD
= max(1, tmpD
/ 2);
1163 TRACE("Calculated levels = %d\n", object
->levels
);
1166 /* Generate all the surfaces */
1171 for (i
=0; i
<object
->levels
; i
++)
1173 IDirect3DVolume8Impl
*volume
;
1175 /* Create the volume - No entry point for this seperately?? */
1176 volume
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVolume8Impl
));
1177 object
->volumes
[i
] = (IDirect3DVolume8Impl
*) volume
;
1179 volume
->lpVtbl
= &Direct3DVolume8_Vtbl
;
1180 volume
->Device
= This
; /* FIXME: AddRef(This) */
1181 volume
->ResourceType
= D3DRTYPE_VOLUME
;
1182 volume
->Container
= object
;
1185 volume
->myDesc
.Width
= Width
;
1186 volume
->myDesc
.Height
= Height
;
1187 volume
->myDesc
.Depth
= Depth
;
1188 volume
->myDesc
.Format
= Format
;
1189 volume
->myDesc
.Type
= D3DRTYPE_VOLUME
;
1190 volume
->myDesc
.Pool
= Pool
;
1191 volume
->myDesc
.Usage
= Usage
;
1192 volume
->bytesPerPixel
= bytesPerPixel(Format
);
1193 volume
->myDesc
.Size
= (Width
* volume
->bytesPerPixel
) * Height
* Depth
;
1194 volume
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, volume
->myDesc
.Size
);
1196 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%d) surf@%p, surfmem@%p, %d bytes\n", This
, Width
, Height
, Depth
, Format
,
1197 volume
, volume
->allocatedMemory
, volume
->myDesc
.Size
);
1199 tmpW
= max(1,tmpW
/ 2);
1200 tmpH
= max(1, tmpH
/ 2);
1201 tmpD
= max(1, tmpD
/ 2);
1204 *ppVolumeTexture
= (LPDIRECT3DVOLUMETEXTURE8
)object
;
1207 HRESULT WINAPI
IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface
, UINT EdgeLength
,UINT Levels
,DWORD Usage
,D3DFORMAT Format
,D3DPOOL Pool
,IDirect3DCubeTexture8
** ppCubeTexture
) {
1209 IDirect3DCubeTexture8Impl
*object
;
1210 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1214 /* Allocate the storage for it */
1215 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%d), Pool(%d)\n", This
, EdgeLength
, Levels
, Usage
, Format
, Pool
);
1216 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DCubeTexture8Impl
));
1217 object
->lpVtbl
= &Direct3DCubeTexture8_Vtbl
;
1219 object
->Device
= This
; /* FIXME: AddRef(This) */
1220 object
->ResourceType
= D3DRTYPE_CUBETEXTURE
;
1222 object
->edgeLength
= EdgeLength
;
1223 object
->levels
= Levels
;
1224 object
->usage
= Usage
;
1225 object
->format
= Format
;
1226 object
->device
= This
;
1228 /* Calculate levels for mip mapping */
1233 tmpW
= max(1,tmpW
/ 2);
1236 TRACE("Calculated levels = %d\n", object
->levels
);
1239 /* Generate all the surfaces */
1241 for (i
=0; i
<object
->levels
; i
++)
1243 /* Create the 6 faces */
1245 IDirect3DDevice8Impl_CreateImageSurface(iface
, tmpW
, tmpW
, Format
, (LPDIRECT3DSURFACE8
*) &object
->surfaces
[j
][i
]);
1246 object
->surfaces
[j
][i
]->Container
= (IUnknown
*) object
;
1247 object
->surfaces
[j
][i
]->myDesc
.Usage
= Usage
;
1248 object
->surfaces
[j
][i
]->myDesc
.Pool
= Pool
;
1250 TRACE("Created surface level %d @ %p, memory at %p\n", i
, object
->surfaces
[j
][i
], object
->surfaces
[j
][i
]->allocatedMemory
);
1251 tmpW
= max(1,tmpW
/ 2);
1255 TRACE("(%p) : Iface@%p\n", This
, object
);
1256 *ppCubeTexture
= (LPDIRECT3DCUBETEXTURE8
)object
;
1259 HRESULT WINAPI
IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface
, UINT Size
, DWORD Usage
,
1260 DWORD FVF
,D3DPOOL Pool
, IDirect3DVertexBuffer8
** ppVertexBuffer
) {
1261 IDirect3DVertexBuffer8Impl
*object
;
1263 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1265 /* Allocate the storage for the device */
1266 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVertexBuffer8Impl
));
1267 object
->lpVtbl
= &Direct3DVertexBuffer8_Vtbl
;
1268 object
->Device
= This
;
1269 object
->ResourceType
= D3DRTYPE_VERTEXBUFFER
;
1271 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, Size
);
1272 object
->currentDesc
.Usage
= Usage
;
1273 object
->currentDesc
.Pool
= Pool
;
1274 object
->currentDesc
.FVF
= FVF
;
1275 object
->currentDesc
.Size
= Size
;
1277 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This
, Size
, Usage
, FVF
, Pool
, object
->allocatedMemory
, object
);
1279 *ppVertexBuffer
= (LPDIRECT3DVERTEXBUFFER8
)object
;
1283 HRESULT WINAPI
IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface
, UINT Length
,DWORD Usage
,D3DFORMAT Format
,D3DPOOL Pool
,IDirect3DIndexBuffer8
** ppIndexBuffer
) {
1285 IDirect3DIndexBuffer8Impl
*object
;
1287 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1288 TRACE("(%p) : Len=%d, Use=%lx, Format=%x, Pool=%d\n", This
, Length
, Usage
, Format
, Pool
);
1290 /* Allocate the storage for the device */
1291 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DIndexBuffer8Impl
));
1292 object
->lpVtbl
= &Direct3DIndexBuffer8_Vtbl
;
1294 object
->Device
= This
;
1295 object
->ResourceType
= D3DRTYPE_INDEXBUFFER
;
1297 object
->currentDesc
.Type
= D3DRTYPE_INDEXBUFFER
;
1298 object
->currentDesc
.Usage
= Usage
;
1299 object
->currentDesc
.Pool
= Pool
;
1300 object
->currentDesc
.Format
= Format
;
1301 object
->currentDesc
.Size
= Length
;
1303 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, Length
);
1305 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This
, object
, object
->allocatedMemory
);
1307 *ppIndexBuffer
= (LPDIRECT3DINDEXBUFFER8
)object
;
1311 HRESULT WINAPI
IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface
, UINT Width
,UINT Height
,D3DFORMAT Format
,D3DMULTISAMPLE_TYPE MultiSample
,BOOL Lockable
,IDirect3DSurface8
** ppSurface
) {
1312 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1313 /* up ref count on surface, surface->container = This */
1314 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1316 HRESULT WINAPI
IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface
, UINT Width
,UINT Height
,D3DFORMAT Format
,D3DMULTISAMPLE_TYPE MultiSample
,IDirect3DSurface8
** ppSurface
) {
1317 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1318 /* surface->container = This */
1319 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1321 HRESULT WINAPI
IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface
, UINT Width
,UINT Height
,D3DFORMAT Format
,IDirect3DSurface8
** ppSurface
) {
1322 IDirect3DSurface8Impl
*object
;
1324 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1326 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DSurface8Impl
));
1327 *ppSurface
= (LPDIRECT3DSURFACE8
) object
;
1328 object
->lpVtbl
= &Direct3DSurface8_Vtbl
;
1329 object
->Device
= This
;
1330 object
->ResourceType
= D3DRTYPE_SURFACE
;
1331 object
->Container
= (IUnknown
*) This
;
1334 object
->myDesc
.Width
= Width
;
1335 object
->myDesc
.Height
= Height
;
1336 object
->myDesc
.Format
= Format
;
1337 object
->myDesc
.Type
= D3DRTYPE_SURFACE
;
1338 /*object->myDesc.Usage */
1339 object
->myDesc
.Pool
= D3DPOOL_SYSTEMMEM
;
1340 object
->bytesPerPixel
= bytesPerPixel(Format
);
1341 object
->myDesc
.Size
= (Width
* object
->bytesPerPixel
) * Height
;
1342 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->myDesc
.Size
);
1344 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
);
1347 HRESULT WINAPI
IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
* pSourceSurface
,CONST RECT
* pSourceRectsArray
,UINT cRects
,
1348 IDirect3DSurface8
* pDestinationSurface
,CONST POINT
* pDestPointsArray
) {
1350 HRESULT rc
= D3D_OK
;
1351 IDirect3DBaseTexture8
* texture
= NULL
;
1354 IDirect3DSurface8Impl
*src
= (IDirect3DSurface8Impl
*) pSourceSurface
;
1355 IDirect3DSurface8Impl
*dst
= (IDirect3DSurface8Impl
*) pDestinationSurface
;
1357 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1358 TRACE("(%p) srcsur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This
,
1359 pSourceSurface
, pSourceRectsArray
, cRects
, pDestinationSurface
, pDestPointsArray
);
1361 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1362 a sample and doesnt seem to break anything as far as I can tell */
1363 if (src
->myDesc
.Format
!= dst
->myDesc
.Format
&& (dst
->myDesc
.Format
!= D3DFMT_UNKNOWN
)) {
1364 TRACE("Formats do not match %x / %x\n", src
->myDesc
.Format
, dst
->myDesc
.Format
);
1365 rc
= D3DERR_INVALIDCALL
;
1367 } else if (dst
->myDesc
.Format
== D3DFMT_UNKNOWN
) {
1368 TRACE("Converting dest to same format as source, since dest was unknown\n");
1369 dst
->myDesc
.Format
= src
->myDesc
.Format
;
1371 /* Convert container as well */
1372 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8
) dst
, &IID_IDirect3DBaseTexture8
, (void**) &texture
); /* FIXME: Which refid? */
1373 if (texture
!= NULL
) {
1375 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8
) texture
)) {
1376 case D3DRTYPE_TEXTURE
:
1377 ((IDirect3DTexture8Impl
*)texture
)->format
= src
->myDesc
.Format
;
1379 case D3DRTYPE_VOLUMETEXTURE
:
1380 ((IDirect3DVolumeTexture8Impl
*)texture
)->format
= src
->myDesc
.Format
;
1382 case D3DRTYPE_CUBETEXTURE
:
1383 ((IDirect3DCubeTexture8Impl
*)texture
)->format
= src
->myDesc
.Format
;
1386 FIXME("Unhandled texture type\n");
1389 /** Releasing texture after GetContainer */
1390 IDirect3DBaseTexture8_Release(texture
);
1394 /* Quick if complete copy ... */
1395 if (rc
== D3D_OK
&& (cRects
== 0 && pSourceRectsArray
==NULL
&& pDestPointsArray
==NULL
&&
1396 src
->myDesc
.Width
== dst
->myDesc
.Width
&&
1397 src
->myDesc
.Height
== dst
->myDesc
.Height
)) {
1398 TRACE("Direct copy as surfaces are equal, w=%d, h=%d\n", dst
->myDesc
.Width
, dst
->myDesc
.Height
);
1399 memcpy(dst
->allocatedMemory
, src
->allocatedMemory
, src
->myDesc
.Size
);
1403 int bytesPerPixel
= ((IDirect3DSurface8Impl
*)pSourceSurface
)->bytesPerPixel
;
1404 int pitchFrom
= ((IDirect3DSurface8Impl
*)pSourceSurface
)->myDesc
.Width
* bytesPerPixel
;
1405 int pitchTo
= ((IDirect3DSurface8Impl
*)pDestinationSurface
)->myDesc
.Width
* bytesPerPixel
;
1407 void *copyfrom
= ((IDirect3DSurface8Impl
*)pSourceSurface
)->allocatedMemory
;
1408 void *copyto
= ((IDirect3DSurface8Impl
*)pDestinationSurface
)->allocatedMemory
;
1410 /* Copy rect by rect */
1411 for (i
=0; i
<cRects
; i
++) {
1412 CONST RECT
*r
= &pSourceRectsArray
[i
];
1413 CONST POINT
*p
= &pDestPointsArray
[i
];
1416 int copyperline
= (r
->right
- r
->left
) * bytesPerPixel
;
1419 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i
, r
->left
, r
->top
,
1420 r
->right
, r
->bottom
, p
->x
, p
->y
);
1422 /* Find where to start */
1423 from
= copyfrom
+ (r
->top
* pitchFrom
) + (r
->left
* bytesPerPixel
);
1424 to
= copyto
+ (p
->y
* pitchTo
) + (p
->x
* bytesPerPixel
);
1426 /* Copy line by line */
1427 for (j
=0; j
<(r
->bottom
- r
->top
); j
++) {
1428 memcpy(to
+ (j
*pitchTo
), from
+ (j
*pitchFrom
), copyperline
);
1435 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8
) dst
, &IID_IDirect3DBaseTexture8
, (void**) &texture
); /* FIXME: Which refid? */
1436 if (texture
!= NULL
) {
1438 switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8
) texture
)) {
1439 case D3DRTYPE_TEXTURE
:
1441 IDirect3DTexture8Impl
*pTexture
= (IDirect3DTexture8Impl
*)texture
;
1442 pTexture
->Dirty
= TRUE
;
1445 case D3DRTYPE_VOLUMETEXTURE
:
1447 IDirect3DVolumeTexture8Impl
*pTexture
= (IDirect3DVolumeTexture8Impl
*)texture
;
1448 pTexture
->Dirty
= TRUE
;
1451 case D3DRTYPE_CUBETEXTURE
:
1453 IDirect3DCubeTexture8Impl
*pTexture
= (IDirect3DCubeTexture8Impl
*)texture
;
1454 pTexture
->Dirty
= TRUE
;
1458 FIXME("Unhandled texture type\n");
1461 /** Releasing texture after GetContainer */
1462 IDirect3DBaseTexture8_Release(texture
);
1468 HRESULT WINAPI
IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface
, IDirect3DBaseTexture8
* pSourceTexture
,IDirect3DBaseTexture8
* pDestinationTexture
) {
1469 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1470 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1472 HRESULT WINAPI
IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
* pDestSurface
) {
1473 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1474 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1476 HRESULT WINAPI
IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
* pRenderTarget
,IDirect3DSurface8
* pNewZStencil
) {
1477 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1478 FIXME("(%p) : stub\n", This
);
1482 HRESULT WINAPI
IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
** ppRenderTarget
) {
1483 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1484 /*TRACE("(%p) : returning %p\n", This, This->renderTarget); */
1485 FIXME("(%p) : stub\n", This
);
1488 **ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1489 *IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1494 HRESULT WINAPI
IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
** ppZStencilSurface
) {
1496 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1498 /* Note inc ref on returned surface *
1499 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer); */
1501 FIXME("(%p) : stub\n", This
);
1505 HRESULT WINAPI
IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface
) {
1506 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1507 TRACE("(%p) : stub\n", This
);
1510 HRESULT WINAPI
IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface
) {
1511 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1512 TRACE("(%p)\n", This
);
1517 checkGLcall("glFlush");
1519 /* Useful for debugging sometimes!
1520 printf("Hit Enter ...\n");
1526 HRESULT WINAPI
IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface
, DWORD Count
,CONST D3DRECT
* pRects
,DWORD Flags
,D3DCOLOR Color
,float Z
,DWORD Stencil
) {
1527 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1529 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1530 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1531 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1532 GLbitfield glMask
= 0;
1534 CONST D3DRECT
*curRect
;
1536 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This
,
1537 Count
, pRects
, Flags
, Z
, Stencil
);
1540 if (Count
> 0 && pRects
) {
1541 glEnable(GL_SCISSOR_TEST
);
1542 checkGLcall("glEnable GL_SCISSOR_TEST");
1548 for (i
=0;i
<Count
|| i
==0; i
++) {
1551 /* Note gl uses lower left, width/height */
1552 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This
, curRect
,
1553 curRect
->x1
, curRect
->y1
, curRect
->x2
, curRect
->y2
,
1554 curRect
->x1
, curRect
->y2
, curRect
->x2
- curRect
->x1
, curRect
->y2
- curRect
->y1
);
1555 glScissor(curRect
->x1
, curRect
->y2
, curRect
->x2
- curRect
->x1
, curRect
->y2
- curRect
->y1
);
1556 checkGLcall("glScissor");
1559 /* Clear the whole screen */
1560 if (Flags
& D3DCLEAR_STENCIL
) {
1561 glClearStencil(Stencil
);
1562 checkGLcall("glClearStencil");
1563 glMask
= glMask
| GL_STENCIL_BUFFER_BIT
;
1566 if (Flags
& D3DCLEAR_ZBUFFER
) {
1568 checkGLcall("glClearDepth");
1569 glMask
= glMask
| GL_DEPTH_BUFFER_BIT
;
1572 if (Flags
& D3DCLEAR_TARGET
) {
1573 TRACE("Clearing screen with glClear to color %lx\n", Color
);
1574 glClearColor(((Color
>> 16) & 0xFF) / 255.0, ((Color
>> 8) & 0xFF) / 255.0,
1575 ((Color
>> 0) & 0xFF) / 255.0, ((Color
>> 24) & 0xFF) / 255.0);
1576 checkGLcall("glClearColor");
1577 glMask
= glMask
| GL_COLOR_BUFFER_BIT
;
1581 checkGLcall("glClear");
1583 if (curRect
) curRect
= curRect
+ sizeof(D3DRECT
);
1586 if (Count
> 0 && pRects
) {
1587 glDisable(GL_SCISSOR_TEST
);
1588 checkGLcall("glDisable");
1594 HRESULT WINAPI
IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface
, D3DTRANSFORMSTATETYPE d3dts
,CONST D3DMATRIX
* lpmatrix
) {
1595 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1598 /* Most of this routine, comments included copied from ddraw tree initially: */
1599 TRACE("(%p) : State=%d\n", This
, d3dts
);
1601 This
->UpdateStateBlock
->Changed
.transform
[d3dts
] = TRUE
;
1602 This
->UpdateStateBlock
->Set
.transform
[d3dts
] = TRUE
;
1603 memcpy(&This
->UpdateStateBlock
->transforms
[d3dts
], lpmatrix
, sizeof(D3DMATRIX
));
1605 /* Handle recording of state blocks */
1606 if (This
->isRecordingState
) {
1607 TRACE("Recording... not performing anything\n");
1612 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1614 where ViewMat = Camera space, WorldMat = world space.
1616 In OpenGL, camera and world space is combined into GL_MODELVIEW
1617 matrix. The Projection matrix stay projection matrix. */
1619 /* After reading through both OpenGL and Direct3D documentations, I
1620 thought that D3D matrices were written in 'line major mode' transposed
1621 from OpenGL's 'column major mode'. But I found out that a simple memcpy
1622 works fine to transfer one matrix format to the other (it did not work
1623 when transposing)....
1626 1) are the documentations wrong
1627 2) does the matrix work even if they are not read correctly
1628 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
1629 loading using glLoadMatrix ?
1631 Anyway, I always use 'conv_mat' to transfer the matrices from one format
1632 to the other so that if I ever find out that I need to transpose them, I
1633 will able to do it quickly, only by changing the macro conv_mat. */
1636 case D3DTS_WORLDMATRIX(0):
1637 conv_mat(lpmatrix
, &This
->StateBlock
.transforms
[D3DTS_WORLDMATRIX(0)]);
1641 conv_mat(lpmatrix
, &This
->StateBlock
.transforms
[D3DTS_VIEW
]);
1644 case D3DTS_PROJECTION
:
1645 conv_mat(lpmatrix
, &This
->StateBlock
.transforms
[D3DTS_PROJECTION
]);
1649 FIXME("Unhandled transform state!!\n");
1654 * Move the GL operation to outside of switch to make it work
1655 * regardless of transform set order. Optimize later.
1658 glMatrixMode(GL_PROJECTION
);
1659 checkGLcall("glMatrixMode");
1660 glLoadMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_PROJECTION
].u
.m
[0][0]);
1661 checkGLcall("glLoadMatrixf");
1663 glMatrixMode(GL_MODELVIEW
);
1664 checkGLcall("glMatrixMode");
1665 glLoadMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_VIEW
].u
.m
[0][0]);
1666 checkGLcall("glLoadMatrixf");
1668 /* If we are changing the View matrix, reset the light information to the new view */
1669 if (d3dts
== D3DTS_VIEW
) {
1670 for (k
= 0; k
< MAX_ACTIVE_LIGHTS
; k
++) {
1671 glLightfv(GL_LIGHT0
+ k
, GL_POSITION
, &This
->lightPosn
[k
][0]);
1672 checkGLcall("glLightfv posn");
1673 glLightfv(GL_LIGHT0
+ k
, GL_SPOT_DIRECTION
, &This
->lightDirn
[k
][0]);
1674 checkGLcall("glLightfv dirn");
1678 glMultMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_WORLDMATRIX(0)].u
.m
[0][0]);
1679 checkGLcall("glMultMatrixf");
1686 HRESULT WINAPI
IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface
, D3DTRANSFORMSTATETYPE State
,D3DMATRIX
* pMatrix
) {
1687 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1688 TRACE("(%p) : for State %d\n", This
, State
);
1689 memcpy(pMatrix
, &This
->StateBlock
.transforms
[State
], sizeof(D3DMATRIX
));
1693 HRESULT WINAPI
IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface
, D3DTRANSFORMSTATETYPE State
, CONST D3DMATRIX
* pMatrix
) {
1694 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1695 FIXME("(%p) : stub\n", This
); return D3D_OK
;
1697 HRESULT WINAPI
IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface
, CONST D3DVIEWPORT8
* pViewport
) {
1698 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1700 TRACE("(%p)\n", This
);
1701 This
->UpdateStateBlock
->Changed
.viewport
= TRUE
;
1702 This
->UpdateStateBlock
->Set
.viewport
= TRUE
;
1703 memcpy(&This
->UpdateStateBlock
->viewport
, pViewport
, sizeof(D3DVIEWPORT8
));
1705 /* Handle recording of state blocks */
1706 if (This
->isRecordingState
) {
1707 TRACE("Recording... not performing anything\n");
1711 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This
,
1712 pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
, pViewport
->MinZ
, pViewport
->MaxZ
);
1714 glDepthRange(pViewport
->MinZ
, pViewport
->MaxZ
);
1715 checkGLcall("glDepthRange");
1716 /* Fixme? Note GL requires lower left, DirectX supplies upper left */
1717 glViewport(pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
);
1718 checkGLcall("glViewport");
1724 HRESULT WINAPI
IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface
, D3DVIEWPORT8
* pViewport
) {
1725 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1726 TRACE("(%p)\n", This
);
1727 memcpy(pViewport
, &This
->StateBlock
.viewport
, sizeof(D3DVIEWPORT8
));
1731 HRESULT WINAPI
IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface
, CONST D3DMATERIAL8
* pMaterial
) {
1732 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1734 This
->UpdateStateBlock
->Changed
.material
= TRUE
;
1735 This
->UpdateStateBlock
->Set
.material
= TRUE
;
1736 memcpy(&This
->UpdateStateBlock
->material
, pMaterial
, sizeof(D3DMATERIAL8
));
1738 /* Handle recording of state blocks */
1739 if (This
->isRecordingState
) {
1740 TRACE("Recording... not performing anything\n");
1745 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This
, pMaterial
->Diffuse
.r
, pMaterial
->Diffuse
.g
, pMaterial
->Diffuse
.b
, pMaterial
->Diffuse
.a
);
1746 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This
, pMaterial
->Ambient
.r
, pMaterial
->Ambient
.g
, pMaterial
->Ambient
.b
, pMaterial
->Ambient
.a
);
1747 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This
, pMaterial
->Specular
.r
, pMaterial
->Specular
.g
, pMaterial
->Specular
.b
, pMaterial
->Specular
.a
);
1748 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This
, pMaterial
->Emissive
.r
, pMaterial
->Emissive
.g
, pMaterial
->Emissive
.b
, pMaterial
->Emissive
.a
);
1749 TRACE("(%p) : Power (%f)\n", This
, pMaterial
->Power
);
1751 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, (float *)&This
->UpdateStateBlock
->material
.Ambient
);
1752 checkGLcall("glMaterialfv");
1753 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, (float *)&This
->UpdateStateBlock
->material
.Diffuse
);
1754 checkGLcall("glMaterialfv");
1756 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, (float *)&This
->UpdateStateBlock
->material
.Specular
);
1757 checkGLcall("glMaterialfv");
1758 glMaterialfv(GL_FRONT_AND_BACK
, GL_EMISSION
, (float *)&This
->UpdateStateBlock
->material
.Emissive
);
1759 checkGLcall("glMaterialfv");
1760 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, This
->UpdateStateBlock
->material
.Power
);
1761 checkGLcall("glMaterialf");
1766 HRESULT WINAPI
IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface
, D3DMATERIAL8
* pMaterial
) {
1767 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1768 memcpy(pMaterial
, &This
->UpdateStateBlock
->material
, sizeof (D3DMATERIAL8
));
1769 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This
, pMaterial
->Diffuse
.r
, pMaterial
->Diffuse
.g
, pMaterial
->Diffuse
.b
, pMaterial
->Diffuse
.a
);
1770 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This
, pMaterial
->Ambient
.r
, pMaterial
->Ambient
.g
, pMaterial
->Ambient
.b
, pMaterial
->Ambient
.a
);
1771 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This
, pMaterial
->Specular
.r
, pMaterial
->Specular
.g
, pMaterial
->Specular
.b
, pMaterial
->Specular
.a
);
1772 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This
, pMaterial
->Emissive
.r
, pMaterial
->Emissive
.g
, pMaterial
->Emissive
.b
, pMaterial
->Emissive
.a
);
1773 TRACE("(%p) : Power (%f)\n", This
, pMaterial
->Power
);
1777 HRESULT WINAPI
IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface
, DWORD Index
,CONST D3DLIGHT8
* pLight
) {
1778 float colRGBA
[] = {0.0, 0.0, 0.0, 0.0};
1782 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1783 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This
, Index
, pLight
);
1785 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
,
1786 pLight
->Diffuse
.r
, pLight
->Diffuse
.g
, pLight
->Diffuse
.b
, pLight
->Diffuse
.a
,
1787 pLight
->Specular
.r
, pLight
->Specular
.g
, pLight
->Specular
.b
, pLight
->Specular
.a
,
1788 pLight
->Ambient
.r
, pLight
->Ambient
.g
, pLight
->Ambient
.b
, pLight
->Ambient
.a
);
1789 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight
->Position
.x
, pLight
->Position
.y
, pLight
->Position
.z
,
1790 pLight
->Direction
.x
, pLight
->Direction
.y
, pLight
->Direction
.z
);
1791 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight
->Range
, pLight
->Falloff
, pLight
->Theta
, pLight
->Phi
);
1793 This
->UpdateStateBlock
->Changed
.lights
[Index
] = TRUE
;
1794 This
->UpdateStateBlock
->Set
.lights
[Index
] = TRUE
;
1795 memcpy(&This
->UpdateStateBlock
->lights
[Index
], pLight
, sizeof(D3DLIGHT8
));
1797 /* Handle recording of state blocks */
1798 if (This
->isRecordingState
) {
1799 TRACE("Recording... not performing anything\n");
1804 colRGBA
[0] = pLight
->Diffuse
.r
;
1805 colRGBA
[1] = pLight
->Diffuse
.g
;
1806 colRGBA
[2] = pLight
->Diffuse
.b
;
1807 colRGBA
[3] = pLight
->Diffuse
.a
;
1808 glLightfv(GL_LIGHT0
+Index
, GL_DIFFUSE
, colRGBA
);
1809 checkGLcall("glLightfv");
1812 colRGBA
[0] = pLight
->Specular
.r
;
1813 colRGBA
[1] = pLight
->Specular
.g
;
1814 colRGBA
[2] = pLight
->Specular
.b
;
1815 colRGBA
[3] = pLight
->Specular
.a
;
1816 glLightfv(GL_LIGHT0
+Index
, GL_SPECULAR
, colRGBA
);
1817 checkGLcall("glLightfv");
1820 colRGBA
[0] = pLight
->Ambient
.r
;
1821 colRGBA
[1] = pLight
->Ambient
.g
;
1822 colRGBA
[2] = pLight
->Ambient
.b
;
1823 colRGBA
[3] = pLight
->Ambient
.a
;
1824 glLightfv(GL_LIGHT0
+Index
, GL_AMBIENT
, colRGBA
);
1825 checkGLcall("glLightfv");
1827 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1828 glMatrixMode(GL_MODELVIEW
);
1830 glLoadMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_VIEW
].u
.m
[0][0]);
1832 /* Attenuation - Are these right? guessing... */
1833 glLightf(GL_LIGHT0
+Index
, GL_CONSTANT_ATTENUATION
, pLight
->Attenuation0
);
1834 checkGLcall("glLightf");
1835 glLightf(GL_LIGHT0
+Index
, GL_LINEAR_ATTENUATION
, pLight
->Attenuation1
);
1836 checkGLcall("glLightf");
1838 quad_att
= 1.4/(pLight
->Range
*pLight
->Range
);
1839 if (quad_att
< pLight
->Attenuation2
) quad_att
= pLight
->Attenuation2
;
1840 glLightf(GL_LIGHT0
+Index
, GL_QUADRATIC_ATTENUATION
, quad_att
);
1841 checkGLcall("glLightf");
1843 switch (pLight
->Type
) {
1844 case D3DLIGHT_POINT
:
1846 This
->lightPosn
[Index
][0] = pLight
->Position
.x
;
1847 This
->lightPosn
[Index
][1] = pLight
->Position
.y
;
1848 This
->lightPosn
[Index
][2] = pLight
->Position
.z
;
1849 This
->lightPosn
[Index
][3] = 1.0;
1850 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &This
->lightPosn
[Index
][0]);
1851 checkGLcall("glLightfv");
1853 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_CUTOFF
, 180);
1854 checkGLcall("glLightf");
1861 This
->lightPosn
[Index
][0] = pLight
->Position
.x
;
1862 This
->lightPosn
[Index
][1] = pLight
->Position
.y
;
1863 This
->lightPosn
[Index
][2] = pLight
->Position
.z
;
1864 This
->lightPosn
[Index
][3] = 1.0;
1865 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &This
->lightPosn
[Index
][0]);
1866 checkGLcall("glLightfv");
1869 This
->lightDirn
[Index
][0] = pLight
->Direction
.x
;
1870 This
->lightDirn
[Index
][1] = pLight
->Direction
.y
;
1871 This
->lightDirn
[Index
][2] = pLight
->Direction
.z
;
1872 This
->lightDirn
[Index
][3] = 1.0;
1873 glLightfv(GL_LIGHT0
+Index
, GL_SPOT_DIRECTION
, &This
->lightDirn
[Index
][0]);
1874 checkGLcall("glLightfv");
1877 * opengl-ish and d3d-ish spot lights use too different models for the
1878 * light "intensity" as a function of the angle towards the main light direction,
1879 * so we only can approximate very roughly.
1880 * however spot lights are rather rarely used in games (if ever used at all).
1881 * furthermore if still used, probably nobody pays attention to such details.
1883 if (pLight
->Falloff
== 0) {
1886 rho
= pLight
->Theta
+ (pLight
->Phi
- pLight
->Theta
)/(2*pLight
->Falloff
);
1888 if (rho
< 0.0001) rho
= 0.0001f
;
1889 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_EXPONENT
, -0.3/log(cos(rho
/2)));
1890 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_CUTOFF
, pLight
->Phi
*90/M_PI
);
1894 case D3DLIGHT_DIRECTIONAL
:
1896 This
->lightPosn
[Index
][0] = -pLight
->Direction
.x
;
1897 This
->lightPosn
[Index
][1] = -pLight
->Direction
.y
;
1898 This
->lightPosn
[Index
][2] = -pLight
->Direction
.z
;
1899 This
->lightPosn
[Index
][3] = 0.0;
1900 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &This
->lightPosn
[Index
][0]); /* Note gl uses w position of 0 for direction! */
1901 checkGLcall("glLightfv");
1903 glLightf(GL_LIGHT0
+Index
, GL_SPOT_CUTOFF
, 180.0f
);
1904 glLightf(GL_LIGHT0
+Index
, GL_SPOT_EXPONENT
, 0.0f
);
1909 FIXME("Unrecognized light type %d\n", pLight
->Type
);
1912 /* Restore the modelview matrix */
1917 HRESULT WINAPI
IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface
, DWORD Index
,D3DLIGHT8
* pLight
) {
1918 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1919 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This
, Index
, pLight
);
1920 memcpy(pLight
, &This
->StateBlock
.lights
[Index
], sizeof(D3DLIGHT8
));
1923 HRESULT WINAPI
IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface
, DWORD Index
,BOOL Enable
) {
1924 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1925 TRACE("(%p) : Idx(%ld), enable? %d\n", This
, Index
, Enable
);
1927 This
->UpdateStateBlock
->Changed
.lightEnable
[Index
] = TRUE
;
1928 This
->UpdateStateBlock
->Set
.lightEnable
[Index
] = TRUE
;
1929 This
->UpdateStateBlock
->lightEnable
[Index
] = Enable
;
1931 /* Handle recording of state blocks */
1932 if (This
->isRecordingState
) {
1933 TRACE("Recording... not performing anything\n");
1938 glEnable(GL_LIGHT0
+Index
);
1939 checkGLcall("glEnable GL_LIGHT0+Index");
1941 glDisable(GL_LIGHT0
+Index
);
1942 checkGLcall("glDisable GL_LIGHT0+Index");
1946 HRESULT WINAPI
IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface
, DWORD Index
,BOOL
* pEnable
) {
1947 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1948 TRACE("(%p) : for idx(%ld)\n", This
, Index
);
1949 *pEnable
= This
->StateBlock
.lightEnable
[Index
];
1952 HRESULT WINAPI
IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface
, DWORD Index
,CONST
float* pPlane
) {
1953 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1954 TRACE("(%p) : for idx %ld, %p\n", This
, Index
, pPlane
);
1956 This
->UpdateStateBlock
->Changed
.clipplane
[Index
] = TRUE
;
1957 This
->UpdateStateBlock
->Set
.clipplane
[Index
] = TRUE
;
1958 This
->UpdateStateBlock
->clipplane
[Index
][0] = pPlane
[0];
1959 This
->UpdateStateBlock
->clipplane
[Index
][1] = pPlane
[1];
1960 This
->UpdateStateBlock
->clipplane
[Index
][2] = pPlane
[2];
1961 This
->UpdateStateBlock
->clipplane
[Index
][3] = pPlane
[3];
1963 /* Handle recording of state blocks */
1964 if (This
->isRecordingState
) {
1965 TRACE("Recording... not performing anything\n");
1971 /* Clip Plane settings are affected by the model view in OpenGL, the World transform in direct3d, I think?*/
1972 glMatrixMode(GL_MODELVIEW
);
1974 glLoadMatrixf((float *) &This
->StateBlock
.transforms
[D3DTS_WORLD
].u
.m
[0][0]);
1976 TRACE("Clipplane [%f,%f,%f,%f]\n", This
->UpdateStateBlock
->clipplane
[Index
][0], This
->UpdateStateBlock
->clipplane
[Index
][1],
1977 This
->UpdateStateBlock
->clipplane
[Index
][2], This
->UpdateStateBlock
->clipplane
[Index
][3]);
1978 glClipPlane(GL_CLIP_PLANE0
+Index
, This
->UpdateStateBlock
->clipplane
[Index
]);
1981 checkGLcall("glClipPlane");
1985 HRESULT WINAPI
IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface
, DWORD Index
,float* pPlane
) {
1986 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1987 TRACE("(%p) : for idx %ld\n", This
, Index
);
1988 pPlane
[0] = This
->StateBlock
.clipplane
[Index
][0];
1989 pPlane
[1] = This
->StateBlock
.clipplane
[Index
][0];
1990 pPlane
[2] = This
->StateBlock
.clipplane
[Index
][0];
1991 pPlane
[3] = This
->StateBlock
.clipplane
[Index
][0];
1994 HRESULT WINAPI
IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface
, D3DRENDERSTATETYPE State
,DWORD Value
) {
1995 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
1996 DWORD OldValue
= This
->StateBlock
.renderstate
[State
];
1998 TRACE("(%p)->state = %d, value = %ld\n", This
, State
, Value
);
1999 This
->UpdateStateBlock
->Changed
.renderstate
[State
] = TRUE
;
2000 This
->UpdateStateBlock
->Set
.renderstate
[State
] = TRUE
;
2001 This
->UpdateStateBlock
->renderstate
[State
] = Value
;
2003 /* Handle recording of state blocks */
2004 if (This
->isRecordingState
) {
2005 TRACE("Recording... not performing anything\n");
2010 case D3DRS_FILLMODE
:
2011 switch ((D3DFILLMODE
) Value
) {
2012 case D3DFILL_POINT
: glPolygonMode(GL_FRONT_AND_BACK
, GL_POINT
); break;
2013 case D3DFILL_WIREFRAME
: glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
); break;
2014 case D3DFILL_SOLID
: glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
); break;
2016 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value
);
2018 checkGLcall("glPolygonMode (fillmode)");
2021 case D3DRS_LIGHTING
:
2023 glEnable(GL_LIGHTING
);
2024 checkGLcall("glEnable GL_LIGHTING");
2026 glDisable(GL_LIGHTING
);
2027 checkGLcall("glDisable GL_LIGHTING");
2031 case D3DRS_ZENABLE
:
2032 switch ((D3DZBUFFERTYPE
) Value
) {
2034 glDisable(GL_DEPTH_TEST
);
2035 checkGLcall("glDisable GL_DEPTH_TEST");
2038 glEnable(GL_DEPTH_TEST
);
2039 checkGLcall("glEnable GL_DEPTH_TEST");
2044 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value
);
2048 case D3DRS_CULLMODE
:
2050 /* If we are culling "back faces with clockwise vertices" then
2051 set front faces to be counter clockwise and enable culling
2053 switch ((D3DCULL
) Value
) {
2055 glDisable(GL_CULL_FACE
);
2056 checkGLcall("glDisable GL_CULL_FACE");
2059 glEnable(GL_CULL_FACE
);
2060 checkGLcall("glEnable GL_CULL_FACE");
2061 glFrontFace(GL_CCW
);
2062 checkGLcall("glFrontFace GL_CCW");
2063 glCullFace(GL_BACK
);
2066 glEnable(GL_CULL_FACE
);
2067 checkGLcall("glEnable GL_CULL_FACE");
2069 checkGLcall("glFrontFace GL_CW");
2070 glCullFace(GL_BACK
);
2073 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value
);
2077 case D3DRS_SHADEMODE
:
2078 switch ((D3DSHADEMODE
) Value
) {
2080 glShadeModel(GL_FLAT
);
2081 checkGLcall("glShadeModel");
2083 case D3DSHADE_GOURAUD
:
2084 glShadeModel(GL_SMOOTH
);
2085 checkGLcall("glShadeModel");
2087 case D3DSHADE_PHONG
:
2088 FIXME("D3DSHADE_PHONG isnt supported?\n");
2089 return D3DERR_INVALIDCALL
;
2091 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value
);
2095 case D3DRS_DITHERENABLE
:
2097 glEnable(GL_DITHER
);
2098 checkGLcall("glEnable GL_DITHER");
2100 glDisable(GL_DITHER
);
2101 checkGLcall("glDisable GL_DITHER");
2105 case D3DRS_ZWRITEENABLE
:
2108 checkGLcall("glDepthMask");
2111 checkGLcall("glDepthMask");
2117 int glParm
= GL_LESS
;
2119 switch ((D3DCMPFUNC
) Value
) {
2120 case D3DCMP_NEVER
: glParm
=GL_NEVER
; break;
2121 case D3DCMP_LESS
: glParm
=GL_LESS
; break;
2122 case D3DCMP_EQUAL
: glParm
=GL_EQUAL
; break;
2123 case D3DCMP_LESSEQUAL
: glParm
=GL_LEQUAL
; break;
2124 case D3DCMP_GREATER
: glParm
=GL_GREATER
; break;
2125 case D3DCMP_NOTEQUAL
: glParm
=GL_NOTEQUAL
; break;
2126 case D3DCMP_GREATEREQUAL
: glParm
=GL_GEQUAL
; break;
2127 case D3DCMP_ALWAYS
: glParm
=GL_ALWAYS
; break;
2129 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2131 glDepthFunc(glParm
);
2132 checkGLcall("glDepthFunc");
2136 case D3DRS_AMBIENT
:
2140 col
[0] = ((Value
>> 16) & 0xFF) / 255.0;
2141 col
[1] = ((Value
>> 8 ) & 0xFF) / 255.0;
2142 col
[2] = ((Value
>> 0 ) & 0xFF) / 255.0;
2143 col
[3] = ((Value
>> 24 ) & 0xFF) / 255.0;
2144 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col
[0],col
[1],col
[2],col
[3]);
2145 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, col
);
2146 checkGLcall("glLightModel for MODEL_AMBIENT");
2151 case D3DRS_ALPHABLENDENABLE
:
2154 checkGLcall("glEnable GL_BLEND");
2156 glDisable(GL_BLEND
);
2157 checkGLcall("glDisable GL_BLEND");
2161 case D3DRS_SRCBLEND
:
2162 case D3DRS_DESTBLEND
:
2164 int newVal
= GL_ZERO
;
2166 case D3DBLEND_ZERO
: newVal
= GL_ZERO
; break;
2167 case D3DBLEND_ONE
: newVal
= GL_ONE
; break;
2168 case D3DBLEND_SRCCOLOR
: newVal
= GL_SRC_COLOR
; break;
2169 case D3DBLEND_INVSRCCOLOR
: newVal
= GL_ONE_MINUS_SRC_COLOR
; break;
2170 case D3DBLEND_SRCALPHA
: newVal
= GL_SRC_ALPHA
; break;
2171 case D3DBLEND_INVSRCALPHA
: newVal
= GL_ONE_MINUS_SRC_ALPHA
; break;
2172 case D3DBLEND_DESTALPHA
: newVal
= GL_DST_ALPHA
; break;
2173 case D3DBLEND_INVDESTALPHA
: newVal
= GL_ONE_MINUS_DST_ALPHA
; break;
2174 case D3DBLEND_DESTCOLOR
: newVal
= GL_DST_COLOR
; break;
2175 case D3DBLEND_INVDESTCOLOR
: newVal
= GL_ONE_MINUS_DST_COLOR
; break;
2176 case D3DBLEND_SRCALPHASAT
: newVal
= GL_SRC_ALPHA_SATURATE
; break;
2178 case D3DBLEND_BOTHSRCALPHA
: newVal
= GL_SRC_ALPHA
;
2179 This
->srcBlend
= newVal
;
2180 This
->dstBlend
= newVal
;
2183 case D3DBLEND_BOTHINVSRCALPHA
: newVal
= GL_ONE_MINUS_SRC_ALPHA
;
2184 This
->srcBlend
= newVal
;
2185 This
->dstBlend
= newVal
;
2188 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value
, State
);
2191 if (State
== D3DRS_SRCBLEND
) This
->srcBlend
= newVal
;
2192 if (State
== D3DRS_DESTBLEND
) This
->dstBlend
= newVal
;
2193 TRACE("glBlendFunc src=%x, dst=%x\n", This
->srcBlend
, This
->dstBlend
);
2194 glBlendFunc(This
->srcBlend
, This
->dstBlend
);
2196 checkGLcall("glBlendFunc");
2200 case D3DRS_ALPHATESTENABLE
:
2202 glEnable(GL_ALPHA_TEST
);
2203 checkGLcall("glEnable GL_ALPHA_TEST");
2205 glDisable(GL_ALPHA_TEST
);
2206 checkGLcall("glDisable GL_ALPHA_TEST");
2210 case D3DRS_ALPHAFUNC
:
2212 int glParm
= GL_LESS
;
2215 glGetFloatv(GL_ALPHA_TEST_REF
, &ref
);
2216 checkGLcall("glGetFloatv(GL_ALPHA_TEST_REF, &ref);");
2218 switch ((D3DCMPFUNC
) Value
) {
2219 case D3DCMP_NEVER
: glParm
=GL_NEVER
; break;
2220 case D3DCMP_LESS
: glParm
=GL_LESS
; break;
2221 case D3DCMP_EQUAL
: glParm
=GL_EQUAL
; break;
2222 case D3DCMP_LESSEQUAL
: glParm
=GL_LEQUAL
; break;
2223 case D3DCMP_GREATER
: glParm
=GL_GREATER
; break;
2224 case D3DCMP_NOTEQUAL
: glParm
=GL_NOTEQUAL
; break;
2225 case D3DCMP_GREATEREQUAL
: glParm
=GL_GEQUAL
; break;
2226 case D3DCMP_ALWAYS
: glParm
=GL_ALWAYS
; break;
2228 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2230 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm
, ref
);
2231 glAlphaFunc(glParm
, ref
);
2232 checkGLcall("glAlphaFunc");
2236 case D3DRS_ALPHAREF
:
2238 int glParm
= GL_LESS
;
2241 glGetIntegerv(GL_ALPHA_TEST_FUNC
, &glParm
);
2242 checkGLcall("glGetFloatv(GL_ALPHA_TEST_FUNC, &glParm);");
2244 ref
= ((float) Value
) / 255.0;
2245 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm
, ref
);
2246 glAlphaFunc(glParm
, ref
);
2247 checkGLcall("glAlphaFunc");
2251 case D3DRS_CLIPPLANEENABLE
:
2252 case D3DRS_CLIPPING
:
2254 /* Ensure we only do the changed clip planes */
2255 DWORD enable
= 0xFFFFFFFF;
2256 DWORD disable
= 0x00000000;
2258 /* If enabling / disabling all */
2259 if (State
== D3DRS_CLIPPING
) {
2261 enable
= This
->StateBlock
.renderstate
[D3DRS_CLIPPLANEENABLE
];
2264 disable
= This
->StateBlock
.renderstate
[D3DRS_CLIPPLANEENABLE
];
2268 enable
= Value
& ~OldValue
;
2269 disable
= ~Value
& OldValue
;
2272 if (enable
& D3DCLIPPLANE0
) { glEnable(GL_CLIP_PLANE0
); checkGLcall("glEnable(clip plane 0)"); }
2273 if (enable
& D3DCLIPPLANE1
) { glEnable(GL_CLIP_PLANE1
); checkGLcall("glEnable(clip plane 1)"); }
2274 if (enable
& D3DCLIPPLANE2
) { glEnable(GL_CLIP_PLANE2
); checkGLcall("glEnable(clip plane 2)"); }
2275 if (enable
& D3DCLIPPLANE3
) { glEnable(GL_CLIP_PLANE3
); checkGLcall("glEnable(clip plane 3)"); }
2276 if (enable
& D3DCLIPPLANE4
) { glEnable(GL_CLIP_PLANE4
); checkGLcall("glEnable(clip plane 4)"); }
2277 if (enable
& D3DCLIPPLANE5
) { glEnable(GL_CLIP_PLANE5
); checkGLcall("glEnable(clip plane 5)"); }
2279 if (disable
& D3DCLIPPLANE0
) { glDisable(GL_CLIP_PLANE0
); checkGLcall("glDisable(clip plane 0)"); }
2280 if (disable
& D3DCLIPPLANE1
) { glDisable(GL_CLIP_PLANE1
); checkGLcall("glDisable(clip plane 1)"); }
2281 if (disable
& D3DCLIPPLANE2
) { glDisable(GL_CLIP_PLANE2
); checkGLcall("glDisable(clip plane 2)"); }
2282 if (disable
& D3DCLIPPLANE3
) { glDisable(GL_CLIP_PLANE3
); checkGLcall("glDisable(clip plane 3)"); }
2283 if (disable
& D3DCLIPPLANE4
) { glDisable(GL_CLIP_PLANE4
); checkGLcall("glDisable(clip plane 4)"); }
2284 if (disable
& D3DCLIPPLANE5
) { glDisable(GL_CLIP_PLANE5
); checkGLcall("glDisable(clip plane 5)"); }
2288 case D3DRS_BLENDOP
:
2290 int glParm
= GL_FUNC_ADD
;
2292 switch ((D3DBLENDOP
) Value
) {
2293 case D3DBLENDOP_ADD
: glParm
= GL_FUNC_ADD
; break;
2294 case D3DBLENDOP_SUBTRACT
: glParm
= GL_FUNC_SUBTRACT
; break;
2295 case D3DBLENDOP_REVSUBTRACT
: glParm
= GL_FUNC_REVERSE_SUBTRACT
; break;
2296 case D3DBLENDOP_MIN
: glParm
= GL_MIN
; break;
2297 case D3DBLENDOP_MAX
: glParm
= GL_MAX
; break;
2299 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value
);
2301 TRACE("glBlendEquation(%x)\n", glParm
);
2302 glBlendEquation(glParm
);
2303 checkGLcall("glBlendEquation");
2307 case D3DRS_TEXTUREFACTOR
:
2311 /* Note the texture color applies to all textures whereas
2312 GL_TEXTURE_ENV_COLOR applies to active only */
2314 col
[0] = ((Value
>> 16) & 0xFF) / 255.0;
2315 col
[1] = ((Value
>> 8 ) & 0xFF) / 255.0;
2316 col
[2] = ((Value
>> 0 ) & 0xFF) / 255.0;
2317 col
[3] = ((Value
>> 24 ) & 0xFF) / 255.0;
2319 /* Set the default alpha blend color */
2320 glBlendColor(col
[0], col
[1], col
[2], col
[3]);
2321 checkGLcall("glBlendColor");
2323 /* And now the default texture color as well */
2324 for (i
= 0; i
< This
->TextureUnits
; i
++) {
2326 /* Note the D3DRS value applies to all textures, but GL has one
2327 per texture, so apply it now ready to be used! */
2328 if (This
->isMultiTexture
) {
2329 glActiveTextureARB(GL_TEXTURE0_ARB
+ i
);
2330 checkGLcall("Activate texture.. to update const color");
2332 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2335 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, &col
[0]);
2336 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2341 case D3DRS_SPECULARENABLE
:
2344 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
,GL_SEPARATE_SPECULAR_COLOR
);
2345 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);");
2347 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
,GL_SINGLE_COLOR
);
2348 checkGLcall("glLightModel (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR);");
2353 case D3DRS_STENCILENABLE
:
2355 glEnable(GL_STENCIL_TEST
);
2356 checkGLcall("glEnable GL_STENCIL_TEST");
2358 glDisable(GL_STENCIL_TEST
);
2359 checkGLcall("glDisable GL_STENCIL_TEST");
2363 case D3DRS_STENCILFUNC
:
2365 int glParm
= GL_ALWAYS
;
2367 GLuint mask
= 0xFFFFFFFF;
2369 glGetIntegerv(GL_STENCIL_REF
, &ref
);
2370 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2371 glGetIntegerv(GL_STENCIL_VALUE_MASK
, &mask
);
2372 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2374 switch ((D3DCMPFUNC
) Value
) {
2375 case D3DCMP_NEVER
: glParm
=GL_NEVER
; break;
2376 case D3DCMP_LESS
: glParm
=GL_LESS
; break;
2377 case D3DCMP_EQUAL
: glParm
=GL_EQUAL
; break;
2378 case D3DCMP_LESSEQUAL
: glParm
=GL_LEQUAL
; break;
2379 case D3DCMP_GREATER
: glParm
=GL_GREATER
; break;
2380 case D3DCMP_NOTEQUAL
: glParm
=GL_NOTEQUAL
; break;
2381 case D3DCMP_GREATEREQUAL
: glParm
=GL_GEQUAL
; break;
2382 case D3DCMP_ALWAYS
: glParm
=GL_ALWAYS
; break;
2384 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2386 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2387 glStencilFunc(glParm
, ref
, mask
);
2388 checkGLcall("glStencilFunc");
2392 case D3DRS_STENCILREF
:
2394 int glParm
= GL_ALWAYS
;
2396 GLuint mask
= 0xFFFFFFFF;
2398 glGetIntegerv(GL_STENCIL_FUNC
, &glParm
);
2399 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2400 glGetIntegerv(GL_STENCIL_VALUE_MASK
, &mask
);
2401 checkGLcall("glGetFloatv(GL_STENCIL_VALUE_MASK, &glParm);");
2404 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2405 glStencilFunc(glParm
, ref
, mask
);
2406 checkGLcall("glStencilFunc");
2410 case D3DRS_STENCILMASK
:
2412 int glParm
= GL_ALWAYS
;
2414 GLuint mask
= Value
;
2416 glGetIntegerv(GL_STENCIL_REF
, &ref
);
2417 checkGLcall("glGetFloatv(GL_STENCIL_REF, &ref);");
2418 glGetIntegerv(GL_STENCIL_FUNC
, &glParm
);
2419 checkGLcall("glGetFloatv(GL_STENCIL_FUNC, &glParm);");
2421 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2422 glStencilFunc(glParm
, ref
, mask
);
2423 checkGLcall("glStencilFunc");
2427 case D3DRS_STENCILFAIL
:
2433 fail
= StencilOp(Value
);
2434 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS
, &zpass
);
2435 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2436 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL
, &zfail
);
2437 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2439 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2440 glStencilOp(fail
, zfail
, zpass
);
2441 checkGLcall("glStencilOp(fail, zfail, zpass);");
2444 case D3DRS_STENCILZFAIL
:
2450 glGetIntegerv(GL_STENCIL_FAIL
, &fail
);
2451 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2452 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS
, &zpass
);
2453 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2454 zfail
= StencilOp(Value
);
2456 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2457 glStencilOp(fail
, zfail
, zpass
);
2458 checkGLcall("glStencilOp(fail, zfail, zpass);");
2461 case D3DRS_STENCILPASS
:
2467 glGetIntegerv(GL_STENCIL_FAIL
, &fail
);
2468 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2469 zpass
= StencilOp(Value
);
2470 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL
, &zfail
);
2471 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2473 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2474 glStencilOp(fail
, zfail
, zpass
);
2475 checkGLcall("glStencilOp(fail, zfail, zpass);");
2479 case D3DRS_STENCILWRITEMASK
:
2481 glStencilMask(Value
);
2482 TRACE("glStencilMask(%lu)\n", Value
);
2483 checkGLcall("glStencilMask");
2487 case D3DRS_FOGENABLE
:
2489 if (Value
&& This
->StateBlock
.renderstate
[D3DRS_FOGTABLEMODE
] != D3DFOG_NONE
) {
2491 checkGLcall("glEnable GL_FOG\n");
2494 checkGLcall("glDisable GL_FOG\n");
2499 case D3DRS_FOGCOLOR
:
2502 col
[0] = ((Value
>> 16) & 0xFF) / 255.0;
2503 col
[1] = ((Value
>> 8 ) & 0xFF) / 255.0;
2504 col
[2] = ((Value
>> 0 ) & 0xFF) / 255.0;
2505 col
[3] = ((Value
>> 24 ) & 0xFF) / 255.0;
2507 /* Set the default alpha blend color */
2508 glFogfv(GL_FOG_COLOR
, &col
[0]);
2509 checkGLcall("glFog GL_FOG_COLOR");
2513 case D3DRS_FOGSTART
:
2515 float *f
= (float *)&Value
;
2516 glFogfv(GL_FOG_START
, f
);
2517 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2518 TRACE("Fog Start == %f\n", *f
);
2524 float *f
= (float *)&Value
;
2525 glFogfv(GL_FOG_END
, f
);
2526 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2527 TRACE("Fog End == %f\n", *f
);
2531 case D3DRS_FOGDENSITY
:
2533 glFogf(GL_FOG_DENSITY
, (float) Value
);
2534 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2538 /* Unhandled yet...! */
2539 case D3DRS_LINEPATTERN
:
2540 case D3DRS_LASTPIXEL
:
2541 case D3DRS_ZVISIBLE
:
2542 case D3DRS_FOGTABLEMODE
:
2543 case D3DRS_EDGEANTIALIAS
:
2545 case D3DRS_RANGEFOGENABLE
:
2554 case D3DRS_FOGVERTEXMODE
:
2555 case D3DRS_COLORVERTEX
:
2556 case D3DRS_LOCALVIEWER
:
2557 case D3DRS_NORMALIZENORMALS
:
2558 case D3DRS_DIFFUSEMATERIALSOURCE
:
2559 case D3DRS_SPECULARMATERIALSOURCE
:
2560 case D3DRS_AMBIENTMATERIALSOURCE
:
2561 case D3DRS_EMISSIVEMATERIALSOURCE
:
2562 case D3DRS_VERTEXBLEND
:
2563 case D3DRS_SOFTWAREVERTEXPROCESSING
:
2564 case D3DRS_POINTSIZE
:
2565 case D3DRS_POINTSIZE_MIN
:
2566 case D3DRS_POINTSPRITEENABLE
:
2567 case D3DRS_POINTSCALEENABLE
:
2568 case D3DRS_POINTSCALE_A
:
2569 case D3DRS_POINTSCALE_B
:
2570 case D3DRS_POINTSCALE_C
:
2571 case D3DRS_MULTISAMPLEANTIALIAS
:
2572 case D3DRS_MULTISAMPLEMASK
:
2573 case D3DRS_PATCHEDGESTYLE
:
2574 case D3DRS_PATCHSEGMENTS
:
2575 case D3DRS_DEBUGMONITORTOKEN
:
2576 case D3DRS_POINTSIZE_MAX
:
2577 case D3DRS_INDEXEDVERTEXBLENDENABLE
:
2578 case D3DRS_COLORWRITEENABLE
:
2579 case D3DRS_TWEENFACTOR
:
2580 case D3DRS_POSITIONORDER
:
2581 case D3DRS_NORMALORDER
:
2582 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2583 TRACE("(%p)->(%d,%ld) not handled yet\n", This
, State
, Value
);
2586 FIXME("(%p)->(%d,%ld) unrecognized\n", This
, State
, Value
);
2591 HRESULT WINAPI
IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface
, D3DRENDERSTATETYPE State
,DWORD
* pValue
) {
2592 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2593 TRACE("(%p) for State %d = %ld\n", This
, State
, This
->UpdateStateBlock
->renderstate
[State
]);
2594 *pValue
= This
->StateBlock
.renderstate
[State
];
2597 HRESULT WINAPI
IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface
) {
2598 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2602 TRACE("(%p)\n", This
);
2603 if (This
->isRecordingState
) {
2604 TRACE("(%p) already recording! returning error\n", This
);
2605 return D3DERR_INVALIDCALL
;
2608 /* Allocate Storage */
2609 memory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(STATEBLOCK
));
2610 This
->isRecordingState
= TRUE
;
2611 This
->UpdateStateBlock
= memory
;
2615 HRESULT WINAPI
IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD
* pToken
) {
2617 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2618 TRACE("(%p)\n", This
);
2620 if (!This
->isRecordingState
) {
2621 TRACE("(%p) not recording! returning error\n", This
);
2622 return D3DERR_INVALIDCALL
;
2625 This
->UpdateStateBlock
->blockType
= D3DSBT_RECORDED
;
2626 *pToken
= (DWORD
) This
->UpdateStateBlock
;
2627 This
->isRecordingState
= FALSE
;
2628 This
->UpdateStateBlock
= &This
->StateBlock
;
2630 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This
, *pToken
);
2634 HRESULT WINAPI
IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD Token
) {
2636 STATEBLOCK
*pSB
= (STATEBLOCK
*)Token
;
2639 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2640 TRACE("(%p) : Applying state block %lx ------------------v\n", This
, Token
);
2642 /* FIXME: Only apply applicable states not all states */
2644 if (pSB
->blockType
== D3DSBT_RECORDED
|| pSB
->blockType
== D3DSBT_ALL
|| pSB
->blockType
== D3DSBT_VERTEXSTATE
) {
2646 for (i
=0; i
<MAX_ACTIVE_LIGHTS
; i
++) {
2648 if (pSB
->Set
.lightEnable
[i
] && pSB
->Changed
.lightEnable
[i
])
2649 IDirect3DDevice8Impl_LightEnable(iface
, i
, pSB
->lightEnable
[i
]);
2650 if (pSB
->Set
.lights
[i
] && pSB
->Changed
.lights
[i
])
2651 IDirect3DDevice8Impl_SetLight(iface
, i
, &pSB
->lights
[i
]);
2654 if (pSB
->Set
.vertexShader
&& pSB
->Changed
.vertexShader
)
2655 IDirect3DDevice8Impl_SetVertexShader(iface
, pSB
->VertexShader
);
2657 /* TODO: Vertex Shader Constants */
2660 if (pSB
->blockType
== D3DSBT_RECORDED
|| pSB
->blockType
== D3DSBT_ALL
|| pSB
->blockType
== D3DSBT_PIXELSTATE
) {
2662 if (pSB
->Set
.pixelShader
&& pSB
->Changed
.pixelShader
)
2663 IDirect3DDevice8Impl_SetPixelShader(iface
, pSB
->PixelShader
);
2665 /* TODO: Pixel Shader Constants */
2668 /* Others + Render & Texture */
2669 if (pSB
->blockType
== D3DSBT_RECORDED
|| pSB
->blockType
== D3DSBT_ALL
) {
2670 for (i
=0; i
<HIGHEST_TRANSFORMSTATE
; i
++) {
2671 if (pSB
->Set
.transform
[i
] && pSB
->Changed
.transform
[i
])
2672 IDirect3DDevice8Impl_SetTransform(iface
, i
, &pSB
->transforms
[i
]);
2675 if (pSB
->Set
.Indices
&& pSB
->Changed
.Indices
)
2676 IDirect3DDevice8Impl_SetIndices(iface
, pSB
->pIndexData
, pSB
->baseVertexIndex
);
2678 if (pSB
->Set
.material
&& pSB
->Changed
.material
)
2679 IDirect3DDevice8Impl_SetMaterial(iface
, &pSB
->material
);
2681 if (pSB
->Set
.viewport
&& pSB
->Changed
.viewport
)
2682 IDirect3DDevice8Impl_SetViewport(iface
, &pSB
->viewport
);
2684 for (i
=0; i
<MAX_STREAMS
; i
++) {
2685 if (pSB
->Set
.stream_source
[i
] && pSB
->Changed
.stream_source
[i
])
2686 IDirect3DDevice8Impl_SetStreamSource(iface
, i
, pSB
->stream_source
[i
], pSB
->stream_stride
[i
]);
2689 for (i
=0; i
<MAX_CLIPPLANES
; i
++) {
2690 if (pSB
->Set
.clipplane
[i
] && pSB
->Changed
.clipplane
[i
]) {
2693 clip
[0] = pSB
->clipplane
[i
][0];
2694 clip
[1] = pSB
->clipplane
[i
][1];
2695 clip
[2] = pSB
->clipplane
[i
][2];
2696 clip
[3] = pSB
->clipplane
[i
][3];
2697 IDirect3DDevice8Impl_SetClipPlane(iface
, i
, clip
);
2702 for (i
=0; i
<HIGHEST_RENDER_STATE
; i
++) {
2704 if (pSB
->Set
.renderstate
[i
] && pSB
->Changed
.renderstate
[i
])
2705 IDirect3DDevice8Impl_SetRenderState(iface
, i
, pSB
->renderstate
[i
]);
2710 for (j
= 0; j
< This
->TextureUnits
; j
++) {
2711 for (i
= 0; i
< HIGHEST_TEXTURE_STATE
; i
++) {
2712 if (pSB
->Set
.texture_state
[j
][i
] && pSB
->Changed
.texture_state
[j
][i
]) {
2713 IDirect3DDevice8Impl_SetTextureStageState(iface
, j
, i
, pSB
->texture_state
[j
][i
]);
2716 if (pSB
->Set
.textures
[j
] && pSB
->Changed
.textures
[j
]) {
2717 IDirect3DDevice8Impl_SetTexture(iface
, j
, pSB
->textures
[j
]);
2722 } else if (pSB
->blockType
== D3DSBT_PIXELSTATE
) {
2724 for (i
=0; i
<NUM_SAVEDPIXELSTATES_R
; i
++) {
2725 if (pSB
->Set
.renderstate
[SavedPixelStates_R
[i
]] && pSB
->Changed
.renderstate
[SavedPixelStates_R
[i
]])
2726 IDirect3DDevice8Impl_SetRenderState(iface
, SavedPixelStates_R
[i
], pSB
->renderstate
[SavedPixelStates_R
[i
]]);
2730 for (j
=0; j
<This
->TextureUnits
; i
++) {
2731 for (i
=0; i
<NUM_SAVEDPIXELSTATES_T
; i
++) {
2733 if (pSB
->Set
.texture_state
[j
][SavedPixelStates_T
[i
]] &&
2734 pSB
->Changed
.texture_state
[j
][SavedPixelStates_T
[i
]])
2735 IDirect3DDevice8Impl_SetTextureStageState(iface
, j
, SavedPixelStates_T
[i
], pSB
->texture_state
[j
][SavedPixelStates_T
[i
]]);
2739 } else if (pSB
->blockType
== D3DSBT_VERTEXSTATE
) {
2741 for (i
=0; i
<NUM_SAVEDVERTEXSTATES_R
; i
++) {
2742 if (pSB
->Set
.renderstate
[SavedVertexStates_R
[i
]] && pSB
->Changed
.renderstate
[SavedVertexStates_R
[i
]])
2743 IDirect3DDevice8Impl_SetRenderState(iface
, SavedVertexStates_R
[i
], pSB
->renderstate
[SavedVertexStates_R
[i
]]);
2747 for (j
=0; j
<This
->TextureUnits
; i
++) {
2748 for (i
=0; i
<NUM_SAVEDVERTEXSTATES_T
; i
++) {
2750 if (pSB
->Set
.texture_state
[j
][SavedVertexStates_T
[i
]] &&
2751 pSB
->Changed
.texture_state
[j
][SavedVertexStates_T
[i
]])
2752 IDirect3DDevice8Impl_SetTextureStageState(iface
, j
, SavedVertexStates_T
[i
], pSB
->texture_state
[j
][SavedVertexStates_T
[i
]]);
2758 FIXME("Unrecognized state block type %d\n", pSB
->blockType
);
2760 memcpy(&This
->StateBlock
.Changed
, &pSB
->Changed
, sizeof(This
->StateBlock
.Changed
));
2761 TRACE("(%p) : Applied state block %lx ------------------^\n", This
, Token
);
2765 HRESULT WINAPI
IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD Token
) {
2767 STATEBLOCK
*updateBlock
= (STATEBLOCK
*)Token
;
2769 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2771 TRACE("(%p) : Updating state block %lx ------------------v \n", This
, Token
);
2773 /* If not recorded, then update can just recapture */
2774 if (updateBlock
->blockType
!= D3DSBT_RECORDED
) {
2776 STATEBLOCK
*tmpBlock
;
2777 IDirect3DDevice8Impl_CreateStateBlock(iface
, updateBlock
->blockType
, &tmpToken
);
2778 tmpBlock
= (STATEBLOCK
*)tmpToken
;
2779 memcpy(updateBlock
, tmpBlock
, sizeof(STATEBLOCK
));
2780 IDirect3DDevice8Impl_DeleteStateBlock(iface
, tmpToken
);
2782 /* FIXME: This will record states of new lights! May need to have and save set_lights
2783 across this action */
2788 /* Recorded => Only update 'changed' values */
2789 if (updateBlock
->Set
.vertexShader
&& updateBlock
->VertexShader
!= This
->StateBlock
.VertexShader
) {
2790 updateBlock
->VertexShader
= This
->StateBlock
.VertexShader
;
2791 TRACE("Updating vertex shader to %ld\n", This
->StateBlock
.VertexShader
);
2794 /* TODO: Vertex Shader Constants */
2796 for (i
=0; i
<MAX_ACTIVE_LIGHTS
; i
++) {
2797 if (updateBlock
->Set
.lightEnable
[i
] && This
->StateBlock
.lightEnable
[i
] != updateBlock
->lightEnable
[i
]) {
2798 TRACE("Updating light enable for light %d to %d\n", i
, This
->StateBlock
.lightEnable
[i
]);
2799 updateBlock
->lightEnable
[i
] = This
->StateBlock
.lightEnable
[i
];
2802 if (updateBlock
->Set
.lights
[i
] && memcmp(&This
->StateBlock
.lights
[i
],
2803 &updateBlock
->lights
[i
],
2804 sizeof(D3DLIGHT8
)) != 0) {
2805 TRACE("Updating lights for light %d\n", i
);
2806 memcpy(&updateBlock
->lights
[i
], &This
->StateBlock
.lights
[i
], sizeof(D3DLIGHT8
));
2810 if (updateBlock
->Set
.pixelShader
&& updateBlock
->PixelShader
!= This
->StateBlock
.PixelShader
) {
2811 TRACE("Updating pixel shader to %ld\n", This
->StateBlock
.PixelShader
);
2812 updateBlock
->lights
[i
] = This
->StateBlock
.lights
[i
];
2813 IDirect3DDevice8Impl_SetVertexShader(iface
, updateBlock
->PixelShader
);
2816 /* TODO: Pixel Shader Constants */
2818 /* Others + Render & Texture */
2819 for (i
=0; i
<HIGHEST_TRANSFORMSTATE
; i
++) {
2820 if (updateBlock
->Set
.transform
[i
] && memcmp(&This
->StateBlock
.transforms
[i
],
2821 &updateBlock
->transforms
[i
],
2822 sizeof(D3DMATRIX
)) != 0) {
2823 TRACE("Updating transform %d\n", i
);
2824 memcpy(&updateBlock
->transforms
[i
], &This
->StateBlock
.transforms
[i
], sizeof(D3DMATRIX
));
2828 if (updateBlock
->Set
.Indices
&& ((updateBlock
->pIndexData
!= This
->StateBlock
.pIndexData
)
2829 || (updateBlock
->baseVertexIndex
!= This
->StateBlock
.baseVertexIndex
))) {
2830 TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
2831 This
->StateBlock
.pIndexData
, This
->StateBlock
.baseVertexIndex
);
2832 updateBlock
->pIndexData
= This
->StateBlock
.pIndexData
;
2833 updateBlock
->baseVertexIndex
= This
->StateBlock
.baseVertexIndex
;
2836 if (updateBlock
->Set
.material
&& memcmp(&This
->StateBlock
.material
,
2837 &updateBlock
->material
,
2838 sizeof(D3DMATERIAL8
)) != 0) {
2839 TRACE("Updating material\n");
2840 memcpy(&updateBlock
->material
, &This
->StateBlock
.material
, sizeof(D3DMATERIAL8
));
2843 if (updateBlock
->Set
.viewport
&& memcmp(&This
->StateBlock
.viewport
,
2844 &updateBlock
->viewport
,
2845 sizeof(D3DVIEWPORT8
)) != 0) {
2846 TRACE("Updating viewport\n");
2847 memcpy(&updateBlock
->viewport
, &This
->StateBlock
.viewport
, sizeof(D3DVIEWPORT8
));
2850 for (i
=0; i
<MAX_STREAMS
; i
++) {
2851 if (updateBlock
->Set
.stream_source
[i
] &&
2852 ((updateBlock
->stream_stride
[i
] != This
->StateBlock
.stream_stride
[i
]) ||
2853 (updateBlock
->stream_source
[i
] != This
->StateBlock
.stream_source
[i
]))) {
2854 TRACE("Updating stream source %d to %p, stride to %d\n", i
, This
->StateBlock
.stream_source
[i
],
2855 This
->StateBlock
.stream_stride
[i
]);
2856 updateBlock
->stream_stride
[i
] = This
->StateBlock
.stream_stride
[i
];
2857 updateBlock
->stream_source
[i
] = This
->StateBlock
.stream_source
[i
];
2861 for (i
=0; i
<MAX_CLIPPLANES
; i
++) {
2862 if (updateBlock
->Set
.clipplane
[i
] && memcmp(&This
->StateBlock
.clipplane
[i
],
2863 &updateBlock
->clipplane
[i
],
2864 sizeof(updateBlock
->clipplane
)) != 0) {
2866 TRACE("Updating clipplane %d\n", i
);
2867 memcpy(&updateBlock
->clipplane
[i
], &This
->StateBlock
.clipplane
[i
],
2868 sizeof(updateBlock
->clipplane
));
2873 for (i
=0; i
<HIGHEST_RENDER_STATE
; i
++) {
2875 if (updateBlock
->Set
.renderstate
[i
] && (updateBlock
->renderstate
[i
] !=
2876 This
->StateBlock
.renderstate
[i
])) {
2877 TRACE("Updating renderstate %d to %ld\n", i
, This
->StateBlock
.renderstate
[i
]);
2878 updateBlock
->renderstate
[i
] = This
->StateBlock
.renderstate
[i
];
2883 for (j
=0; j
<This
->TextureUnits
; j
++) {
2884 for (i
=0; i
<HIGHEST_TEXTURE_STATE
; i
++) {
2886 if (updateBlock
->Set
.texture_state
[j
][i
] && (updateBlock
->texture_state
[j
][i
] !=
2887 This
->StateBlock
.texture_state
[j
][i
])) {
2888 TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j
,i
, This
->StateBlock
.texture_state
[j
][i
],
2889 updateBlock
->texture_state
[j
][i
]);
2890 updateBlock
->texture_state
[j
][i
] = This
->StateBlock
.texture_state
[j
][i
];
2893 if (updateBlock
->Set
.textures
[j
] && (updateBlock
->textures
[j
] != This
->StateBlock
.textures
[j
])) {
2894 TRACE("Updating texture %d to %p (was %p)\n", j
, This
->StateBlock
.textures
[j
], updateBlock
->textures
[j
]);
2895 updateBlock
->textures
[j
] = This
->StateBlock
.textures
[j
];
2902 TRACE("(%p) : Updated state block %lx ------------------^\n", This
, Token
);
2906 HRESULT WINAPI
IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD Token
) {
2907 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2908 TRACE("(%p) : freeing StateBlock %lx\n", This
, Token
);
2909 HeapFree(GetProcessHeap(), 0, (void *)Token
);
2913 HRESULT WINAPI
IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface
, D3DSTATEBLOCKTYPE Type
, DWORD
* pToken
) {
2918 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2919 TRACE("(%p) : for type %d\n", This
, Type
);
2921 /* Allocate Storage */
2922 memory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(STATEBLOCK
));
2924 memcpy(memory
, &This
->StateBlock
, sizeof(STATEBLOCK
));
2926 *pToken
= 0xFFFFFFFF;
2927 return E_OUTOFMEMORY
;
2929 *pToken
= (DWORD
) memory
;
2931 s
->blockType
= Type
;
2933 TRACE("Updating changed flags appropriate for type %d\n", Type
);
2935 if (Type
== D3DSBT_ALL
) {
2936 TRACE("ALL => Pretend everything has changed\n");
2937 memset(&s
->Changed
, TRUE
, sizeof(This
->StateBlock
.Changed
));
2939 } else if (Type
== D3DSBT_PIXELSTATE
) {
2941 memset(&s
->Changed
, FALSE
, sizeof(This
->StateBlock
.Changed
));
2943 /* TODO: Pixel Shader Constants */
2944 s
->Changed
.pixelShader
= TRUE
;
2945 for (i
=0; i
<NUM_SAVEDPIXELSTATES_R
; i
++) {
2946 s
->Changed
.renderstate
[SavedPixelStates_R
[i
]] = TRUE
;
2948 for (j
=0; j
<This
->TextureUnits
; i
++) {
2949 for (i
=0; i
<NUM_SAVEDPIXELSTATES_T
; i
++) {
2950 s
->Changed
.texture_state
[j
][SavedPixelStates_T
[i
]] = TRUE
;
2954 } else if (Type
== D3DSBT_VERTEXSTATE
) {
2956 memset(&s
->Changed
, FALSE
, sizeof(This
->StateBlock
.Changed
));
2958 /* TODO: Vertex Shader Constants */
2959 s
->Changed
.vertexShader
= TRUE
;
2961 for (i
=0; i
<NUM_SAVEDVERTEXSTATES_R
; i
++) {
2962 s
->Changed
.renderstate
[SavedVertexStates_R
[i
]] = TRUE
;
2964 for (j
=0; j
<This
->TextureUnits
; i
++) {
2965 for (i
=0; i
<NUM_SAVEDVERTEXSTATES_T
; i
++) {
2966 s
->Changed
.texture_state
[j
][SavedVertexStates_T
[i
]] = TRUE
;
2970 for (i
=0; i
<MAX_ACTIVE_LIGHTS
; i
++) {
2971 s
->Changed
.lightEnable
[i
] = TRUE
;
2972 s
->Changed
.lights
[i
] = TRUE
;
2976 FIXME("Unrecognized state block type %d\n", Type
);
2978 TRACE("(%p) returning token (ptr to stateblock) of %lx\n", This
, *pToken
);
2982 HRESULT WINAPI
IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface
, CONST D3DCLIPSTATUS8
* pClipStatus
) {
2983 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2984 FIXME("(%p) : stub\n", This
); return D3D_OK
;
2986 HRESULT WINAPI
IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface
, D3DCLIPSTATUS8
* pClipStatus
) {
2987 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2988 FIXME("(%p) : stub\n", This
); return D3D_OK
;
2990 HRESULT WINAPI
IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface
, DWORD Stage
,IDirect3DBaseTexture8
** ppTexture
) {
2991 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
2992 TRACE("(%p) : returning %p for stage %ld\n", This
, This
->StateBlock
.textures
[Stage
], Stage
);
2993 *ppTexture
= (LPDIRECT3DBASETEXTURE8
)This
->StateBlock
.textures
[Stage
];
2994 IDirect3DBaseTexture8Impl_AddRef(*ppTexture
);
2997 HRESULT WINAPI
IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface
, DWORD Stage
,IDirect3DBaseTexture8
* pTexture
) {
2999 IDirect3DBaseTexture8
*oldTxt
;
3001 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3002 D3DRESOURCETYPE textureType
;
3004 oldTxt
= This
->StateBlock
.textures
[Stage
];
3005 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This
, Stage
, pTexture
);
3007 This
->UpdateStateBlock
->Set
.textures
[Stage
] = TRUE
;
3008 This
->UpdateStateBlock
->Changed
.textures
[Stage
] = TRUE
;
3009 This
->UpdateStateBlock
->textures
[Stage
] = pTexture
;
3011 /* Handle recording of state blocks */
3012 if (This
->isRecordingState
) {
3013 TRACE("Recording... not performing anything\n");
3017 /* Make appropriate texture active */
3018 if (This
->isMultiTexture
) {
3019 glActiveTextureARB(GL_TEXTURE0_ARB
+ Stage
);
3020 checkGLcall("glActiveTextureARB");
3021 } else if (Stage
>0) {
3022 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3025 /* Decrement the count of the previous texture */
3026 /* FIXME PERF: If old == new and not dirty then skip all this */
3027 if (oldTxt
!= NULL
) {
3028 IDirect3DBaseTexture8Impl_Release(oldTxt
);
3032 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8
)This
->StateBlock
.textures
[Stage
]);
3034 /* Now setup the texture appropraitly */
3035 textureType
= IDirect3DBaseTexture8Impl_GetType(pTexture
);
3037 if (textureType
== D3DRTYPE_TEXTURE
) {
3038 IDirect3DTexture8Impl
*pTexture2
= (IDirect3DTexture8Impl
*) pTexture
;
3041 /* Standard 2D texture */
3042 TRACE("Standard 2d texture\n");
3043 This
->StateBlock
.textureDimensions
[Stage
] = GL_TEXTURE_2D
;
3045 for (i
=0; i
<pTexture2
->levels
; i
++)
3048 if (i
==0 && pTexture2
->surfaces
[i
]->textureName
!= 0 && pTexture2
->Dirty
== FALSE
) {
3049 glBindTexture(GL_TEXTURE_2D
, pTexture2
->surfaces
[i
]->textureName
);
3050 checkGLcall("glBindTexture");
3051 TRACE("Texture %p (level %d) given name %d\n", pTexture2
->surfaces
[i
], i
, pTexture2
->surfaces
[i
]->textureName
);
3055 if (pTexture2
->surfaces
[i
]->textureName
== 0) {
3056 glGenTextures(1, &pTexture2
->surfaces
[i
]->textureName
);
3057 checkGLcall("glGenTextures");
3058 TRACE("Texture %p (level %d) given name %d\n", pTexture2
->surfaces
[i
], i
, pTexture2
->surfaces
[i
]->textureName
);
3061 glBindTexture(GL_TEXTURE_2D
, pTexture2
->surfaces
[i
]->textureName
);
3062 checkGLcall("glBindTexture");
3064 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", pTexture2
->levels
-1);
3065 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAX_LEVEL
, pTexture2
->levels
-1);
3066 checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels)");
3069 TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3070 GL_TEXTURE_2D
, i
, fmt2glintFmt(pTexture2
->format
), pTexture2
->surfaces
[i
]->myDesc
.Width
,
3071 pTexture2
->surfaces
[i
]->myDesc
.Height
, 0, fmt2glFmt(pTexture2
->format
),fmt2glType(pTexture2
->format
),
3072 pTexture2
->surfaces
[i
]->allocatedMemory
);
3073 glTexImage2D(GL_TEXTURE_2D
, i
,
3074 fmt2glintFmt(pTexture2
->format
),
3075 pTexture2
->surfaces
[i
]->myDesc
.Width
,
3076 pTexture2
->surfaces
[i
]->myDesc
.Height
,
3078 fmt2glFmt(pTexture2
->format
),
3079 fmt2glType(pTexture2
->format
),
3080 pTexture2
->surfaces
[i
]->allocatedMemory
3082 checkGLcall("glTexImage2D");
3084 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3085 pTexture2
->Dirty
= FALSE
;
3090 } else if (textureType
== D3DRTYPE_VOLUMETEXTURE
) {
3091 IDirect3DVolumeTexture8Impl
*pTexture2
= (IDirect3DVolumeTexture8Impl
*) pTexture
;
3094 /* Standard 3D (volume) texture */
3095 TRACE("Standard 3d texture\n");
3096 This
->StateBlock
.textureDimensions
[Stage
] = GL_TEXTURE_3D
;
3098 for (i
=0; i
<pTexture2
->levels
; i
++)
3101 if (i
==0 && pTexture2
->volumes
[i
]->textureName
!= 0 && pTexture2
->Dirty
== FALSE
) {
3102 glBindTexture(GL_TEXTURE_3D
, pTexture2
->volumes
[i
]->textureName
);
3103 checkGLcall("glBindTexture");
3104 TRACE("Texture %p given name %d\n", pTexture2
->volumes
[i
], pTexture2
->volumes
[i
]->textureName
);
3108 if (pTexture2
->volumes
[i
]->textureName
== 0) {
3109 glGenTextures(1, &pTexture2
->volumes
[i
]->textureName
);
3110 checkGLcall("glGenTextures");
3111 TRACE("Texture %p given name %d\n", pTexture2
->volumes
[i
], pTexture2
->volumes
[i
]->textureName
);
3114 glBindTexture(GL_TEXTURE_3D
, pTexture2
->volumes
[i
]->textureName
);
3115 checkGLcall("glBindTexture");
3117 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_MAX_LEVEL
, pTexture2
->levels
-1);
3118 checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, pTexture2->levels-1)");
3121 TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%lx, Mem=%p\n",
3122 GL_TEXTURE_3D
, i
, fmt2glintFmt(pTexture2
->format
), pTexture2
->volumes
[i
]->myDesc
.Width
,
3123 pTexture2
->volumes
[i
]->myDesc
.Height
, pTexture2
->volumes
[i
]->myDesc
.Depth
,
3124 0, fmt2glFmt(pTexture2
->format
),fmt2glType(pTexture2
->format
),
3125 pTexture2
->volumes
[i
]->allocatedMemory
);
3126 glTexImage3D(GL_TEXTURE_3D
, i
,
3127 fmt2glintFmt(pTexture2
->format
),
3128 pTexture2
->volumes
[i
]->myDesc
.Width
,
3129 pTexture2
->volumes
[i
]->myDesc
.Height
,
3130 pTexture2
->volumes
[i
]->myDesc
.Depth
,
3132 fmt2glFmt(pTexture2
->format
),
3133 fmt2glType(pTexture2
->format
),
3134 pTexture2
->volumes
[i
]->allocatedMemory
3136 checkGLcall("glTexImage3D");
3138 /* Removed glTexParameterf now TextureStageStates are initialized at startup */
3139 pTexture2
->Dirty
= FALSE
;
3144 FIXME("(%p) : Incorrect type for a texture : %d\n", This
, textureType
);
3147 TRACE("Setting to no texture (ie default texture)\n");
3148 This
->StateBlock
.textureDimensions
[Stage
] = GL_TEXTURE_1D
;
3149 glBindTexture(GL_TEXTURE_1D
, This
->dummyTextureName
[Stage
]);
3150 checkGLcall("glBindTexture");
3151 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage
, This
->dummyTextureName
[Stage
]);
3154 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3155 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3156 setupTextureStates (iface
, Stage
);
3161 HRESULT WINAPI
IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface
, DWORD Stage
,D3DTEXTURESTAGESTATETYPE Type
,DWORD
* pValue
) {
3162 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3163 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This
, Stage
, Type
, This
->StateBlock
.texture_state
[Stage
][Type
]);
3164 *pValue
= This
->StateBlock
.texture_state
[Stage
][Type
];
3168 HRESULT WINAPI
IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface
, DWORD Stage
,D3DTEXTURESTAGESTATETYPE Type
,DWORD Value
) {
3169 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3171 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3173 TRACE("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This
, Stage
, Type
, Value
);
3175 This
->UpdateStateBlock
->Changed
.texture_state
[Stage
][Type
] = TRUE
;
3176 This
->UpdateStateBlock
->Set
.texture_state
[Stage
][Type
] = TRUE
;
3177 This
->UpdateStateBlock
->texture_state
[Stage
][Type
] = Value
;
3179 /* Handle recording of state blocks */
3180 if (This
->isRecordingState
) {
3181 TRACE("Recording... not performing anything\n");
3185 /* Make appropriate texture active */
3186 TRACE("Activating appropriate texture state %ld\n", Stage
);
3187 if (This
->isMultiTexture
) {
3188 glActiveTextureARB(GL_TEXTURE0_ARB
+ Stage
);
3189 checkGLcall("glActiveTextureARB");
3190 } else if (Stage
>0) {
3191 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
3196 case D3DTSS_MINFILTER
:
3197 case D3DTSS_MIPFILTER
:
3199 DWORD ValueMIN
= This
->StateBlock
.texture_state
[Stage
][D3DTSS_MINFILTER
];
3200 DWORD ValueMIP
= This
->StateBlock
.texture_state
[Stage
][D3DTSS_MIPFILTER
];
3201 GLint realVal
= GL_LINEAR
;
3203 if (ValueMIN
== D3DTEXF_POINT
) {
3205 if (ValueMIP
== D3DTEXF_POINT
) {
3206 realVal
= GL_NEAREST_MIPMAP_NEAREST
;
3207 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
3208 realVal
= GL_NEAREST_MIPMAP_LINEAR
;
3209 } else if (ValueMIP
== D3DTEXF_NONE
) {
3210 realVal
= GL_NEAREST
;
3212 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
3213 realVal
= GL_NEAREST_MIPMAP_LINEAR
;
3215 } else if (ValueMIN
== D3DTEXF_LINEAR
) {
3217 if (ValueMIP
== D3DTEXF_POINT
) {
3218 realVal
= GL_LINEAR_MIPMAP_NEAREST
;
3219 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
3220 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3221 } else if (ValueMIP
== D3DTEXF_NONE
) {
3222 realVal
= GL_LINEAR
;
3224 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
3225 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3227 } else if (ValueMIN
== D3DTEXF_NONE
) {
3228 /* Doesnt really make sense - Windows just seems to disable
3229 mipmapping when this occurs */
3230 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3231 realVal
= GL_LINEAR
;
3234 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN
);
3235 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3238 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN
, ValueMIP
, realVal
);
3239 glTexParameteri(This
->StateBlock
.textureDimensions
[Stage
], GL_TEXTURE_MIN_FILTER
, realVal
);
3240 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
3245 case D3DTSS_MAGFILTER
:
3246 if (Value
== D3DTEXF_POINT
) {
3247 glTexParameteri(This
->StateBlock
.textureDimensions
[Stage
], GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
3248 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
3249 } else if (Value
== D3DTEXF_LINEAR
) {
3250 glTexParameteri(This
->StateBlock
.textureDimensions
[Stage
], GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
3251 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
3253 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value
);
3257 case D3DTSS_COLORARG0
:
3258 case D3DTSS_ALPHAARG0
:
3259 /* FIXME: Mesa seems to struggle setting these at the moment */
3262 case D3DTSS_COLORARG1
:
3263 case D3DTSS_COLORARG2
:
3264 case D3DTSS_ALPHAARG1
:
3265 case D3DTSS_ALPHAARG2
:
3267 BOOL isAlphaReplicate
= FALSE
;
3268 BOOL isComplement
= FALSE
;
3269 BOOL isAlphaArg
= (Type
== D3DTSS_ALPHAARG1
|| Type
== D3DTSS_ALPHAARG2
|| Type
== D3DTSS_ALPHAARG0
);
3270 int operand
= GL_SRC_COLOR
;
3271 int source
= GL_TEXTURE
;
3273 /* Catch alpha replicate */
3274 if (Value
& D3DTA_ALPHAREPLICATE
) {
3275 Value
= Value
& ~D3DTA_ALPHAREPLICATE
;
3276 isAlphaReplicate
= TRUE
;
3279 /* Catch Complement */
3280 if (Value
& D3DTA_COMPLEMENT
) {
3281 Value
= Value
& ~D3DTA_COMPLEMENT
;
3282 isComplement
= TRUE
;
3285 /* Calculate the operand */
3286 if (isAlphaReplicate
&& !isComplement
) {
3287 operand
= GL_SRC_ALPHA
;
3288 } else if (isAlphaReplicate
&& isComplement
) {
3289 operand
= GL_ONE_MINUS_SRC_ALPHA
;
3290 } else if (isComplement
) {
3292 operand
= GL_ONE_MINUS_SRC_COLOR
;
3294 operand
= GL_ONE_MINUS_SRC_ALPHA
;
3298 operand
= GL_SRC_ALPHA
;
3300 operand
= GL_SRC_COLOR
;
3304 /* Calculate the source */
3306 case D3DTA_CURRENT
: source
= GL_PREVIOUS_EXT
;
3308 case D3DTA_DIFFUSE
: source
= GL_PRIMARY_COLOR_EXT
;
3310 case D3DTA_TEXTURE
: source
= GL_TEXTURE
;
3312 case D3DTA_TFACTOR
: source
= GL_CONSTANT_EXT
;
3315 /* According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
3316 isnt supported until base GL supports it
3317 There is no concept of temp registers as far as I can tell */
3320 FIXME("Unrecognized or unhandled texture arg %ld\n", Value
);
3324 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type
), source
, OPERANDx_ALPHA_EXT(Type
), operand
);
3325 glTexEnvi(GL_TEXTURE_ENV
, SOURCEx_ALPHA_EXT(Type
), source
);
3326 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
3327 glTexEnvi(GL_TEXTURE_ENV
, OPERANDx_ALPHA_EXT(Type
), operand
);
3328 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
3330 TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type
), source
, OPERANDx_RGB_EXT(Type
), operand
);
3331 glTexEnvi(GL_TEXTURE_ENV
, SOURCEx_RGB_EXT(Type
), source
);
3332 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
3333 glTexEnvi(GL_TEXTURE_ENV
, OPERANDx_RGB_EXT(Type
), operand
);
3334 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
3339 case D3DTSS_ALPHAOP
:
3340 case D3DTSS_COLOROP
:
3344 int Parm
= (Type
== D3DTSS_ALPHAOP
)? GL_COMBINE_ALPHA_EXT
: GL_COMBINE_RGB_EXT
;
3346 if (Type
==D3DTSS_COLOROP
&& Value
== D3DTOP_DISABLE
) {
3347 /* TODO: Disable by making this and all later levels disabled */
3348 glDisable(GL_TEXTURE_1D
);
3349 checkGLcall("Disable GL_TEXTURE_1D");
3350 glDisable(GL_TEXTURE_2D
);
3351 checkGLcall("Disable GL_TEXTURE_2D");
3352 glDisable(GL_TEXTURE_3D
);
3353 checkGLcall("Disable GL_TEXTURE_3D");
3356 /* Enable only the appropriate texture dimension */
3357 if (Type
==D3DTSS_COLOROP
) {
3358 if (This
->StateBlock
.textureDimensions
[Stage
] == GL_TEXTURE_1D
) {
3359 glEnable(GL_TEXTURE_1D
);
3360 checkGLcall("Enable GL_TEXTURE_1D");
3362 glDisable(GL_TEXTURE_1D
);
3363 checkGLcall("Disable GL_TEXTURE_1D");
3365 if (This
->StateBlock
.textureDimensions
[Stage
] == GL_TEXTURE_2D
) {
3366 glEnable(GL_TEXTURE_2D
);
3367 checkGLcall("Enable GL_TEXTURE_2D");
3369 glDisable(GL_TEXTURE_2D
);
3370 checkGLcall("Disable GL_TEXTURE_2D");
3372 if (This
->StateBlock
.textureDimensions
[Stage
] == GL_TEXTURE_3D
) {
3373 glEnable(GL_TEXTURE_3D
);
3374 checkGLcall("Enable GL_TEXTURE_3D");
3376 glDisable(GL_TEXTURE_3D
);
3377 checkGLcall("Disable GL_TEXTURE_3D");
3381 /* Now set up the operand correctly */
3383 case D3DTOP_DISABLE
:
3384 /* Contrary to the docs, alpha can be disabled when colorop is enabled
3385 and it works, so ignore this op */
3386 TRACE("Disable ALPHAOP but COLOROP enabled!\n");
3389 case D3DTOP_SELECTARG1
:
3390 glTexEnvi(GL_TEXTURE_ENV
, Parm
, GL_REPLACE
);
3391 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
3394 case D3DTOP_MODULATE4X
: Scale
= Scale
* 2; /* Drop through */
3395 case D3DTOP_MODULATE2X
: Scale
= Scale
* 2; /* Drop through */
3396 case D3DTOP_MODULATE
:
3399 if (Type
== D3DTSS_ALPHAOP
) {
3400 glTexEnvi(GL_TEXTURE_ENV
, GL_ALPHA_SCALE
, Scale
);
3401 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
3403 glTexEnvi(GL_TEXTURE_ENV
, GL_RGB_SCALE_EXT
, Scale
);
3404 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
3406 glTexEnvi(GL_TEXTURE_ENV
, Parm
, GL_MODULATE
);
3407 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
3411 glTexEnvi(GL_TEXTURE_ENV
, Parm
, GL_ADD
);
3412 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
3415 case D3DTOP_ADDSIGNED2X
: Scale
= Scale
* 2; /* Drop through */
3416 case D3DTOP_ADDSIGNED
:
3417 glTexEnvi(GL_TEXTURE_ENV
, Parm
, GL_ADD_SIGNED_EXT
);
3418 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
3421 case D3DTOP_DOTPRODUCT3
:
3422 /*glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
3423 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
3426 case D3DTOP_SUBTRACT
:
3427 /* glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); Missing? */
3428 case D3DTOP_SELECTARG2
:
3429 /* GL_REPLACE, swap args 0 and 1? */
3430 case D3DTOP_ADDSMOOTH
:
3431 case D3DTOP_BLENDDIFFUSEALPHA
:
3432 case D3DTOP_BLENDTEXTUREALPHA
:
3433 case D3DTOP_BLENDFACTORALPHA
:
3434 case D3DTOP_BLENDTEXTUREALPHAPM
:
3435 case D3DTOP_BLENDCURRENTALPHA
:
3436 case D3DTOP_PREMODULATE
:
3437 case D3DTOP_MODULATEALPHA_ADDCOLOR
:
3438 case D3DTOP_MODULATECOLOR_ADDALPHA
:
3439 case D3DTOP_MODULATEINVALPHA_ADDCOLOR
:
3440 case D3DTOP_MODULATEINVCOLOR_ADDALPHA
:
3441 case D3DTOP_BUMPENVMAP
:
3442 case D3DTOP_BUMPENVMAPLUMINANCE
:
3443 case D3DTOP_MULTIPLYADD
:
3446 FIXME("Unhandled texture operation %ld\n", Value
);
3452 case D3DTSS_ADDRESSU
:
3453 case D3DTSS_ADDRESSV
:
3454 case D3DTSS_ADDRESSW
:
3456 GLint wrapParm
= GL_REPEAT
;
3458 case D3DTADDRESS_WRAP
: wrapParm
= GL_REPEAT
; break;
3459 case D3DTADDRESS_CLAMP
: wrapParm
= GL_CLAMP
; break;
3460 case D3DTADDRESS_BORDER
: wrapParm
= GL_CLAMP_TO_EDGE
; break;
3462 case D3DTADDRESS_MIRROR
: /* Unsupported in OpenGL? */
3463 case D3DTADDRESS_MIRRORONCE
: /* Unsupported in OpenGL? */
3465 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value
, Type
);
3466 wrapParm
= GL_REPEAT
;
3470 case D3DTSS_ADDRESSU
:
3471 TRACE("Setting WRAP_S to %d for %x\n", wrapParm
, This
->StateBlock
.textureDimensions
[Stage
]);
3472 glTexParameteri(This
->StateBlock
.textureDimensions
[Stage
], GL_TEXTURE_WRAP_S
, wrapParm
);
3473 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3475 case D3DTSS_ADDRESSV
:
3476 TRACE("Setting WRAP_T to %d for %x\n", wrapParm
, This
->StateBlock
.textureDimensions
[Stage
]);
3477 glTexParameteri(This
->StateBlock
.textureDimensions
[Stage
], GL_TEXTURE_WRAP_T
, wrapParm
);
3478 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3480 case D3DTSS_ADDRESSW
:
3481 TRACE("Setting WRAP_R to %d for %x\n", wrapParm
, This
->StateBlock
.textureDimensions
[Stage
]);
3482 glTexParameteri(This
->StateBlock
.textureDimensions
[Stage
], GL_TEXTURE_WRAP_R
, wrapParm
);
3483 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3486 break; /** stupic compilator */
3491 case D3DTSS_BORDERCOLOR
:
3494 col
[0] = ((Value
>> 16) & 0xFF) / 255.0;
3495 col
[1] = ((Value
>> 8) & 0xFF) / 255.0;
3496 col
[2] = ((Value
>> 0) & 0xFF) / 255.0;
3497 col
[3] = ((Value
>> 24) & 0xFF) / 255.0;
3499 TRACE("Setting border color for %x to %lx\n", This
->StateBlock
.textureDimensions
[Stage
], Value
);
3500 glTexParameterfv(This
->StateBlock
.textureDimensions
[Stage
], GL_TEXTURE_BORDER_COLOR
, &col
[0]);
3501 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3506 case D3DTSS_BUMPENVMAT00
:
3507 case D3DTSS_BUMPENVMAT01
:
3508 case D3DTSS_BUMPENVMAT10
:
3509 case D3DTSS_BUMPENVMAT11
:
3510 case D3DTSS_TEXCOORDINDEX
:
3511 case D3DTSS_MIPMAPLODBIAS
:
3512 case D3DTSS_MAXMIPLEVEL
:
3513 case D3DTSS_MAXANISOTROPY
:
3514 case D3DTSS_BUMPENVLSCALE
:
3515 case D3DTSS_BUMPENVLOFFSET
:
3516 case D3DTSS_TEXTURETRANSFORMFLAGS
:
3517 case D3DTSS_RESULTARG
:
3519 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3520 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3524 HRESULT WINAPI
IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface
, DWORD
* pNumPasses
) {
3525 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3526 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3528 HRESULT WINAPI
IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface
, DWORD DevInfoID
,void* pDevInfoStruct
,DWORD DevInfoStructSize
) {
3529 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3530 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3532 HRESULT WINAPI
IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface
, UINT PaletteNumber
,CONST PALETTEENTRY
* pEntries
) {
3533 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3534 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3536 HRESULT WINAPI
IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface
, UINT PaletteNumber
,PALETTEENTRY
* pEntries
) {
3537 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3538 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3540 HRESULT WINAPI
IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface
, UINT PaletteNumber
) {
3541 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3542 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3544 HRESULT WINAPI
IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface
, UINT
*PaletteNumber
) {
3545 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3546 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3548 HRESULT WINAPI
IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
,UINT StartVertex
,UINT PrimitiveCount
) {
3550 IDirect3DVertexBuffer8
*pVB
;
3552 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3553 pVB
= This
->StateBlock
.stream_source
[0];
3555 TRACE("(%p) : Type=%d, Start=%d, Count=%d\n", This
, PrimitiveType
, StartVertex
, PrimitiveCount
);
3557 DrawPrimitiveI(iface
, PrimitiveType
, PrimitiveCount
, FALSE
,
3558 This
->StateBlock
.VertexShader
, ((IDirect3DVertexBuffer8Impl
*)pVB
)->allocatedMemory
, StartVertex
, -1, 0, NULL
, 0);
3562 HRESULT WINAPI
IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
,
3563 UINT minIndex
,UINT NumVertices
,UINT startIndex
,UINT primCount
) {
3565 IDirect3DIndexBuffer8
*pIB
;
3566 IDirect3DVertexBuffer8
*pVB
;
3567 D3DINDEXBUFFER_DESC IdxBufDsc
;
3569 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3570 pIB
= This
->StateBlock
.pIndexData
;
3571 pVB
= This
->StateBlock
.stream_source
[0];
3573 TRACE("(%p) : Type=%d, min=%d, CountV=%d, startIdx=%d, countP=%d \n", This
, PrimitiveType
,
3574 minIndex
, NumVertices
, startIndex
, primCount
);
3576 IDirect3DIndexBuffer8Impl_GetDesc(pIB
, &IdxBufDsc
);
3577 if (IdxBufDsc
.Format
== D3DFMT_INDEX16
) {
3583 DrawPrimitiveI(iface
, PrimitiveType
, primCount
, TRUE
, This
->StateBlock
.VertexShader
, ((IDirect3DVertexBuffer8Impl
*)pVB
)->allocatedMemory
,
3584 This
->StateBlock
.baseVertexIndex
, startIndex
, idxStride
, ((IDirect3DIndexBuffer8Impl
*) pIB
)->allocatedMemory
,
3589 HRESULT WINAPI
IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
,UINT PrimitiveCount
,CONST
void* pVertexStreamZeroData
,UINT VertexStreamZeroStride
) {
3590 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3592 TRACE("(%p) : Type=%d, pCount=%d, pVtxData=%p, Stride=%d\n", This
, PrimitiveType
, PrimitiveCount
, pVertexStreamZeroData
, VertexStreamZeroStride
);
3594 if (This
->StateBlock
.stream_source
[0] != NULL
) IDirect3DVertexBuffer8Impl_Release(This
->StateBlock
.stream_source
[0]);
3596 This
->StateBlock
.stream_source
[0] = NULL
;
3597 This
->StateBlock
.stream_stride
[0] = VertexStreamZeroStride
;
3598 DrawPrimitiveI(iface
, PrimitiveType
, PrimitiveCount
, FALSE
, This
->StateBlock
.VertexShader
, pVertexStreamZeroData
,
3600 This
->StateBlock
.stream_stride
[0] = 0;
3602 /*stream zero settings set to null at end */
3605 HRESULT WINAPI
IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
,UINT MinVertexIndex
,
3606 UINT NumVertexIndices
,UINT PrimitiveCount
,CONST
void* pIndexData
,
3607 D3DFORMAT IndexDataFormat
,CONST
void* pVertexStreamZeroData
,
3608 UINT VertexStreamZeroStride
) {
3610 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3611 TRACE("(%p) : Type=%d, MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This
, PrimitiveType
,
3612 MinVertexIndex
, NumVertexIndices
, PrimitiveCount
, pIndexData
, IndexDataFormat
, pVertexStreamZeroData
, VertexStreamZeroStride
);
3614 if (This
->StateBlock
.stream_source
[0] != NULL
) IDirect3DVertexBuffer8Impl_Release(This
->StateBlock
.stream_source
[0]);
3615 if (IndexDataFormat
== D3DFMT_INDEX16
) {
3621 This
->StateBlock
.stream_source
[0] = NULL
;
3622 This
->StateBlock
.stream_stride
[0] = VertexStreamZeroStride
;
3623 DrawPrimitiveI(iface
, PrimitiveType
, PrimitiveCount
, TRUE
, This
->StateBlock
.VertexShader
, pVertexStreamZeroData
,
3624 This
->StateBlock
.baseVertexIndex
, 0, idxStride
, pIndexData
, MinVertexIndex
);
3626 /*stream zero settings set to null at end */
3627 This
->StateBlock
.stream_stride
[0] = 0;
3628 IDirect3DDevice8Impl_SetIndices(iface
, NULL
, 0);
3632 HRESULT WINAPI
IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface
, UINT SrcStartIndex
,UINT DestIndex
,UINT VertexCount
,IDirect3DVertexBuffer8
* pDestBuffer
,DWORD Flags
) {
3633 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3634 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3636 HRESULT WINAPI
IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface
, CONST DWORD
* pDeclaration
, CONST DWORD
* pFunction
, DWORD
* pHandle
, DWORD Usage
) {
3637 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3638 VERTEXSHADER8
* object
;
3641 FIXME("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This
, pDeclaration
, pFunction
);
3642 if (NULL
== pDeclaration
|| NULL
== pHandle
) { /* pFunction can be NULL see MSDN */
3643 return D3DERR_INVALIDCALL
;
3645 for (i
= 1; NULL
!= VertexShaders
[i
] && i
< sizeof(VertexShaders
) / sizeof(VERTEXSHADER8
*); ++i
) ;
3646 if (i
>= sizeof(VertexShaders
) / sizeof(VERTEXSHADER8
*)) {
3647 return D3DERR_OUTOFVIDEOMEMORY
;
3649 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(VERTEXSHADER8
));
3650 if (NULL
== object
) {
3651 return D3DERR_OUTOFVIDEOMEMORY
;
3654 object
->usage
= Usage
;
3655 object
->data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SHADERDATA8
));
3657 VertexShaders
[i
] = object
;
3658 *pHandle
= VS_HIGHESTFIXEDFXF
+ i
;
3660 object
->decl
= (DWORD
*) pDeclaration
;
3661 object
->function
= (DWORD
*) pFunction
;
3663 vshader_decl_parse(object
);
3664 vshader_program_parse(object
);
3666 /* copy the function ... because it will certainly be released by application */
3667 if (NULL
!= pFunction
) {
3668 object
->function
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->functionLength
);
3669 memcpy(object
->function
, pFunction
, object
->functionLength
);
3671 /* copy the declaration too */
3672 object
->decl
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->declLength
);
3673 memcpy(object
->decl
, pDeclaration
, object
->declLength
);
3676 HRESULT WINAPI
IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
3677 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3679 This
->UpdateStateBlock
->VertexShader
= Handle
;
3680 This
->UpdateStateBlock
->Changed
.vertexShader
= TRUE
;
3681 This
->UpdateStateBlock
->Set
.vertexShader
= TRUE
;
3683 /* Handle recording of state blocks */
3684 if (This
->isRecordingState
) {
3685 TRACE("Recording... not performing anything\n");
3688 if (Handle
<= VS_HIGHESTFIXEDFXF
) {
3689 TRACE("(%p) : FVF Shader, Handle=%lx\n", This
, Handle
);
3692 FIXME("(%p) : Created shader, Handle=%lx stub\n", This
, Handle
);
3696 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface
, DWORD
* pHandle
) {
3697 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3698 TRACE("(%p) : GetVertexShader returning %ld\n", This
, This
->StateBlock
.VertexShader
);
3699 *pHandle
= This
->StateBlock
.VertexShader
;
3703 HRESULT WINAPI
IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
3704 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3705 VERTEXSHADER8
* object
;
3707 if (Handle
<= VS_HIGHESTFIXEDFXF
) { /* only delete user defined shaders */
3708 return D3DERR_INVALIDCALL
;
3710 object
= VertexShaders
[Handle
- VS_HIGHESTFIXEDFXF
];
3711 if (NULL
== object
) {
3712 return D3DERR_INVALIDCALL
;
3714 TRACE("(%p) : freing VertexShader %p\n", This
, object
);
3715 /* TODO: check validity of object */
3716 if (NULL
!= object
->function
) HeapFree(GetProcessHeap(), 0, (void *)object
->function
);
3717 HeapFree(GetProcessHeap(), 0, (void *)object
->decl
);
3718 HeapFree(GetProcessHeap(), 0, (void *)object
->data
);
3719 HeapFree(GetProcessHeap(), 0, (void *)object
);
3720 VertexShaders
[Handle
- VS_HIGHESTFIXEDFXF
] = NULL
;
3724 HRESULT WINAPI
IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
, CONST
void* pConstantData
, DWORD ConstantCount
) {
3725 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3726 VERTEXSHADER8
* object
;
3727 DWORD Handle
= This
->UpdateStateBlock
->VertexShader
;
3729 /* FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); */
3730 if (Register
+ ConstantCount
> D3D8_VSHADER_MAX_CONSTANTS
) {
3731 return D3DERR_INVALIDCALL
;
3733 object
= VERTEX_SHADER(Handle
);
3734 if (NULL
== object
|| NULL
== pConstantData
) {
3735 return D3DERR_INVALIDCALL
;
3737 if (NULL
== object
->data
) { /* temporary while datas not supported */
3738 FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This
);
3739 return D3DERR_INVALIDCALL
;
3741 memcpy(object
->data
->C
+ Register
, pConstantData
, ConstantCount
* sizeof(D3DSHADERVECTOR
));
3745 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
, void* pConstantData
, DWORD ConstantCount
) {
3746 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3747 VERTEXSHADER8
* object
;
3748 DWORD Handle
= This
->UpdateStateBlock
->VertexShader
;
3750 FIXME("(%p) : VertexShader_GetConstant not fully supported yet\n", This
);
3752 if (Register
+ ConstantCount
> D3D8_VSHADER_MAX_CONSTANTS
) {
3753 return D3DERR_INVALIDCALL
;
3755 object
= VERTEX_SHADER(Handle
);
3756 if (NULL
== object
|| NULL
== pConstantData
) {
3757 return D3DERR_INVALIDCALL
;
3759 if (NULL
== object
->data
) { /* temporary while datas not supported */
3760 return D3DERR_INVALIDCALL
;
3762 memcpy(pConstantData
, object
->data
->C
+ Register
, ConstantCount
* sizeof(D3DSHADERVECTOR
));
3766 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface
, DWORD Handle
, void* pData
, DWORD
* pSizeOfData
) {
3767 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3768 VERTEXSHADER8
* object
;
3770 object
= VERTEX_SHADER(Handle
);
3771 if (NULL
== object
) {
3772 return D3DERR_INVALIDCALL
;
3774 if (NULL
== pData
) {
3775 *pSizeOfData
= object
->declLength
;
3778 if (*pSizeOfData
< object
->declLength
) {
3779 *pSizeOfData
= object
->declLength
;
3780 return D3DERR_MOREDATA
;
3782 TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This
, pData
);
3783 memcpy(pData
, object
->decl
, object
->declLength
);
3786 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface
, DWORD Handle
, void* pData
, DWORD
* pSizeOfData
) {
3787 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3788 VERTEXSHADER8
* object
;
3790 object
= VERTEX_SHADER(Handle
);
3791 if (NULL
== object
) {
3792 return D3DERR_INVALIDCALL
;
3794 if (NULL
== pData
) {
3795 *pSizeOfData
= object
->functionLength
;
3798 if (*pSizeOfData
< object
->functionLength
) {
3799 *pSizeOfData
= object
->functionLength
;
3800 return D3DERR_MOREDATA
;
3802 if (NULL
== object
->function
) { /* no function defined */
3803 TRACE("(%p) : GetVertexShaderFunction no User Function defined using NULL to %p\n", This
, pData
);
3804 ((DWORD
*) pData
) = NULL
;
3806 TRACE("(%p) : GetVertexShaderFunction copying to %p\n", This
, pData
);
3807 memcpy(pData
, object
->function
, object
->functionLength
);
3812 HRESULT WINAPI
IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface
, IDirect3DIndexBuffer8
* pIndexData
,UINT BaseVertexIndex
) {
3813 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3814 IDirect3DIndexBuffer8
*oldIdxs
;
3816 TRACE("(%p) : Setting to %p, base %d\n", This
, pIndexData
, BaseVertexIndex
);
3817 oldIdxs
= This
->StateBlock
.pIndexData
;
3819 This
->UpdateStateBlock
->Changed
.Indices
= TRUE
;
3820 This
->UpdateStateBlock
->Set
.Indices
= TRUE
;
3821 This
->UpdateStateBlock
->pIndexData
= pIndexData
;
3822 This
->UpdateStateBlock
->baseVertexIndex
= BaseVertexIndex
;
3824 /* Handle recording of state blocks */
3825 if (This
->isRecordingState
) {
3826 TRACE("Recording... not performing anything\n");
3830 if (oldIdxs
) IDirect3DIndexBuffer8Impl_Release(oldIdxs
);
3831 if (pIndexData
) IDirect3DIndexBuffer8Impl_AddRef(This
->StateBlock
.pIndexData
);
3834 HRESULT WINAPI
IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface
, IDirect3DIndexBuffer8
** ppIndexData
,UINT
* pBaseVertexIndex
) {
3835 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3836 FIXME("(%p) : stub\n", This
);
3838 *ppIndexData
= This
->StateBlock
.pIndexData
;
3839 /* up ref count on ppindexdata */
3840 if (*ppIndexData
) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData
);
3841 *pBaseVertexIndex
= This
->StateBlock
.baseVertexIndex
;
3845 HRESULT WINAPI
IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface
, CONST DWORD
* pFunction
, DWORD
* pHandle
) {
3846 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3847 PIXELSHADER8
* object
;
3850 FIXME("(%p) : PixelShader not fully supported yet\n", This
);
3851 if (NULL
== pFunction
|| NULL
== pHandle
) {
3852 return D3DERR_INVALIDCALL
;
3854 for (i
= 1; NULL
!= PixelShaders
[i
] && i
< sizeof(PixelShaders
) / sizeof(PIXELSHADER8
*); ++i
) ;
3855 if (i
>= sizeof(PixelShaders
) / sizeof(PIXELSHADER8
*)) {
3856 return D3DERR_OUTOFVIDEOMEMORY
;
3858 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PIXELSHADER8
));
3859 if (NULL
== object
) {
3860 return D3DERR_OUTOFVIDEOMEMORY
;
3863 object
->data
= NULL
; /* TODO */
3865 PixelShaders
[i
] = object
;
3866 *pHandle
= VS_HIGHESTFIXEDFXF
+ i
;
3868 object
->function
= pFunction
;
3869 for (i
= 0; 0xFFFFFFFF != pFunction
[i
]; ++i
) ;
3870 object
->functionLength
= i
+ 1;
3874 HRESULT WINAPI
IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
3875 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3877 This
->UpdateStateBlock
->PixelShader
= Handle
;
3878 This
->UpdateStateBlock
->Changed
.pixelShader
= TRUE
;
3879 This
->UpdateStateBlock
->Set
.pixelShader
= TRUE
;
3881 /* Handle recording of state blocks */
3882 if (This
->isRecordingState
) {
3883 TRACE("Recording... not performing anything\n");
3887 /* FIXME: Quieten when not being used */
3889 FIXME("(%p) : stub %ld\n", This
, Handle
);
3891 TRACE("(%p) : stub %ld\n", This
, Handle
);
3896 HRESULT WINAPI
IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface
, DWORD
* pHandle
) {
3897 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3898 TRACE("(%p) : GetPixelShader returning %ld\n", This
, This
->StateBlock
.PixelShader
);
3899 *pHandle
= This
->StateBlock
.PixelShader
;
3903 HRESULT WINAPI
IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
3904 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3905 PIXELSHADER8
* object
;
3907 if (Handle
<= VS_HIGHESTFIXEDFXF
) { /* only delete user defined shaders */
3908 return D3DERR_INVALIDCALL
;
3910 object
= PixelShaders
[Handle
- VS_HIGHESTFIXEDFXF
];
3911 TRACE("(%p) : freeing PixelShader %p\n", This
, object
);
3912 /* TODO: check validity of object before free */
3913 HeapFree(GetProcessHeap(), 0, (void *)object
);
3914 PixelShaders
[Handle
- VS_HIGHESTFIXEDFXF
] = 0;
3917 #define PIXEL_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(PixelShaders) / sizeof(PIXELSHADER8*)) ? NULL : PixelShaders[Handle]) : PixelShaders[Handle - VS_HIGHESTFIXEDFXF])
3919 HRESULT WINAPI
IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
,CONST
void* pConstantData
, DWORD ConstantCount
) {
3920 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3921 FIXME("(%p) : stub\n", This
);
3924 HRESULT WINAPI
IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
,void* pConstantData
, DWORD ConstantCount
) {
3925 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3926 FIXME("(%p) : stub\n", This
);
3929 HRESULT WINAPI
IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface
, DWORD Handle
, void* pData
, DWORD
* pSizeOfData
) {
3930 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3931 PIXELSHADER8
* object
;
3933 object
= PIXEL_SHADER(Handle
);
3934 if (NULL
== object
) {
3935 return D3DERR_INVALIDCALL
;
3937 if (NULL
== pData
) {
3938 *pSizeOfData
= object
->functionLength
;
3941 if (*pSizeOfData
< object
->functionLength
) {
3942 *pSizeOfData
= object
->functionLength
;
3943 return D3DERR_MOREDATA
;
3945 TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This
, pData
);
3946 memcpy(pData
, object
->function
, object
->functionLength
);
3949 HRESULT WINAPI
IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface
, UINT Handle
,CONST
float* pNumSegs
,CONST D3DRECTPATCH_INFO
* pRectPatchInfo
) {
3950 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3951 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3953 HRESULT WINAPI
IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface
, UINT Handle
,CONST
float* pNumSegs
,CONST D3DTRIPATCH_INFO
* pTriPatchInfo
) {
3954 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3955 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3957 HRESULT WINAPI
IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface
, UINT Handle
) {
3958 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3959 FIXME("(%p) : stub\n", This
); return D3D_OK
;
3962 HRESULT WINAPI
IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface
, UINT StreamNumber
,IDirect3DVertexBuffer8
* pStreamData
,UINT Stride
) {
3963 IDirect3DVertexBuffer8
*oldSrc
;
3964 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3966 oldSrc
= This
->StateBlock
.stream_source
[StreamNumber
];
3967 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This
, StreamNumber
, oldSrc
, pStreamData
, Stride
);
3969 This
->UpdateStateBlock
->Changed
.stream_source
[StreamNumber
] = TRUE
;
3970 This
->UpdateStateBlock
->Set
.stream_source
[StreamNumber
] = TRUE
;
3971 This
->UpdateStateBlock
->stream_stride
[StreamNumber
] = Stride
;
3972 This
->UpdateStateBlock
->stream_source
[StreamNumber
] = pStreamData
;
3974 /* Handle recording of state blocks */
3975 if (This
->isRecordingState
) {
3976 TRACE("Recording... not performing anything\n");
3980 if (oldSrc
!= NULL
) IDirect3DVertexBuffer8Impl_Release(oldSrc
);
3981 if (pStreamData
!= NULL
) IDirect3DVertexBuffer8Impl_AddRef(pStreamData
);
3984 HRESULT WINAPI
IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface
, UINT StreamNumber
,IDirect3DVertexBuffer8
** pStream
,UINT
* pStride
) {
3985 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
3986 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This
, StreamNumber
, This
->StateBlock
.stream_source
[StreamNumber
], This
->StateBlock
.stream_stride
[StreamNumber
]);
3987 *pStream
= This
->StateBlock
.stream_source
[StreamNumber
];
3988 *pStride
= This
->StateBlock
.stream_stride
[StreamNumber
];
3989 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8
) *pStream
);
3994 ICOM_VTABLE(IDirect3DDevice8
) Direct3DDevice8_Vtbl
=
3996 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3997 IDirect3DDevice8Impl_QueryInterface
,
3998 IDirect3DDevice8Impl_AddRef
,
3999 IDirect3DDevice8Impl_Release
,
4000 IDirect3DDevice8Impl_TestCooperativeLevel
,
4001 IDirect3DDevice8Impl_GetAvailableTextureMem
,
4002 IDirect3DDevice8Impl_ResourceManagerDiscardBytes
,
4003 IDirect3DDevice8Impl_GetDirect3D
,
4004 IDirect3DDevice8Impl_GetDeviceCaps
,
4005 IDirect3DDevice8Impl_GetDisplayMode
,
4006 IDirect3DDevice8Impl_GetCreationParameters
,
4007 IDirect3DDevice8Impl_SetCursorProperties
,
4008 IDirect3DDevice8Impl_SetCursorPosition
,
4009 IDirect3DDevice8Impl_ShowCursor
,
4010 IDirect3DDevice8Impl_CreateAdditionalSwapChain
,
4011 IDirect3DDevice8Impl_Reset
,
4012 IDirect3DDevice8Impl_Present
,
4013 IDirect3DDevice8Impl_GetBackBuffer
,
4014 IDirect3DDevice8Impl_GetRasterStatus
,
4015 IDirect3DDevice8Impl_SetGammaRamp
,
4016 IDirect3DDevice8Impl_GetGammaRamp
,
4017 IDirect3DDevice8Impl_CreateTexture
,
4018 IDirect3DDevice8Impl_CreateVolumeTexture
,
4019 IDirect3DDevice8Impl_CreateCubeTexture
,
4020 IDirect3DDevice8Impl_CreateVertexBuffer
,
4021 IDirect3DDevice8Impl_CreateIndexBuffer
,
4022 IDirect3DDevice8Impl_CreateRenderTarget
,
4023 IDirect3DDevice8Impl_CreateDepthStencilSurface
,
4024 IDirect3DDevice8Impl_CreateImageSurface
,
4025 IDirect3DDevice8Impl_CopyRects
,
4026 IDirect3DDevice8Impl_UpdateTexture
,
4027 IDirect3DDevice8Impl_GetFrontBuffer
,
4028 IDirect3DDevice8Impl_SetRenderTarget
,
4029 IDirect3DDevice8Impl_GetRenderTarget
,
4030 IDirect3DDevice8Impl_GetDepthStencilSurface
,
4031 IDirect3DDevice8Impl_BeginScene
,
4032 IDirect3DDevice8Impl_EndScene
,
4033 IDirect3DDevice8Impl_Clear
,
4034 IDirect3DDevice8Impl_SetTransform
,
4035 IDirect3DDevice8Impl_GetTransform
,
4036 IDirect3DDevice8Impl_MultiplyTransform
,
4037 IDirect3DDevice8Impl_SetViewport
,
4038 IDirect3DDevice8Impl_GetViewport
,
4039 IDirect3DDevice8Impl_SetMaterial
,
4040 IDirect3DDevice8Impl_GetMaterial
,
4041 IDirect3DDevice8Impl_SetLight
,
4042 IDirect3DDevice8Impl_GetLight
,
4043 IDirect3DDevice8Impl_LightEnable
,
4044 IDirect3DDevice8Impl_GetLightEnable
,
4045 IDirect3DDevice8Impl_SetClipPlane
,
4046 IDirect3DDevice8Impl_GetClipPlane
,
4047 IDirect3DDevice8Impl_SetRenderState
,
4048 IDirect3DDevice8Impl_GetRenderState
,
4049 IDirect3DDevice8Impl_BeginStateBlock
,
4050 IDirect3DDevice8Impl_EndStateBlock
,
4051 IDirect3DDevice8Impl_ApplyStateBlock
,
4052 IDirect3DDevice8Impl_CaptureStateBlock
,
4053 IDirect3DDevice8Impl_DeleteStateBlock
,
4054 IDirect3DDevice8Impl_CreateStateBlock
,
4055 IDirect3DDevice8Impl_SetClipStatus
,
4056 IDirect3DDevice8Impl_GetClipStatus
,
4057 IDirect3DDevice8Impl_GetTexture
,
4058 IDirect3DDevice8Impl_SetTexture
,
4059 IDirect3DDevice8Impl_GetTextureStageState
,
4060 IDirect3DDevice8Impl_SetTextureStageState
,
4061 IDirect3DDevice8Impl_ValidateDevice
,
4062 IDirect3DDevice8Impl_GetInfo
,
4063 IDirect3DDevice8Impl_SetPaletteEntries
,
4064 IDirect3DDevice8Impl_GetPaletteEntries
,
4065 IDirect3DDevice8Impl_SetCurrentTexturePalette
,
4066 IDirect3DDevice8Impl_GetCurrentTexturePalette
,
4067 IDirect3DDevice8Impl_DrawPrimitive
,
4068 IDirect3DDevice8Impl_DrawIndexedPrimitive
,
4069 IDirect3DDevice8Impl_DrawPrimitiveUP
,
4070 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP
,
4071 IDirect3DDevice8Impl_ProcessVertices
,
4072 IDirect3DDevice8Impl_CreateVertexShader
,
4073 IDirect3DDevice8Impl_SetVertexShader
,
4074 IDirect3DDevice8Impl_GetVertexShader
,
4075 IDirect3DDevice8Impl_DeleteVertexShader
,
4076 IDirect3DDevice8Impl_SetVertexShaderConstant
,
4077 IDirect3DDevice8Impl_GetVertexShaderConstant
,
4078 IDirect3DDevice8Impl_GetVertexShaderDeclaration
,
4079 IDirect3DDevice8Impl_GetVertexShaderFunction
,
4080 IDirect3DDevice8Impl_SetStreamSource
,
4081 IDirect3DDevice8Impl_GetStreamSource
,
4082 IDirect3DDevice8Impl_SetIndices
,
4083 IDirect3DDevice8Impl_GetIndices
,
4084 IDirect3DDevice8Impl_CreatePixelShader
,
4085 IDirect3DDevice8Impl_SetPixelShader
,
4086 IDirect3DDevice8Impl_GetPixelShader
,
4087 IDirect3DDevice8Impl_DeletePixelShader
,
4088 IDirect3DDevice8Impl_SetPixelShaderConstant
,
4089 IDirect3DDevice8Impl_GetPixelShaderConstant
,
4090 IDirect3DDevice8Impl_GetPixelShaderFunction
,
4091 IDirect3DDevice8Impl_DrawRectPatch
,
4092 IDirect3DDevice8Impl_DrawTriPatch
,
4093 IDirect3DDevice8Impl_DeletePatch
4096 void CreateStateBlock(LPDIRECT3DDEVICE8 iface
) {
4100 ICOM_THIS(IDirect3DDevice8Impl
,iface
);
4102 /* Note this may have a large overhead but it should only be executed
4103 once, in order to initialize the complete state of the device and
4104 all opengl equivalents */
4105 TRACE("-----------------------> Setting up device defaults...\n");
4106 This
->StateBlock
.blockType
= D3DSBT_ALL
;
4108 /* FIXME: Set some of the defaults for lights, transforms etc */
4109 memcpy(&This
->StateBlock
.transforms
[D3DTS_WORLDMATRIX(0)], &idmatrix
, sizeof(idmatrix
));
4110 memcpy(&This
->StateBlock
.transforms
[D3DTS_PROJECTION
], &idmatrix
, sizeof(idmatrix
));
4111 memcpy(&This
->StateBlock
.transforms
[D3DTS_VIEW
], &idmatrix
, sizeof(idmatrix
));
4113 /* Render states: */
4114 if (This
->PresentParms
.EnableAutoDepthStencil
) {
4115 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZENABLE
, D3DZB_TRUE
);
4117 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZENABLE
, D3DZB_FALSE
);
4119 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FILLMODE
, D3DFILL_SOLID
);
4120 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SHADEMODE
, D3DSHADE_GOURAUD
);
4121 lp
.wRepeatFactor
= 0; lp
.wLinePattern
= 0; IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LINEPATTERN
, (DWORD
) &lp
);
4122 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZWRITEENABLE
, TRUE
);
4123 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHATESTENABLE
, FALSE
);
4124 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LASTPIXEL
, TRUE
);
4125 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SRCBLEND
, D3DBLEND_ONE
);
4126 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DESTBLEND
, D3DBLEND_ZERO
);
4127 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_CULLMODE
, D3DCULL_CCW
);
4128 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZFUNC
, D3DCMP_LESSEQUAL
);
4129 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHAFUNC
, D3DCMP_ALWAYS
);
4130 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHAREF
, 0xff); /*??*/
4131 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DITHERENABLE
, FALSE
);
4132 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ALPHABLENDENABLE
, FALSE
);
4133 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGENABLE
, FALSE
);
4134 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SPECULARENABLE
, FALSE
);
4135 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZVISIBLE
, 0);
4136 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGCOLOR
, 0);
4137 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGTABLEMODE
, D3DFOG_NONE
);
4138 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGSTART
, 0.0f
);
4139 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGEND
, 1.0f
);
4140 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGDENSITY
, 1.0f
);
4141 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_EDGEANTIALIAS
, FALSE
);
4142 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_ZBIAS
, 0);
4143 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_RANGEFOGENABLE
, FALSE
);
4144 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILENABLE
, FALSE
);
4145 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILFAIL
, D3DSTENCILOP_KEEP
);
4146 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILZFAIL
, D3DSTENCILOP_KEEP
);
4147 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILPASS
, D3DSTENCILOP_KEEP
);
4148 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILFUNC
, D3DCMP_ALWAYS
);
4149 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILREF
, 0);
4150 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILMASK
, 0xFFFFFFFF);
4151 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_STENCILWRITEMASK
, 0xFFFFFFFF);
4152 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_TEXTUREFACTOR
, 0xFFFFFFFF);
4153 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP0
, 0);
4154 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP1
, 0);
4155 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP2
, 0);
4156 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP3
, 0);
4157 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP4
, 0);
4158 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP5
, 0);
4159 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP6
, 0);
4160 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_WRAP7
, 0);
4161 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_CLIPPING
, TRUE
);
4162 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LIGHTING
, TRUE
);
4163 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_AMBIENT
, 0);
4164 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_FOGVERTEXMODE
, D3DFOG_NONE
);
4165 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_COLORVERTEX
, TRUE
);
4166 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_LOCALVIEWER
, TRUE
);
4167 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_NORMALIZENORMALS
, FALSE
);
4168 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DIFFUSEMATERIALSOURCE
, D3DMCS_COLOR1
);
4169 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SPECULARMATERIALSOURCE
, D3DMCS_COLOR2
);
4170 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_AMBIENTMATERIALSOURCE
, D3DMCS_COLOR2
);
4171 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_EMISSIVEMATERIALSOURCE
, D3DMCS_MATERIAL
);
4172 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_VERTEXBLEND
, D3DVBF_DISABLE
);
4173 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_CLIPPLANEENABLE
, 0);
4174 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_SOFTWAREVERTEXPROCESSING
, FALSE
);
4175 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSIZE
, 1.0f
);
4176 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSIZE_MIN
, 0.0f
);
4177 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSPRITEENABLE
, FALSE
);
4178 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALEENABLE
, FALSE
);
4179 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALE_A
, TRUE
);
4180 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALE_B
, TRUE
);
4181 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSCALE_C
, TRUE
);
4182 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_MULTISAMPLEANTIALIAS
, TRUE
);
4183 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_MULTISAMPLEMASK
, 0xFFFFFFFF);
4184 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_PATCHEDGESTYLE
, D3DPATCHEDGE_DISCRETE
);
4185 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_PATCHSEGMENTS
, 1.0f
);
4186 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_DEBUGMONITORTOKEN
, D3DDMT_DISABLE
);
4187 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POINTSIZE_MAX
, (DWORD
) 64.0f
);
4188 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_INDEXEDVERTEXBLENDENABLE
, FALSE
);
4189 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_COLORWRITEENABLE
, 0x0000000F);
4190 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_TWEENFACTOR
, (DWORD
) 0.0f
);
4191 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_BLENDOP
, D3DBLENDOP_ADD
);
4192 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_POSITIONORDER
, D3DORDER_CUBIC
);
4193 IDirect3DDevice8Impl_SetRenderState(iface
, D3DRS_NORMALORDER
, D3DORDER_LINEAR
);
4195 /* Texture Stage States - Put directly into state block, we will call function below */
4196 for (i
=0; i
<This
->TextureUnits
;i
++) {
4197 memcpy(&This
->StateBlock
.transforms
[D3DTS_TEXTURE0
+i
], &idmatrix
, sizeof(idmatrix
));
4198 This
->StateBlock
.texture_state
[i
][D3DTSS_COLOROP
] = (i
==0)? D3DTOP_MODULATE
: D3DTOP_DISABLE
;
4199 This
->StateBlock
.texture_state
[i
][D3DTSS_COLORARG1
] = D3DTA_TEXTURE
;
4200 This
->StateBlock
.texture_state
[i
][D3DTSS_COLORARG2
] = D3DTA_CURRENT
;
4201 This
->StateBlock
.texture_state
[i
][D3DTSS_ALPHAOP
] = (i
==0)? D3DTOP_SELECTARG1
: D3DTOP_DISABLE
;
4202 This
->StateBlock
.texture_state
[i
][D3DTSS_ALPHAARG1
] = D3DTA_TEXTURE
;
4203 This
->StateBlock
.texture_state
[i
][D3DTSS_ALPHAARG2
] = D3DTA_CURRENT
;
4204 This
->StateBlock
.texture_state
[i
][D3DTSS_BUMPENVMAT00
] = (DWORD
) 0.0;
4205 This
->StateBlock
.texture_state
[i
][D3DTSS_BUMPENVMAT01
] = (DWORD
) 0.0;
4206 This
->StateBlock
.texture_state
[i
][D3DTSS_BUMPENVMAT10
] = (DWORD
) 0.0;
4207 This
->StateBlock
.texture_state
[i
][D3DTSS_BUMPENVMAT11
] = (DWORD
) 0.0;
4208 /* FIXME: This->StateBlock.texture_state[i][D3DTSS_TEXCOORDINDEX ] = ?; */
4209 This
->StateBlock
.texture_state
[i
][D3DTSS_ADDRESSU
] = D3DTADDRESS_WRAP
;
4210 This
->StateBlock
.texture_state
[i
][D3DTSS_ADDRESSV
] = D3DTADDRESS_WRAP
;
4211 This
->StateBlock
.texture_state
[i
][D3DTSS_BORDERCOLOR
] = 0x00;
4212 This
->StateBlock
.texture_state
[i
][D3DTSS_MAGFILTER
] = D3DTEXF_POINT
;
4213 This
->StateBlock
.texture_state
[i
][D3DTSS_MINFILTER
] = D3DTEXF_POINT
;
4214 This
->StateBlock
.texture_state
[i
][D3DTSS_MIPFILTER
] = D3DTEXF_NONE
;
4215 This
->StateBlock
.texture_state
[i
][D3DTSS_MIPMAPLODBIAS
] = 0;
4216 This
->StateBlock
.texture_state
[i
][D3DTSS_MAXMIPLEVEL
] = 0;
4217 This
->StateBlock
.texture_state
[i
][D3DTSS_MAXANISOTROPY
] = 1;
4218 This
->StateBlock
.texture_state
[i
][D3DTSS_BUMPENVLSCALE
] = (DWORD
) 0.0;
4219 This
->StateBlock
.texture_state
[i
][D3DTSS_BUMPENVLOFFSET
] = (DWORD
) 0.0;
4220 This
->StateBlock
.texture_state
[i
][D3DTSS_TEXTURETRANSFORMFLAGS
] = D3DTTFF_DISABLE
;
4221 This
->StateBlock
.texture_state
[i
][D3DTSS_ADDRESSW
] = D3DTADDRESS_WRAP
;
4222 This
->StateBlock
.texture_state
[i
][D3DTSS_COLORARG0
] = D3DTA_CURRENT
;
4223 This
->StateBlock
.texture_state
[i
][D3DTSS_ALPHAARG0
] = D3DTA_CURRENT
;
4224 This
->StateBlock
.texture_state
[i
][D3DTSS_RESULTARG
] = D3DTA_CURRENT
;
4227 /* Under DirectX you can have texture stage operations even if no texture is
4228 bound, whereas opengl will only do texture operations when a valid texture is
4229 bound. We emulate this by creating dummy textures and binding them to each
4230 texture stage, but disable all stages by default. Hence if a stage is enabled
4231 then the default texture will kick in until replaced by a SetTexture call */
4233 for (i
=0; i
<This
->TextureUnits
; i
++) {
4234 GLubyte white
= 255;
4236 /* Note this avoids calling settexture, so pretend it has been called */
4237 This
->StateBlock
.Set
.textures
[i
] = TRUE
;
4238 This
->StateBlock
.Changed
.textures
[i
] = TRUE
;
4239 This
->StateBlock
.textures
[i
] = NULL
;
4241 /* Make appropriate texture active */
4242 if (This
->isMultiTexture
) {
4243 glActiveTextureARB(GL_TEXTURE0_ARB
+ i
);
4244 checkGLcall("glActiveTextureARB");
4246 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
4249 /* Generate an opengl texture name */
4250 glGenTextures(1, &This
->dummyTextureName
[i
]);
4251 checkGLcall("glGenTextures");
4252 TRACE("Dummy Texture %d given name %d\n", i
, This
->dummyTextureName
[i
]);
4254 /* Generate a dummy 1d texture */
4255 This
->StateBlock
.textureDimensions
[i
] = GL_TEXTURE_1D
;
4256 glBindTexture(GL_TEXTURE_1D
, This
->dummyTextureName
[i
]);
4257 checkGLcall("glBindTexture");
4259 glTexImage1D(GL_TEXTURE_1D
, 0, GL_LUMINANCE
, 1, 0, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, &white
);
4260 checkGLcall("glTexImage1D");
4262 /* Reapply all the texture state information to this texture */
4263 setupTextureStates(iface
, i
);
4266 TRACE("-----------------------> Device defaults now set up...\n");
4271 DWORD SavedPixelStates_R
[NUM_SAVEDPIXELSTATES_R
] = {
4272 D3DRS_ALPHABLENDENABLE
,
4275 D3DRS_ALPHATESTENABLE
,
4277 D3DRS_COLORWRITEENABLE
,
4279 D3DRS_DITHERENABLE
,
4280 D3DRS_EDGEANTIALIAS
,
4289 D3DRS_STENCILENABLE
,
4295 D3DRS_STENCILWRITEMASK
,
4296 D3DRS_STENCILZFAIL
,
4297 D3DRS_TEXTUREFACTOR
,
4312 DWORD SavedPixelStates_T
[NUM_SAVEDPIXELSTATES_T
] = {
4320 D3DTSS_BORDERCOLOR
,
4321 D3DTSS_BUMPENVLOFFSET
,
4322 D3DTSS_BUMPENVLSCALE
,
4323 D3DTSS_BUMPENVMAT00
,
4324 D3DTSS_BUMPENVMAT01
,
4325 D3DTSS_BUMPENVMAT10
,
4326 D3DTSS_BUMPENVMAT11
,
4332 D3DTSS_MAXANISOTROPY
,
4333 D3DTSS_MAXMIPLEVEL
,
4336 D3DTSS_MIPMAPLODBIAS
,
4338 D3DTSS_TEXCOORDINDEX
,
4339 D3DTSS_TEXTURETRANSFORMFLAGS
4342 DWORD SavedVertexStates_R
[NUM_SAVEDVERTEXSTATES_R
] = {
4344 D3DRS_AMBIENTMATERIALSOURCE
,
4346 D3DRS_CLIPPLANEENABLE
,
4348 D3DRS_DIFFUSEMATERIALSOURCE
,
4349 D3DRS_EMISSIVEMATERIALSOURCE
,
4353 D3DRS_FOGTABLEMODE
,
4354 D3DRS_FOGVERTEXMODE
,
4355 D3DRS_INDEXEDVERTEXBLENDENABLE
,
4358 D3DRS_MULTISAMPLEANTIALIAS
,
4359 D3DRS_MULTISAMPLEMASK
,
4360 D3DRS_NORMALIZENORMALS
,
4361 D3DRS_PATCHEDGESTYLE
,
4362 D3DRS_PATCHSEGMENTS
,
4363 D3DRS_POINTSCALE_A
,
4364 D3DRS_POINTSCALE_B
,
4365 D3DRS_POINTSCALE_C
,
4366 D3DRS_POINTSCALEENABLE
,
4368 D3DRS_POINTSIZE_MAX
,
4369 D3DRS_POINTSIZE_MIN
,
4370 D3DRS_POINTSPRITEENABLE
,
4371 D3DRS_RANGEFOGENABLE
,
4372 D3DRS_SOFTWAREVERTEXPROCESSING
,
4373 D3DRS_SPECULARMATERIALSOURCE
,
4378 DWORD SavedVertexStates_T
[NUM_SAVEDVERTEXSTATES_T
] = {
4379 D3DTSS_TEXCOORDINDEX
,
4380 D3DTSS_TEXTURETRANSFORMFLAGS