2 * IDirect3DDevice8 implementation
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2004 Christian Costa
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
33 #include "wine/debug.h"
35 /** define GL_GLEXT_PROTOTYPES for having extensions prototypes defined */
36 /*#define GL_GLEXT_PROTOTYPES*/
37 /*#undef GLX_GLXEXT_LEGACY*/
38 #include "d3d8_private.h"
40 /** currently desactiving 1_4 support as mesa doesn't implement all 1_4 support while defining it */
43 /* Uncomment the next line to get extra traces, important but impact speed */
44 /* #define EXTRA_TRACES */
46 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
47 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader
);
48 WINE_DECLARE_DEBUG_CHANNEL(d3d_fps
);
50 IDirect3DVertexShaderImpl
* VertexShaders
[64];
51 IDirect3DVertexShaderDeclarationImpl
* VertexShaderDeclarations
[64];
52 IDirect3DPixelShaderImpl
* PixelShaders
[64];
55 #ifdef FRAME_DEBUGGING
57 BOOL isDumpingFrames
= FALSE
;
62 * Utility functions or macros
64 #define conv_mat(mat,gl_mat) \
66 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
67 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
68 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
69 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
70 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
73 /* Apply the current values to the specified texture stage */
74 void setupTextureStates(LPDIRECT3DDEVICE8 iface
, DWORD Stage
, DWORD Flags
) {
75 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
78 BOOL changeTexture
= TRUE
;
80 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage
);
81 for (i
= 1; i
< HIGHEST_TEXTURE_STATE
; i
++) {
86 /* Performance: For texture states where multiples effect the outcome, only bother
87 applying the last one as it will pick up all the other values */
88 case D3DTSS_COLORARG0
: /* Will be picked up when setting color op */
89 case D3DTSS_COLORARG1
: /* Will be picked up when setting color op */
90 case D3DTSS_COLORARG2
: /* Will be picked up when setting color op */
91 case D3DTSS_ALPHAARG0
: /* Will be picked up when setting alpha op */
92 case D3DTSS_ALPHAARG1
: /* Will be picked up when setting alpha op */
93 case D3DTSS_ALPHAARG2
: /* Will be picked up when setting alpha op */
97 /* Performance: If the texture states only impact settings for the texture unit
98 (compared to the texture object) then there is no need to reapply them. The
99 only time they need applying is the first time, since we cheat and put the
100 values into the stateblock without applying.
101 Per-texture unit: texture function (eg. combine), ops and args
103 texture generation settings
104 Note: Due to some special conditions there may be a need to do particular ones
105 of these, which is what the Flags allows */
107 case D3DTSS_TEXCOORDINDEX
:
108 if (!(Flags
== REAPPLY_ALL
)) skip
=TRUE
;
112 if (!(Flags
& REAPPLY_ALPHAOP
)) skip
=TRUE
;
120 /* Performance: Only change to this texture if we have to */
122 /* Make appropriate texture active */
123 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
124 #if defined(GL_VERSION_1_3)
125 glActiveTexture(GL_TEXTURE0
+ Stage
);
126 checkGLcall("glActiveTexture");
128 glActiveTextureARB(GL_TEXTURE0_ARB
+ Stage
);
129 checkGLcall("glActiveTextureARB");
131 } else if (Stage
> 0) {
132 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
134 changeTexture
= FALSE
;
137 /* Now apply the change */
138 IDirect3DDevice8Impl_SetTextureStageState(iface
, Stage
, i
, This
->StateBlock
->texture_state
[Stage
][i
]);
142 /* Note the D3DRS value applies to all textures, but GL has one
143 * per texture, so apply it now ready to be used!
145 D3DCOLORTOGLFLOAT4(This
->StateBlock
->renderstate
[D3DRS_TEXTUREFACTOR
], col
);
146 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, &col
[0]);
147 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
149 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage
);
152 /* Convert the D3DLIGHT8 properties into equivalent gl lights */
153 static void setup_light(LPDIRECT3DDEVICE8 iface
, LONG Index
, PLIGHTINFOEL
*lightInfo
) {
156 float colRGBA
[] = {0.0, 0.0, 0.0, 0.0};
157 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
159 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
160 glMatrixMode(GL_MODELVIEW
);
162 glLoadMatrixf((float *) &This
->StateBlock
->transforms
[D3DTS_VIEW
].u
.m
[0][0]);
165 colRGBA
[0] = lightInfo
->OriginalParms
.Diffuse
.r
;
166 colRGBA
[1] = lightInfo
->OriginalParms
.Diffuse
.g
;
167 colRGBA
[2] = lightInfo
->OriginalParms
.Diffuse
.b
;
168 colRGBA
[3] = lightInfo
->OriginalParms
.Diffuse
.a
;
169 glLightfv(GL_LIGHT0
+Index
, GL_DIFFUSE
, colRGBA
);
170 checkGLcall("glLightfv");
173 colRGBA
[0] = lightInfo
->OriginalParms
.Specular
.r
;
174 colRGBA
[1] = lightInfo
->OriginalParms
.Specular
.g
;
175 colRGBA
[2] = lightInfo
->OriginalParms
.Specular
.b
;
176 colRGBA
[3] = lightInfo
->OriginalParms
.Specular
.a
;
177 glLightfv(GL_LIGHT0
+Index
, GL_SPECULAR
, colRGBA
);
178 checkGLcall("glLightfv");
181 colRGBA
[0] = lightInfo
->OriginalParms
.Ambient
.r
;
182 colRGBA
[1] = lightInfo
->OriginalParms
.Ambient
.g
;
183 colRGBA
[2] = lightInfo
->OriginalParms
.Ambient
.b
;
184 colRGBA
[3] = lightInfo
->OriginalParms
.Ambient
.a
;
185 glLightfv(GL_LIGHT0
+Index
, GL_AMBIENT
, colRGBA
);
186 checkGLcall("glLightfv");
188 /* Attenuation - Are these right? guessing... */
189 glLightf(GL_LIGHT0
+Index
, GL_CONSTANT_ATTENUATION
, lightInfo
->OriginalParms
.Attenuation0
);
190 checkGLcall("glLightf");
191 glLightf(GL_LIGHT0
+Index
, GL_LINEAR_ATTENUATION
, lightInfo
->OriginalParms
.Attenuation1
);
192 checkGLcall("glLightf");
194 quad_att
= 1.4/(lightInfo
->OriginalParms
.Range
*lightInfo
->OriginalParms
.Range
);
195 if (quad_att
< lightInfo
->OriginalParms
.Attenuation2
) quad_att
= lightInfo
->OriginalParms
.Attenuation2
;
196 glLightf(GL_LIGHT0
+Index
, GL_QUADRATIC_ATTENUATION
, quad_att
);
197 checkGLcall("glLightf");
199 switch (lightInfo
->OriginalParms
.Type
) {
202 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &lightInfo
->lightPosn
[0]);
203 checkGLcall("glLightfv");
204 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_CUTOFF
, lightInfo
->cutoff
);
205 checkGLcall("glLightf");
211 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &lightInfo
->lightPosn
[0]);
212 checkGLcall("glLightfv");
214 glLightfv(GL_LIGHT0
+Index
, GL_SPOT_DIRECTION
, &lightInfo
->lightDirn
[0]);
215 checkGLcall("glLightfv");
216 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_EXPONENT
, lightInfo
->exponent
);
217 checkGLcall("glLightf");
218 glLightf(GL_LIGHT0
+ Index
, GL_SPOT_CUTOFF
, lightInfo
->cutoff
);
219 checkGLcall("glLightf");
223 case D3DLIGHT_DIRECTIONAL
:
225 glLightfv(GL_LIGHT0
+Index
, GL_POSITION
, &lightInfo
->lightPosn
[0]); /* Note gl uses w position of 0 for direction! */
226 checkGLcall("glLightfv");
227 glLightf(GL_LIGHT0
+Index
, GL_SPOT_CUTOFF
, lightInfo
->cutoff
);
228 checkGLcall("glLightf");
229 glLightf(GL_LIGHT0
+Index
, GL_SPOT_EXPONENT
, 0.0f
);
230 checkGLcall("glLightf");
234 FIXME("Unrecognized light type %d\n", lightInfo
->OriginalParms
.Type
);
237 /* Restore the modelview matrix */
241 /* Setup this textures matrix */
242 static void set_texture_matrix(const float *smat
, DWORD flags
)
246 glMatrixMode(GL_TEXTURE
);
248 if (flags
== D3DTTFF_DISABLE
) {
250 checkGLcall("glLoadIdentity()");
254 if (flags
== (D3DTTFF_COUNT1
|D3DTTFF_PROJECTED
)) {
255 ERR("Invalid texture transform flags: D3DTTFF_COUNT1|D3DTTFF_PROJECTED\n");
256 checkGLcall("glLoadIdentity()");
260 memcpy(mat
, smat
, 16*sizeof(float));
262 switch (flags
& ~D3DTTFF_PROJECTED
) {
263 case D3DTTFF_COUNT1
: mat
[1] = mat
[5] = mat
[9] = mat
[13] = 0;
264 case D3DTTFF_COUNT2
: mat
[2] = mat
[6] = mat
[10] = mat
[14] = 0;
265 default: mat
[3] = mat
[7] = mat
[11] = 0, mat
[15] = 1;
268 if (flags
& D3DTTFF_PROJECTED
) switch (flags
& ~D3DTTFF_PROJECTED
) {
270 mat
[3] = mat
[1], mat
[7] = mat
[5], mat
[11] = mat
[9], mat
[15] = mat
[13];
271 mat
[1] = mat
[5] = mat
[9] = mat
[13] = 0;
274 mat
[3] = mat
[2], mat
[7] = mat
[6], mat
[11] = mat
[10], mat
[15] = mat
[14];
275 mat
[2] = mat
[6] = mat
[10] = mat
[14] = 0;
279 checkGLcall("glLoadMatrixf(mat)");
282 /* IDirect3D IUnknown parts follow: */
283 HRESULT WINAPI
IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface
,REFIID riid
,LPVOID
*ppobj
)
285 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
287 if (IsEqualGUID(riid
, &IID_IUnknown
)
288 || IsEqualGUID(riid
, &IID_IDirect3DDevice8
)) {
289 IDirect3DDevice8Impl_AddRef(iface
);
294 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppobj
);
295 return E_NOINTERFACE
;
298 ULONG WINAPI
IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface
) {
299 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
300 ULONG ref
= InterlockedIncrement(&This
->ref
);
302 TRACE("(%p) : AddRef from %ld\n", This
, ref
- 1);
307 ULONG WINAPI
IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface
) {
308 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
309 ULONG ref
= InterlockedDecrement(&This
->ref
);
311 TRACE("(%p) : ReleaseRef to %ld\n", This
, ref
);
314 IDirect3DDevice8Impl_CleanRender(iface
);
315 IDirect3D8_Release((LPDIRECT3D8
) This
->direct3d8
);
316 IWineD3DDevice_Release(This
->WineD3DDevice
);
318 if (glXGetCurrentContext() == This
->glCtx
) {
319 glXMakeCurrent(This
->display
, None
, NULL
);
321 glXDestroyContext(This
->display
, This
->glCtx
);
323 HeapFree(GetProcessHeap(), 0, This
);
328 /* IDirect3DDevice Interface follow: */
329 HRESULT WINAPI
IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface
) {
330 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
331 TRACE("(%p) : stub\n", This
); /* No way of notifying yet! */
335 UINT WINAPI
IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface
) {
336 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
337 TRACE("(%p) : stub, emulating 32Mb for now\n", This
);
339 * pretend we have 32MB of any type of memory queried.
341 return (1024*1024*32);
344 HRESULT WINAPI
IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface
, DWORD Bytes
) {
345 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
346 FIXME("(%p) : stub\n", This
);
349 HRESULT WINAPI
IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface
, IDirect3D8
** ppD3D8
) {
350 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
351 TRACE("(%p) : returning %p\n", This
, This
->direct3d8
);
354 IDirect3D8_AddRef((LPDIRECT3D8
) This
->direct3d8
);
356 *ppD3D8
= (IDirect3D8
*)This
->direct3d8
;
359 HRESULT WINAPI
IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface
, D3DCAPS8
* pCaps
) {
360 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
361 FIXME("(%p) : stub, calling idirect3d for now\n", This
);
362 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8
) This
->direct3d8
, This
->adapterNo
, This
->devType
, pCaps
);
365 HRESULT WINAPI
IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface
, D3DDISPLAYMODE
* pMode
) {
370 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
371 pMode
->Width
= GetSystemMetrics(SM_CXSCREEN
);
372 pMode
->Height
= GetSystemMetrics(SM_CYSCREEN
);
373 pMode
->RefreshRate
= 85; /*FIXME: How to identify? */
375 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
376 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
380 case 8: pMode
->Format
= D3DFMT_R8G8B8
; break;
381 case 16: pMode
->Format
= D3DFMT_R5G6B5
; break;
382 case 24: /*pMode->Format = D3DFMT_R8G8B8; break; */
383 case 32: pMode
->Format
= D3DFMT_A8R8G8B8
; break;
385 FIXME("Unrecognized display mode format\n");
386 pMode
->Format
= D3DFMT_UNKNOWN
;
389 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This
, pMode
->Width
, pMode
->Height
, pMode
->RefreshRate
,
390 pMode
->Format
, debug_d3dformat(pMode
->Format
));
393 HRESULT WINAPI
IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface
, D3DDEVICE_CREATION_PARAMETERS
*pParameters
) {
394 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
395 TRACE("(%p) copying to %p\n", This
, pParameters
);
396 memcpy(pParameters
, &This
->CreateParms
, sizeof(D3DDEVICE_CREATION_PARAMETERS
));
399 HRESULT WINAPI
IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface
, UINT XHotSpot
, UINT YHotSpot
, IDirect3DSurface8
* pCursorBitmap
) {
400 IDirect3DSurface8Impl
* pSur
= (IDirect3DSurface8Impl
*) pCursorBitmap
;
401 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
402 TRACE("(%p) : Spot Pos(%u,%u)\n", This
, XHotSpot
, YHotSpot
);
404 if (D3DFMT_A8R8G8B8
!= pSur
->myDesc
.Format
) {
405 ERR("(%p) : surface(%p) has an invalid format\n", This
, pCursorBitmap
);
406 return D3DERR_INVALIDCALL
;
408 if (32 != pSur
->myDesc
.Height
|| 32 != pSur
->myDesc
.Width
) {
409 ERR("(%p) : surface(%p) has an invalid size\n", This
, pCursorBitmap
);
410 return D3DERR_INVALIDCALL
;
413 This
->xHotSpot
= XHotSpot
;
414 This
->yHotSpot
= YHotSpot
;
417 void WINAPI
IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface
, UINT XScreenSpace
, UINT YScreenSpace
, DWORD Flags
) {
418 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
419 TRACE("(%p) : SetPos to (%u,%u)\n", This
, XScreenSpace
, YScreenSpace
);
420 This
->xScreenSpace
= XScreenSpace
;
421 This
->yScreenSpace
= YScreenSpace
;
424 BOOL WINAPI
IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface
, BOOL bShow
) {
425 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
426 TRACE("(%p) : visible(%d)\n", This
, bShow
);
427 This
->bCursorVisible
= bShow
;
430 HRESULT WINAPI
IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
, IDirect3DSwapChain8
** pSwapChain
) {
431 IDirect3DSwapChain8Impl
* object
;
432 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
433 FIXME("(%p) : stub\n", This
);
435 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DDevice8Impl
));
436 if (NULL
== object
) {
437 return D3DERR_OUTOFVIDEOMEMORY
;
439 object
->lpVtbl
= &Direct3DSwapChain8_Vtbl
;
442 TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This
,
443 pPresentationParameters
->AutoDepthStencilFormat
, debug_d3dformat(pPresentationParameters
->AutoDepthStencilFormat
),
444 pPresentationParameters
->BackBufferFormat
, debug_d3dformat(pPresentationParameters
->BackBufferFormat
));
446 if (pPresentationParameters
->Windowed
&& ((pPresentationParameters
->BackBufferWidth
== 0) ||
447 (pPresentationParameters
->BackBufferHeight
== 0))) {
450 GetClientRect(This
->win_handle
, &Rect
);
452 if (pPresentationParameters
->BackBufferWidth
== 0) {
453 pPresentationParameters
->BackBufferWidth
= Rect
.right
;
454 TRACE("Updating width to %d\n", pPresentationParameters
->BackBufferWidth
);
456 if (pPresentationParameters
->BackBufferHeight
== 0) {
457 pPresentationParameters
->BackBufferHeight
= Rect
.bottom
;
458 TRACE("Updating height to %d\n", pPresentationParameters
->BackBufferHeight
);
462 /* Save the presentation parms now filled in correctly */
463 memcpy(&object
->PresentParms
, pPresentationParameters
, sizeof(D3DPRESENT_PARAMETERS
));
465 IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8
) object
,
466 pPresentationParameters
->BackBufferWidth
,
467 pPresentationParameters
->BackBufferHeight
,
468 pPresentationParameters
->BackBufferFormat
,
469 pPresentationParameters
->MultiSampleType
,
471 (LPDIRECT3DSURFACE8
*) &object
->frontBuffer
);
473 IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8
) object
,
474 pPresentationParameters
->BackBufferWidth
,
475 pPresentationParameters
->BackBufferHeight
,
476 pPresentationParameters
->BackBufferFormat
,
477 pPresentationParameters
->MultiSampleType
,
479 (LPDIRECT3DSURFACE8
*) &object
->backBuffer
);
481 if (pPresentationParameters
->EnableAutoDepthStencil
) {
482 IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8
) object
,
483 pPresentationParameters
->BackBufferWidth
,
484 pPresentationParameters
->BackBufferHeight
,
485 pPresentationParameters
->AutoDepthStencilFormat
,
487 (LPDIRECT3DSURFACE8
*) &object
->depthStencilBuffer
);
489 object
->depthStencilBuffer
= NULL
;
492 *pSwapChain
= (IDirect3DSwapChain8
*) object
;
495 HRESULT WINAPI
IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
) {
496 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
497 FIXME("(%p) : stub\n", This
);
500 HRESULT WINAPI
IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface
,
501 CONST RECT
* pSourceRect
, CONST RECT
* pDestRect
,
502 HWND hDestWindowOverride
, CONST RGNDATA
* pDirtyRegion
) {
503 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
504 TRACE("(%p) : complete stub!\n", This
);
508 if (pSourceRect
|| pDestRect
) FIXME("Unhandled present options %p/%p\n", pSourceRect
, pDestRect
);
511 glXSwapBuffers(This
->display
, This
->drawable
);
512 /* Don't call checkGLcall, as glGetError is not applicable here */
513 TRACE("glXSwapBuffers called, Starting new frame\n");
516 if (TRACE_ON(d3d_fps
))
518 static long prev_time
, frames
;
520 DWORD time
= GetTickCount();
522 /* every 1.5 seconds */
523 if (time
- prev_time
> 1500) {
524 TRACE_(d3d_fps
)("@ approx %.2ffps\n", 1000.0*frames
/(time
- prev_time
));
530 #if defined(FRAME_DEBUGGING)
532 if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES
) {
535 FIXME("Enabling D3D Trace\n");
536 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE
, __wine_dbch_d3d
, 1);
537 #if defined(SHOW_FRAME_MAKEUP)
538 FIXME("Singe Frame snapshots Starting\n");
539 isDumpingFrames
= TRUE
;
540 glClear(GL_COLOR_BUFFER_BIT
);
543 #if defined(SINGLE_FRAME_DEBUGGING)
545 #if defined(SHOW_FRAME_MAKEUP)
546 FIXME("Singe Frame snapshots Finishing\n");
547 isDumpingFrames
= FALSE
;
549 FIXME("Singe Frame trace complete\n");
550 DeleteFileA("C:\\D3DTRACE");
551 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE
, __wine_dbch_d3d
, 0);
557 #if defined(SHOW_FRAME_MAKEUP)
558 FIXME("Singe Frame snapshots Finishing\n");
559 isDumpingFrames
= FALSE
;
561 FIXME("Disabling D3D Trace\n");
562 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE
, __wine_dbch_d3d
, 0);
569 /* Although this is not strictly required, a simple demo showed this does occur
570 on (at least non-debug) d3d */
571 if (This
->PresentParms
.SwapEffect
== D3DSWAPEFFECT_DISCARD
) {
572 IDirect3DDevice8Impl_Clear(iface
, 0, NULL
, D3DCLEAR_STENCIL
|D3DCLEAR_ZBUFFER
|D3DCLEAR_TARGET
, 0x00, 1.0, 0);
577 HRESULT WINAPI
IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface
, UINT BackBuffer
, D3DBACKBUFFER_TYPE Type
, IDirect3DSurface8
** ppBackBuffer
) {
578 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
579 *ppBackBuffer
= (LPDIRECT3DSURFACE8
) This
->backBuffer
;
580 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This
, BackBuffer
, Type
, *ppBackBuffer
);
582 if (BackBuffer
> This
->PresentParms
.BackBufferCount
- 1) {
583 FIXME("Only one backBuffer currently supported\n");
584 return D3DERR_INVALIDCALL
;
587 /* Note inc ref on returned surface */
588 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) *ppBackBuffer
);
592 HRESULT WINAPI
IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface
, D3DRASTER_STATUS
* pRasterStatus
) {
593 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
594 FIXME("(%p) : stub\n", This
);
597 void WINAPI
IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface
, DWORD Flags
, CONST D3DGAMMARAMP
* pRamp
) {
599 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
601 FIXME("(%p) : pRamp@%p\n", This
, pRamp
);
602 hDC
= GetDC(This
->win_handle
);
603 SetDeviceGammaRamp(hDC
, (LPVOID
) pRamp
);
604 ReleaseDC(This
->win_handle
, hDC
);
607 void WINAPI
IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface
, D3DGAMMARAMP
* pRamp
) {
609 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
611 FIXME("(%p) : pRamp@%p\n", This
, pRamp
);
612 hDC
= GetDC(This
->win_handle
);
613 GetDeviceGammaRamp(hDC
, pRamp
);
614 ReleaseDC(This
->win_handle
, hDC
);
617 HRESULT WINAPI
IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface
, UINT Width
, UINT Height
, UINT Levels
, DWORD Usage
,
618 D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DTexture8
** ppTexture
) {
619 IDirect3DTexture8Impl
*object
;
624 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
626 /* Allocate the storage for the device */
627 TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%d)\n", This
, Width
, Height
, Levels
, Usage
, Format
, debug_d3dformat(Format
), Pool
);
628 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DTexture8Impl
));
629 object
->lpVtbl
= &Direct3DTexture8_Vtbl
;
630 object
->Device
= This
;
631 object
->ResourceType
= D3DRTYPE_TEXTURE
;
633 object
->width
= Width
;
634 object
->height
= Height
;
635 object
->levels
= Levels
;
636 object
->usage
= Usage
;
637 object
->format
= Format
;
639 /* Calculate levels for mip mapping */
644 while (tmpW
> 1 && tmpH
> 1) {
645 tmpW
= max(1, tmpW
/ 2);
646 tmpH
= max(1, tmpH
/ 2);
649 TRACE("Calculated levels = %d\n", object
->levels
);
652 /* Generate all the surfaces */
655 for (i
= 0; i
< object
->levels
; i
++)
657 IDirect3DDevice8Impl_CreateImageSurface(iface
, tmpW
, tmpH
, Format
, (LPDIRECT3DSURFACE8
*) &object
->surfaces
[i
]);
658 object
->surfaces
[i
]->Container
= (IUnknown
*) object
;
659 object
->surfaces
[i
]->myDesc
.Usage
= Usage
;
660 object
->surfaces
[i
]->myDesc
.Pool
= Pool
;
662 * As written in msdn in IDirect3DTexture8::LockRect
663 * Textures created in D3DPOOL_DEFAULT are not lockable.
665 if (D3DPOOL_DEFAULT
== Pool
) {
666 object
->surfaces
[i
]->lockable
= FALSE
;
669 TRACE("Created surface level %d @ %p, memory at %p\n", i
, object
->surfaces
[i
], object
->surfaces
[i
]->allocatedMemory
);
670 tmpW
= max(1, tmpW
/ 2);
671 tmpH
= max(1, tmpH
/ 2);
674 *ppTexture
= (LPDIRECT3DTEXTURE8
) object
;
675 TRACE("(%p) : Created texture %p\n", This
, object
);
678 HRESULT WINAPI
IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface
,
679 UINT Width
, UINT Height
, UINT Depth
, UINT Levels
, DWORD Usage
,
680 D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DVolumeTexture8
** ppVolumeTexture
) {
682 IDirect3DVolumeTexture8Impl
*object
;
688 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
690 /* Allocate the storage for it */
691 TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%s)\n", This
, Width
, Height
, Depth
, Levels
, Usage
, Format
, debug_d3dformat(Format
), debug_d3dpool(Pool
));
692 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVolumeTexture8Impl
));
693 object
->lpVtbl
= &Direct3DVolumeTexture8_Vtbl
;
694 object
->ResourceType
= D3DRTYPE_VOLUMETEXTURE
;
695 object
->Device
= This
;
698 object
->width
= Width
;
699 object
->height
= Height
;
700 object
->depth
= Depth
;
701 object
->levels
= Levels
;
702 object
->usage
= Usage
;
703 object
->format
= Format
;
705 /* Calculate levels for mip mapping */
711 while (tmpW
> 1 && tmpH
> 1 && tmpD
> 1) {
712 tmpW
= max(1, tmpW
/ 2);
713 tmpH
= max(1, tmpH
/ 2);
714 tmpD
= max(1, tmpD
/ 2);
717 TRACE("Calculated levels = %d\n", object
->levels
);
720 /* Generate all the surfaces */
725 for (i
= 0; i
< object
->levels
; i
++)
727 IDirect3DVolume8Impl
* volume
;
729 /* Create the volume - No entry point for this seperately?? */
730 volume
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVolume8Impl
));
731 object
->volumes
[i
] = (IDirect3DVolume8Impl
*) volume
;
733 volume
->lpVtbl
= &Direct3DVolume8_Vtbl
;
734 volume
->Device
= This
;
735 volume
->ResourceType
= D3DRTYPE_VOLUME
;
736 volume
->Container
= (IUnknown
*) object
;
739 volume
->myDesc
.Width
= Width
;
740 volume
->myDesc
.Height
= Height
;
741 volume
->myDesc
.Depth
= Depth
;
742 volume
->myDesc
.Format
= Format
;
743 volume
->myDesc
.Type
= D3DRTYPE_VOLUME
;
744 volume
->myDesc
.Pool
= Pool
;
745 volume
->myDesc
.Usage
= Usage
;
746 volume
->bytesPerPixel
= D3DFmtGetBpp(This
, Format
);
747 /* Note: Volume textures cannot be dxtn, hence no need to check here */
748 volume
->myDesc
.Size
= (Width
* volume
->bytesPerPixel
) * Height
* Depth
;
749 volume
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, volume
->myDesc
.Size
);
751 volume
->lockable
= TRUE
;
752 volume
->locked
= FALSE
;
753 memset(&volume
->lockedBox
, 0, sizeof(D3DBOX
));
754 volume
->Dirty
= FALSE
;
755 IDirect3DVolume8Impl_CleanDirtyBox((LPDIRECT3DVOLUME8
) volume
);
757 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%u,%s) surf@%p, surfmem@%p, %d bytes\n",
758 This
, Width
, Height
, Depth
, Format
, debug_d3dformat(Format
),
759 volume
, volume
->allocatedMemory
, volume
->myDesc
.Size
);
761 tmpW
= max(1, tmpW
/ 2);
762 tmpH
= max(1, tmpH
/ 2);
763 tmpD
= max(1, tmpD
/ 2);
766 *ppVolumeTexture
= (LPDIRECT3DVOLUMETEXTURE8
) object
;
767 TRACE("(%p) : Created volume texture %p\n", This
, object
);
770 HRESULT WINAPI
IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface
, UINT EdgeLength
, UINT Levels
, DWORD Usage
,
771 D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DCubeTexture8
** ppCubeTexture
) {
773 IDirect3DCubeTexture8Impl
*object
;
774 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
778 /* Allocate the storage for it */
779 TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%s)\n", This
, EdgeLength
, Levels
, Usage
, Format
, debug_d3dformat(Format
), debug_d3dpool(Pool
));
780 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DCubeTexture8Impl
));
781 object
->lpVtbl
= &Direct3DCubeTexture8_Vtbl
;
783 object
->Device
= This
;
784 object
->ResourceType
= D3DRTYPE_CUBETEXTURE
;
786 object
->edgeLength
= EdgeLength
;
787 object
->levels
= Levels
;
788 object
->usage
= Usage
;
789 object
->format
= Format
;
791 /* Calculate levels for mip mapping */
796 tmpW
= max(1, tmpW
/ 2);
799 TRACE("Calculated levels = %d\n", object
->levels
);
802 /* Generate all the surfaces */
804 for (i
= 0; i
< object
->levels
; i
++) {
805 /* Create the 6 faces */
806 for (j
= 0; j
< 6; j
++) {
807 IDirect3DDevice8Impl_CreateImageSurface(iface
, tmpW
, tmpW
, Format
, (LPDIRECT3DSURFACE8
*) &object
->surfaces
[j
][i
]);
808 object
->surfaces
[j
][i
]->Container
= (IUnknown
*) object
;
809 object
->surfaces
[j
][i
]->myDesc
.Usage
= Usage
;
810 object
->surfaces
[j
][i
]->myDesc
.Pool
= Pool
;
812 * As written in msdn in IDirect3DCubeTexture8::LockRect
813 * Textures created in D3DPOOL_DEFAULT are not lockable.
815 if (D3DPOOL_DEFAULT
== Pool
) {
816 object
->surfaces
[j
][i
]->lockable
= FALSE
;
819 TRACE("Created surface level %d @ %p, memory at %p\n", i
, object
->surfaces
[j
][i
], object
->surfaces
[j
][i
]->allocatedMemory
);
821 tmpW
= max(1, tmpW
/ 2);
824 TRACE("(%p) : Iface@%p\n", This
, object
);
825 *ppCubeTexture
= (LPDIRECT3DCUBETEXTURE8
) object
;
828 HRESULT WINAPI
IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface
, UINT Size
, DWORD Usage
, DWORD FVF
, D3DPOOL Pool
, IDirect3DVertexBuffer8
** ppVertexBuffer
) {
829 IDirect3DVertexBuffer8Impl
*object
;
831 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
833 /* Allocate the storage for the device */
834 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVertexBuffer8Impl
));
835 object
->lpVtbl
= &Direct3DVertexBuffer8_Vtbl
;
836 object
->Device
= This
;
837 object
->ResourceType
= D3DRTYPE_VERTEXBUFFER
;
839 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, Size
);
840 object
->currentDesc
.Usage
= Usage
;
841 object
->currentDesc
.Pool
= Pool
;
842 object
->currentDesc
.FVF
= FVF
;
843 object
->currentDesc
.Size
= Size
;
845 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This
, Size
, Usage
, FVF
, Pool
, object
->allocatedMemory
, object
);
847 *ppVertexBuffer
= (LPDIRECT3DVERTEXBUFFER8
) object
;
851 HRESULT WINAPI
IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface
, UINT Length
, DWORD Usage
, D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DIndexBuffer8
** ppIndexBuffer
) {
852 IDirect3DIndexBuffer8Impl
*object
;
854 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
855 TRACE("(%p) : Len=%d, Use=%lx, Format=(%u,%s), Pool=%d\n", This
, Length
, Usage
, Format
, debug_d3dformat(Format
), Pool
);
857 /* Allocate the storage for the device */
858 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DIndexBuffer8Impl
));
859 object
->lpVtbl
= &Direct3DIndexBuffer8_Vtbl
;
860 object
->Device
= This
;
862 object
->ResourceType
= D3DRTYPE_INDEXBUFFER
;
864 object
->currentDesc
.Type
= D3DRTYPE_INDEXBUFFER
;
865 object
->currentDesc
.Usage
= Usage
;
866 object
->currentDesc
.Pool
= Pool
;
867 object
->currentDesc
.Format
= Format
;
868 object
->currentDesc
.Size
= Length
;
870 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, Length
);
872 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This
, object
, object
->allocatedMemory
);
874 *ppIndexBuffer
= (LPDIRECT3DINDEXBUFFER8
) object
;
878 HRESULT WINAPI
IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface
, UINT Width
, UINT Height
, D3DFORMAT Format
, D3DMULTISAMPLE_TYPE MultiSample
, BOOL Lockable
, IDirect3DSurface8
** ppSurface
) {
879 IDirect3DSurface8Impl
*object
;
880 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
882 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DSurface8Impl
));
883 if (NULL
== object
) {
885 return D3DERR_OUTOFVIDEOMEMORY
;
887 *ppSurface
= (LPDIRECT3DSURFACE8
) object
;
888 object
->lpVtbl
= &Direct3DSurface8_Vtbl
;
889 object
->Device
= This
;
890 object
->ResourceType
= D3DRTYPE_SURFACE
;
891 object
->Container
= (IUnknown
*) This
;
894 object
->myDesc
.Width
= Width
;
895 object
->myDesc
.Height
= Height
;
896 object
->myDesc
.Format
= Format
;
897 object
->myDesc
.Type
= D3DRTYPE_SURFACE
;
898 object
->myDesc
.Usage
= D3DUSAGE_RENDERTARGET
;
899 object
->myDesc
.Pool
= D3DPOOL_DEFAULT
;
900 object
->myDesc
.MultiSampleType
= MultiSample
;
901 object
->bytesPerPixel
= D3DFmtGetBpp(This
, Format
);
902 if (Format
== D3DFMT_DXT1
) {
903 object
->myDesc
.Size
= (Width
* object
->bytesPerPixel
)/2 * Height
; /* DXT1 is half byte per pixel */
905 object
->myDesc
.Size
= (Width
* object
->bytesPerPixel
) * Height
;
907 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->myDesc
.Size
);
908 object
->lockable
= Lockable
;
909 object
->locked
= FALSE
;
910 memset(&object
->lockedRect
, 0, sizeof(RECT
));
911 IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8
) object
);
913 TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n", This
, Width
, Height
, Format
, debug_d3dformat(Format
), Lockable
, *ppSurface
, object
->allocatedMemory
, object
->myDesc
.Size
);
916 HRESULT WINAPI
IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface
, UINT Width
, UINT Height
, D3DFORMAT Format
, D3DMULTISAMPLE_TYPE MultiSample
, IDirect3DSurface8
** ppSurface
) {
917 IDirect3DSurface8Impl
*object
;
919 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
921 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DSurface8Impl
));
922 if (NULL
== object
) {
924 return D3DERR_OUTOFVIDEOMEMORY
;
926 *ppSurface
= (LPDIRECT3DSURFACE8
) object
;
927 object
->lpVtbl
= &Direct3DSurface8_Vtbl
;
928 object
->Device
= This
;
929 object
->ResourceType
= D3DRTYPE_SURFACE
;
930 object
->Container
= (IUnknown
*) This
;
933 object
->myDesc
.Width
= Width
;
934 object
->myDesc
.Height
= Height
;
935 object
->myDesc
.Format
= Format
;
936 object
->myDesc
.Type
= D3DRTYPE_SURFACE
;
937 object
->myDesc
.Usage
= D3DUSAGE_DEPTHSTENCIL
;
938 object
->myDesc
.Pool
= D3DPOOL_DEFAULT
;
939 object
->myDesc
.MultiSampleType
= MultiSample
;
940 object
->bytesPerPixel
= D3DFmtGetBpp(This
, Format
);
941 if (Format
== D3DFMT_DXT1
) {
942 object
->myDesc
.Size
= (Width
* object
->bytesPerPixel
)/2 * Height
; /* DXT1 is half byte per pixel */
944 object
->myDesc
.Size
= (Width
* object
->bytesPerPixel
) * Height
;
946 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->myDesc
.Size
);
947 object
->lockable
= (D3DFMT_D16_LOCKABLE
== Format
) ? TRUE
: FALSE
;
948 object
->locked
= FALSE
;
949 memset(&object
->lockedRect
, 0, sizeof(RECT
));
950 IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8
) object
);
952 TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This
, Width
, Height
, Format
, debug_d3dformat(Format
), *ppSurface
, object
->allocatedMemory
, object
->myDesc
.Size
);
955 HRESULT WINAPI
IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface
, UINT Width
, UINT Height
, D3DFORMAT Format
, IDirect3DSurface8
** ppSurface
) {
956 IDirect3DSurface8Impl
*object
;
958 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
960 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DSurface8Impl
));
961 *ppSurface
= (LPDIRECT3DSURFACE8
) object
;
962 object
->lpVtbl
= &Direct3DSurface8_Vtbl
;
963 object
->Device
= This
;
964 object
->ResourceType
= D3DRTYPE_SURFACE
;
965 object
->Container
= (IUnknown
*) This
;
968 object
->myDesc
.Width
= Width
;
969 object
->myDesc
.Height
= Height
;
970 object
->myDesc
.Format
= Format
;
971 object
->myDesc
.Type
= D3DRTYPE_SURFACE
;
972 object
->myDesc
.Usage
= 0;
973 object
->myDesc
.Pool
= D3DPOOL_SYSTEMMEM
;
974 object
->bytesPerPixel
= D3DFmtGetBpp(This
, Format
);
975 /* DXTn mipmaps use the same number of 'levels' down to eg. 8x1, but since
976 it is based around 4x4 pixel blocks it requires padding, so allocate enough
978 if (Format
== D3DFMT_DXT1
) {
979 object
->myDesc
.Size
= ((max(Width
,4) * object
->bytesPerPixel
) * max(Height
,4)) / 2; /* DXT1 is half byte per pixel */
980 } else if (Format
== D3DFMT_DXT2
|| Format
== D3DFMT_DXT3
||
981 Format
== D3DFMT_DXT4
|| Format
== D3DFMT_DXT5
) {
982 object
->myDesc
.Size
= ((max(Width
,4) * object
->bytesPerPixel
) * max(Height
,4));
984 object
->myDesc
.Size
= (Width
* object
->bytesPerPixel
) * Height
;
986 object
->allocatedMemory
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->myDesc
.Size
);
987 object
->lockable
= TRUE
;
988 object
->locked
= FALSE
;
989 memset(&object
->lockedRect
, 0, sizeof(RECT
));
990 IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8
) object
);
992 TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This
, Width
, Height
, Format
, debug_d3dformat(Format
), *ppSurface
, object
->allocatedMemory
, object
->myDesc
.Size
);
995 HRESULT WINAPI
IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface
,
996 IDirect3DSurface8
* pSourceSurface
, CONST RECT
* pSourceRectsArray
, UINT cRects
,
997 IDirect3DSurface8
* pDestinationSurface
, CONST POINT
* pDestPointsArray
) {
1000 IDirect3DBaseTexture8
* texture
= NULL
;
1003 IDirect3DSurface8Impl
* src
= (IDirect3DSurface8Impl
*) pSourceSurface
;
1004 IDirect3DSurface8Impl
* dst
= (IDirect3DSurface8Impl
*) pDestinationSurface
;
1006 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1007 TRACE("(%p) pSrcSur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This
,
1008 pSourceSurface
, pSourceRectsArray
, cRects
, pDestinationSurface
, pDestPointsArray
);
1010 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
1011 a sample and doesn't seem to break anything as far as I can tell */
1012 if (src
->myDesc
.Format
!= dst
->myDesc
.Format
&& (dst
->myDesc
.Format
!= D3DFMT_UNKNOWN
)) {
1013 TRACE("Formats do not match (%x,%s) / (%x,%s)\n",
1014 src
->myDesc
.Format
, debug_d3dformat(src
->myDesc
.Format
),
1015 dst
->myDesc
.Format
, debug_d3dformat(dst
->myDesc
.Format
));
1016 rc
= D3DERR_INVALIDCALL
;
1018 } else if (dst
->myDesc
.Format
== D3DFMT_UNKNOWN
) {
1019 TRACE("Converting dest to same format as source, since dest was unknown\n");
1020 dst
->myDesc
.Format
= src
->myDesc
.Format
;
1022 /* Convert container as well */
1023 rc
= IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8
) dst
, &IID_IDirect3DBaseTexture8
, (void**) &texture
); /* FIXME: Which refid? */
1024 if (SUCCEEDED(rc
) && NULL
!= texture
) {
1025 ((IDirect3DBaseTexture8Impl
*) texture
)->format
= src
->myDesc
.Format
;
1026 /** Releasing texture after GetContainer */
1027 IDirect3DBaseTexture8_Release(texture
);
1032 /* Quick if complete copy ... */
1033 if (SUCCEEDED(rc
)) {
1034 if (cRects
== 0 && pSourceRectsArray
== NULL
&& pDestPointsArray
== NULL
) {
1036 if (src
->myDesc
.Width
== dst
->myDesc
.Width
&& src
->myDesc
.Height
== dst
->myDesc
.Height
) {
1038 D3DLOCKED_RECT lrSrc
;
1039 D3DLOCKED_RECT lrDst
;
1040 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8
) src
, &lrSrc
, NULL
, D3DLOCK_READONLY
);
1041 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8
) dst
, &lrDst
, NULL
, 0L);
1042 TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", dst
->myDesc
.Width
, dst
->myDesc
.Height
);
1044 memcpy(lrDst
.pBits
, lrSrc
.pBits
, src
->myDesc
.Size
);
1046 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8
) src
);
1047 rc
= IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8
) dst
);
1048 TRACE("Unlocked src and dst\n");
1052 FIXME("Wanted to copy all surfaces but size not compatible\n");
1053 rc
= D3DERR_INVALIDCALL
;
1059 if (NULL
!= pSourceRectsArray
&& NULL
!= pDestPointsArray
) {
1061 int bytesPerPixel
= ((IDirect3DSurface8Impl
*) pSourceSurface
)->bytesPerPixel
;
1064 /* Copy rect by rect */
1065 for (i
= 0; i
< cRects
; i
++) {
1066 CONST RECT
* r
= &pSourceRectsArray
[i
];
1067 CONST POINT
* p
= &pDestPointsArray
[i
];
1070 D3DLOCKED_RECT lrSrc
;
1071 D3DLOCKED_RECT lrDst
;
1074 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i
, r
->left
, r
->top
, r
->right
, r
->bottom
, p
->x
, p
->y
);
1075 if (src
->myDesc
.Format
== D3DFMT_DXT1
) {
1076 copyperline
= ((r
->right
- r
->left
) * bytesPerPixel
)/2; /* DXT1 is half byte per pixel */
1078 copyperline
= ((r
->right
- r
->left
) * bytesPerPixel
);
1080 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8
) src
, &lrSrc
, r
, D3DLOCK_READONLY
);
1081 dest_rect
.left
= p
->x
;
1082 dest_rect
.top
= p
->y
;
1083 dest_rect
.right
= p
->x
+ (r
->right
- r
->left
);
1084 dest_rect
.bottom
= p
->y
+ (r
->bottom
- r
->top
);
1085 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8
) dst
, &lrDst
, &dest_rect
, 0L);
1086 TRACE("Locked src and dst\n");
1088 /* Find where to start */
1089 for (j
= 0; j
< (r
->bottom
- r
->top
- 1); j
++) {
1090 memcpy((char*) lrDst
.pBits
+ (j
* lrDst
.Pitch
), (char*) lrSrc
.pBits
+ (j
* lrSrc
.Pitch
), copyperline
);
1092 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8
) src
);
1093 rc
= IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8
) dst
);
1094 TRACE("Unlocked src and dst\n");
1097 FIXME("Wanted to copy partial surfaces not implemented\n");
1098 rc
= D3DERR_INVALIDCALL
;
1105 HRESULT WINAPI
IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface
, IDirect3DBaseTexture8
* pSourceTexture
, IDirect3DBaseTexture8
* pDestinationTexture
) {
1106 IDirect3DBaseTexture8Impl
* src
= (IDirect3DBaseTexture8Impl
*) pSourceTexture
;
1107 IDirect3DBaseTexture8Impl
* dst
= (IDirect3DBaseTexture8Impl
*) pDestinationTexture
;
1108 D3DRESOURCETYPE srcType
;
1109 D3DRESOURCETYPE dstType
;
1111 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1112 TRACE("(%p) : first try\n", This
);
1114 srcType
= IDirect3DBaseTexture8Impl_GetType(pSourceTexture
);
1115 dstType
= IDirect3DBaseTexture8Impl_GetType(pDestinationTexture
);
1117 if (srcType
!= dstType
) {
1118 return D3DERR_INVALIDCALL
;
1120 if (D3DPOOL_SYSTEMMEM
!= IDirect3DResource8Impl_GetPool((LPDIRECT3DRESOURCE8
) src
)) {
1121 return D3DERR_INVALIDCALL
;
1123 if (D3DPOOL_DEFAULT
!= IDirect3DResource8Impl_GetPool((LPDIRECT3DRESOURCE8
) dst
)) {
1124 return D3DERR_INVALIDCALL
;
1126 if (IDirect3DBaseTexture8Impl_IsDirty(pSourceTexture
)) {
1127 /** Only copy Dirty textures */
1128 DWORD srcLevelCnt
= IDirect3DBaseTexture8Impl_GetLevelCount(pSourceTexture
);
1129 DWORD dstLevelCnt
= IDirect3DBaseTexture8Impl_GetLevelCount(pDestinationTexture
);
1130 DWORD skipLevels
= (dstLevelCnt
< srcLevelCnt
) ? srcLevelCnt
- dstLevelCnt
: 0;
1133 for (i
= skipLevels
; i
< srcLevelCnt
; ++i
) {
1137 case D3DRTYPE_TEXTURE
:
1139 IDirect3DSurface8
* srcSur
= NULL
;
1140 IDirect3DSurface8
* dstSur
= NULL
;
1141 hr
= IDirect3DTexture8Impl_GetSurfaceLevel((LPDIRECT3DTEXTURE8
) src
, i
, &srcSur
);
1142 hr
= IDirect3DTexture8Impl_GetSurfaceLevel((LPDIRECT3DTEXTURE8
) dst
, i
- skipLevels
, &dstSur
);
1144 /* Fixme: Work out how to just do the dirty regions (src or dst dirty region, and what
1145 about dst with less levels than the source?) */
1146 IDirect3DDevice8Impl_CopyRects(iface
, srcSur
, NULL
, 0, dstSur
, NULL
);
1148 IDirect3DSurface8Impl_Release(srcSur
);
1149 IDirect3DSurface8Impl_Release(dstSur
);
1152 case D3DRTYPE_VOLUMETEXTURE
:
1154 FIXME("D3DRTYPE_VOLUMETEXTURE reload currently not implemented\n");
1157 case D3DRTYPE_CUBETEXTURE
:
1159 IDirect3DSurface8
* srcSur
= NULL
;
1160 IDirect3DSurface8
* dstSur
= NULL
;
1161 for (j
= 0; j
< 5; ++j
) {
1162 hr
= IDirect3DCubeTexture8Impl_GetCubeMapSurface((LPDIRECT3DCUBETEXTURE8
) src
, j
, i
, &srcSur
);
1163 hr
= IDirect3DCubeTexture8Impl_GetCubeMapSurface((LPDIRECT3DCUBETEXTURE8
) dst
, j
, i
- skipLevels
, &dstSur
);
1165 IDirect3DDevice8Impl_CopyRects(iface
, srcSur
, NULL
, 0, dstSur
, NULL
);
1167 IDirect3DSurface8Impl_Release(srcSur
);
1168 IDirect3DSurface8Impl_Release(dstSur
);
1176 IDirect3DBaseTexture8Impl_SetDirty(pSourceTexture
, FALSE
);
1181 HRESULT WINAPI
IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
* pDestSurface
) {
1183 D3DLOCKED_RECT lockedRect
;
1188 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1190 FIXME("(%p) : Should return whole screen, only returns GL context window in top left corner\n", This
);
1192 if (D3DFMT_A8R8G8B8
!= ((IDirect3DSurface8Impl
*) pDestSurface
)->myDesc
.Format
) {
1193 ERR("(%p) : surface(%p) has an invalid format\n", This
, pDestSurface
);
1194 return D3DERR_INVALIDCALL
;
1197 wantedRect
.left
= 0;
1199 wantedRect
.right
= This
->PresentParms
.BackBufferWidth
;
1200 wantedRect
.bottom
= This
->PresentParms
.BackBufferHeight
;
1202 hr
= IDirect3DSurface8Impl_LockRect(pDestSurface
, &lockedRect
, &wantedRect
, 0);
1204 ERR("(%p) : cannot lock surface\n", This
);
1205 return D3DERR_INVALIDCALL
;
1211 vcheckGLcall("glFlush");
1212 glGetIntegerv(GL_READ_BUFFER
, &prev_read
);
1213 vcheckGLcall("glIntegerv");
1214 glGetIntegerv(GL_PACK_SWAP_BYTES
, &prev_store
);
1215 vcheckGLcall("glIntegerv");
1217 glReadBuffer(GL_FRONT
);
1218 vcheckGLcall("glReadBuffer");
1219 glPixelStorei(GL_PACK_SWAP_BYTES
, TRUE
);
1220 vcheckGLcall("glPixelStorei");
1224 for (j
= 0; j
< This
->PresentParms
.BackBufferHeight
; ++j
) {
1225 glReadPixels(0, This
->PresentParms
.BackBufferHeight
- j
- 1, This
->PresentParms
.BackBufferWidth
, 1,
1226 GL_BGRA
, GL_UNSIGNED_BYTE
, ((char*) lockedRect
.pBits
) + (j
* lockedRect
.Pitch
));
1227 vcheckGLcall("glReadPixels");
1230 glPixelStorei(GL_PACK_SWAP_BYTES
, prev_store
);
1231 vcheckGLcall("glPixelStorei");
1232 glReadBuffer(prev_read
);
1233 vcheckGLcall("glReadBuffer");
1237 hr
= IDirect3DSurface8Impl_UnlockRect(pDestSurface
);
1240 HRESULT WINAPI
IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
* pRenderTarget
, IDirect3DSurface8
* pNewZStencil
) {
1241 HRESULT hr
= D3D_OK
;
1242 D3DVIEWPORT8 viewport
;
1244 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1246 /* If pRenderTarget == NULL, it seems to default to back buffer */
1247 if (pRenderTarget
== NULL
) pRenderTarget
= (IDirect3DSurface8
*)This
->backBuffer
;
1249 /* For ease of code later on, handle a null depth as leave alone
1250 - Have not tested real d3d for this case but doing this avoids
1251 numerous null pointer checks */
1252 if (pNewZStencil
== NULL
) pNewZStencil
= (IDirect3DSurface8
*)This
->stencilBufferTarget
;
1254 /* If we are trying to set what we already have, don't bother */
1255 if ((IDirect3DSurface8Impl
*) pRenderTarget
== This
->renderTarget
&& (IDirect3DSurface8Impl
*) pNewZStencil
== This
->stencilBufferTarget
) {
1256 TRACE("Trying to do a NOP SetRenderTarget operation\n");
1258 /* Otherwise, set the render target up */
1259 TRACE("(%p) : newRender@%p newZStencil@%p (default is backbuffer=(%p))\n", This
, pRenderTarget
, pNewZStencil
, This
->backBuffer
);
1260 IDirect3DDevice8Impl_CleanRender(iface
);
1261 hr
= IDirect3DDevice8Impl_ActiveRender(iface
, pRenderTarget
, pNewZStencil
);
1264 if (SUCCEEDED(hr
)) {
1265 /* Finally, reset the viewport as the MSDN states. */
1266 viewport
.Height
= ((IDirect3DSurface8Impl
*)pRenderTarget
)->myDesc
.Height
;
1267 viewport
.Width
= ((IDirect3DSurface8Impl
*)pRenderTarget
)->myDesc
.Width
;
1270 viewport
.MaxZ
= 1.0f
;
1271 viewport
.MinZ
= 0.0f
;
1272 IDirect3DDevice8Impl_SetViewport(iface
, &viewport
);
1278 HRESULT WINAPI
IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
** ppRenderTarget
) {
1279 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1281 TRACE("(%p)->returning (%p) default is backbuffer=(%p)\n", This
, This
->renderTarget
, This
->backBuffer
);
1283 *ppRenderTarget
= (LPDIRECT3DSURFACE8
) This
->renderTarget
;
1284 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) *ppRenderTarget
);
1289 HRESULT WINAPI
IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface
, IDirect3DSurface8
** ppZStencilSurface
) {
1290 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1292 TRACE("(%p)->(%p) default(%p)\n", This
, This
->stencilBufferTarget
, This
->depthStencilBuffer
);
1294 /* Note inc ref on returned surface */
1295 *ppZStencilSurface
= (LPDIRECT3DSURFACE8
) This
->stencilBufferTarget
;
1296 if (NULL
!= *ppZStencilSurface
) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) *ppZStencilSurface
);
1301 HRESULT WINAPI
IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface
) {
1302 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1303 return IWineD3DDevice_BeginScene(This
->WineD3DDevice
);
1306 HRESULT WINAPI
IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface
) {
1307 IDirect3DBaseTexture8
* cont
= NULL
;
1309 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1310 TRACE("(%p)\n", This
);
1315 checkGLcall("glFlush");
1317 #if 0 /* Useful for debugging sometimes! */
1318 printf("Hit Enter ...\n");
1322 if ((This
->frontBuffer
!= This
->renderTarget
) && (This
->backBuffer
!= This
->renderTarget
)) {
1325 glGetIntegerv(GL_READ_BUFFER
, &prev_read
);
1326 vcheckGLcall("glIntegerv");
1327 glReadBuffer(GL_FRONT
);
1328 vcheckGLcall("glReadBuffer");
1331 long pitch
= This
->renderTarget
->myDesc
.Width
* This
->renderTarget
->bytesPerPixel
;
1333 if (This
->renderTarget
->myDesc
.Format
== D3DFMT_DXT1
) /* DXT1 is half byte per pixel */
1336 for (j
= 0; j
< This
->renderTarget
->myDesc
.Height
; ++j
) {
1338 This
->renderTarget
->myDesc
.Height
- j
- 1,
1339 This
->renderTarget
->myDesc
.Width
,
1341 D3DFmt2GLFmt(This
, This
->renderTarget
->myDesc
.Format
),
1342 D3DFmt2GLType(This
, This
->renderTarget
->myDesc
.Format
),
1343 This
->renderTarget
->allocatedMemory
+ j
* pitch
);
1344 vcheckGLcall("glReadPixels");
1347 glReadBuffer(prev_read
);
1348 vcheckGLcall("glReadBuffer");
1351 hr
= IDirect3DSurface8_GetContainer((LPDIRECT3DSURFACE8
) This
->renderTarget
, &IID_IDirect3DBaseTexture8
, (void**) &cont
);
1352 if (SUCCEEDED(hr
) && NULL
!= cont
) {
1353 /** always dirtify for now. we must find a better way to see that surface have been modified */
1354 This
->renderTarget
->inPBuffer
= TRUE
;
1355 This
->renderTarget
->inTexture
= FALSE
;
1356 IDirect3DBaseTexture8Impl_SetDirty(cont
, TRUE
);
1357 IDirect3DBaseTexture8_PreLoad(cont
);
1358 This
->renderTarget
->inPBuffer
= FALSE
;
1359 IDirect3DBaseTexture8Impl_Release(cont
);
1367 HRESULT WINAPI
IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface
, DWORD Count
, CONST D3DRECT
* pRects
, DWORD Flags
, D3DCOLOR Color
, float Z
, DWORD Stencil
) {
1368 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1370 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1371 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1372 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1373 GLbitfield glMask
= 0;
1374 GLboolean old_ztest
;
1375 GLfloat old_z_clear_value
;
1376 GLint old_stencil_clear_value
;
1377 GLfloat old_color_clear_value
[4];
1379 CONST D3DRECT
* curRect
;
1381 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This
,
1382 Count
, pRects
, Flags
, Z
, Stencil
);
1385 glEnable(GL_SCISSOR_TEST
);
1386 checkGLcall("glEnable GL_SCISSOR_TEST");
1387 if (Count
> 0 && pRects
) {
1393 /* Only set the values up once, as they are not changing */
1394 if (Flags
& D3DCLEAR_STENCIL
) {
1395 glGetIntegerv(GL_STENCIL_CLEAR_VALUE
, &old_stencil_clear_value
);
1396 glClearStencil(Stencil
);
1397 checkGLcall("glClearStencil");
1398 glMask
= glMask
| GL_STENCIL_BUFFER_BIT
;
1399 glStencilMask(0xFFFFFFFF);
1402 if (Flags
& D3DCLEAR_ZBUFFER
) {
1403 glGetBooleanv(GL_DEPTH_WRITEMASK
, &old_ztest
);
1404 glDepthMask(GL_TRUE
);
1405 glGetFloatv(GL_DEPTH_CLEAR_VALUE
, &old_z_clear_value
);
1407 checkGLcall("glClearDepth");
1408 glMask
= glMask
| GL_DEPTH_BUFFER_BIT
;
1411 if (Flags
& D3DCLEAR_TARGET
) {
1412 TRACE("Clearing screen with glClear to color %lx\n", Color
);
1413 glGetFloatv(GL_COLOR_CLEAR_VALUE
, old_color_clear_value
);
1414 glClearColor(D3DCOLOR_R(Color
),
1418 checkGLcall("glClearColor");
1420 /* Clear ALL colors! */
1421 glColorMask(GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
1422 glMask
= glMask
| GL_COLOR_BUFFER_BIT
;
1425 /* Now process each rect in turn */
1426 for (i
= 0; i
< Count
|| i
== 0; i
++) {
1429 /* Note gl uses lower left, width/height */
1430 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This
, curRect
,
1431 curRect
->x1
, curRect
->y1
, curRect
->x2
, curRect
->y2
,
1432 curRect
->x1
, (This
->renderTarget
->myDesc
.Height
- curRect
->y2
),
1433 curRect
->x2
- curRect
->x1
, curRect
->y2
- curRect
->y1
);
1434 glScissor(curRect
->x1
, (This
->renderTarget
->myDesc
.Height
- curRect
->y2
),
1435 curRect
->x2
- curRect
->x1
, curRect
->y2
- curRect
->y1
);
1436 checkGLcall("glScissor");
1438 glScissor(This
->StateBlock
->viewport
.X
,
1439 (This
->renderTarget
->myDesc
.Height
- (This
->StateBlock
->viewport
.Y
+ This
->StateBlock
->viewport
.Height
)),
1440 This
->StateBlock
->viewport
.Width
,
1441 This
->StateBlock
->viewport
.Height
);
1442 checkGLcall("glScissor");
1445 /* Clear the selected rectangle (or full screen) */
1447 checkGLcall("glClear");
1449 /* Step to the next rectangle */
1450 if (curRect
) curRect
= curRect
+ sizeof(D3DRECT
);
1453 /* Restore the old values (why..?) */
1454 if (Flags
& D3DCLEAR_STENCIL
) {
1455 glClearStencil(old_stencil_clear_value
);
1456 glStencilMask(This
->StateBlock
->renderstate
[D3DRS_STENCILWRITEMASK
]);
1458 if (Flags
& D3DCLEAR_ZBUFFER
) {
1459 glDepthMask(old_ztest
);
1460 glClearDepth(old_z_clear_value
);
1462 if (Flags
& D3DCLEAR_TARGET
) {
1463 glClearColor(old_color_clear_value
[0],
1464 old_color_clear_value
[1],
1465 old_color_clear_value
[2],
1466 old_color_clear_value
[3]);
1467 glColorMask(This
->StateBlock
->renderstate
[D3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_RED
? GL_TRUE
: GL_FALSE
,
1468 This
->StateBlock
->renderstate
[D3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_GREEN
? GL_TRUE
: GL_FALSE
,
1469 This
->StateBlock
->renderstate
[D3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_BLUE
? GL_TRUE
: GL_FALSE
,
1470 This
->StateBlock
->renderstate
[D3DRS_COLORWRITEENABLE
] & D3DCOLORWRITEENABLE_ALPHA
? GL_TRUE
: GL_FALSE
);
1473 glDisable(GL_SCISSOR_TEST
);
1474 checkGLcall("glDisable");
1479 HRESULT WINAPI
IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface
, D3DTRANSFORMSTATETYPE d3dts
, CONST D3DMATRIX
* lpmatrix
) {
1480 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1483 /* Most of this routine, comments included copied from ddraw tree initially: */
1484 TRACE("(%p) : State=%d\n", This
, d3dts
);
1486 /* Handle recording of state blocks */
1487 if (This
->isRecordingState
) {
1488 TRACE("Recording... not performing anything\n");
1489 This
->UpdateStateBlock
->Changed
.transform
[d3dts
] = TRUE
;
1490 This
->UpdateStateBlock
->Set
.transform
[d3dts
] = TRUE
;
1491 memcpy(&This
->UpdateStateBlock
->transforms
[d3dts
], lpmatrix
, sizeof(D3DMATRIX
));
1496 * if the new matrix is the same as the current one,
1497 * we cut off any further processing. this seems to be a reasonable
1498 * optimization because as was noticed, some apps (warcraft3 for example)
1499 * tend towards setting the same matrix repeatedly for some dumb reason.
1501 * From here on we assume that the new matrix is different, wherever it matters
1504 if (!memcmp(&This
->StateBlock
->transforms
[d3dts
].u
.m
[0][0], lpmatrix
, sizeof(D3DMATRIX
))) {
1505 TRACE("The app is setting the same matrix over again\n");
1508 conv_mat(lpmatrix
, &This
->StateBlock
->transforms
[d3dts
].u
.m
[0][0]);
1512 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1513 where ViewMat = Camera space, WorldMat = world space.
1515 In OpenGL, camera and world space is combined into GL_MODELVIEW
1516 matrix. The Projection matrix stay projection matrix.
1519 /* Capture the times we can just ignore the change */
1520 if (d3dts
== D3DTS_WORLDMATRIX(0)) {
1521 This
->modelview_valid
= FALSE
;
1524 } else if (d3dts
== D3DTS_PROJECTION
) {
1525 This
->proj_valid
= FALSE
;
1528 } else if (d3dts
>= D3DTS_WORLDMATRIX(1) && d3dts
<= D3DTS_WORLDMATRIX(255)) { /* Indexed Vertex Blending Matrices 256 -> 511 */
1529 /* Use arb_vertex_blend or NV_VERTEX_WEIGHTING? */
1530 FIXME("D3DTS_WORLDMATRIX(1..255) not handled\n");
1534 /* Chances are we really are going to have to change a matrix */
1537 if (d3dts
>= D3DTS_TEXTURE0
&& d3dts
<= D3DTS_TEXTURE7
) { /* handle texture matrices */
1538 if (d3dts
< GL_LIMITS(textures
)) {
1539 int tex
= d3dts
- D3DTS_TEXTURE0
;
1540 #if defined(GL_VERSION_1_3)
1541 glActiveTexture(GL_TEXTURE0
+ tex
);
1542 checkGLcall("glActiveTexture");
1544 glActiveTextureARB(GL_TEXTURE0_ARB
+ tex
);
1545 checkGLcall("glActiveTextureARB");
1547 set_texture_matrix((const float *)lpmatrix
, This
->UpdateStateBlock
->texture_state
[tex
][D3DTSS_TEXTURETRANSFORMFLAGS
]);
1550 } else if (d3dts
== D3DTS_VIEW
) { /* handle the VIEW matrice */
1552 PLIGHTINFOEL
*lightChain
= NULL
;
1553 float identity
[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
1554 This
->modelview_valid
= FALSE
;
1555 This
->view_ident
= !memcmp(lpmatrix
, identity
, 16*sizeof(float));
1556 glMatrixMode(GL_MODELVIEW
);
1557 checkGLcall("glMatrixMode(GL_MODELVIEW)");
1559 glLoadMatrixf((const float *)lpmatrix
);
1560 checkGLcall("glLoadMatrixf(...)");
1562 /* If we are changing the View matrix, reset the light and clipping planes to the new view
1563 * NOTE: We have to reset the positions even if the light/plane is not currently
1564 * enabled, since the call to enable it will not reset the position.
1565 * NOTE2: Apparently texture transforms do NOT need reapplying
1569 lightChain
= This
->StateBlock
->lights
;
1570 while (lightChain
&& lightChain
->glIndex
!= -1) {
1571 glLightfv(GL_LIGHT0
+ lightChain
->glIndex
, GL_POSITION
, lightChain
->lightPosn
);
1572 checkGLcall("glLightfv posn");
1573 glLightfv(GL_LIGHT0
+ lightChain
->glIndex
, GL_SPOT_DIRECTION
, lightChain
->lightDirn
);
1574 checkGLcall("glLightfv dirn");
1575 lightChain
= lightChain
->next
;
1577 /* Reset Clipping Planes if clipping is enabled */
1578 for (k
= 0; k
< GL_LIMITS(clipplanes
); k
++) {
1579 glClipPlane(GL_CLIP_PLANE0
+ k
, This
->StateBlock
->clipplane
[k
]);
1580 checkGLcall("glClipPlane");
1584 } else { /* What was requested!?? */
1585 WARN("invalid matrix specified: %i\n", d3dts
);
1589 /* Release lock, all done */
1594 HRESULT WINAPI
IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface
, D3DTRANSFORMSTATETYPE State
,D3DMATRIX
* pMatrix
) {
1595 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1596 TRACE("(%p) : for State %d\n", This
, State
);
1597 memcpy(pMatrix
, &This
->StateBlock
->transforms
[State
], sizeof(D3DMATRIX
));
1601 HRESULT WINAPI
IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface
, D3DTRANSFORMSTATETYPE State
, CONST D3DMATRIX
* pMatrix
) {
1602 D3DMATRIX
*mat
= NULL
;
1605 /* Note: Using UpdateStateBlock means it would be recorded in a state block change,
1606 but works regardless of recording being on.
1607 If this is found to be wrong, change to StateBlock. */
1608 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1609 TRACE("(%p) : For state %u\n", This
, State
);
1611 if (State
< HIGHEST_TRANSFORMSTATE
)
1613 mat
= &This
->UpdateStateBlock
->transforms
[State
];
1615 FIXME("Unhandled transform state!!\n");
1618 /* Copied from ddraw code: */
1619 temp
.u
.s
._11
= (mat
->u
.s
._11
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._14
);
1620 temp
.u
.s
._21
= (mat
->u
.s
._11
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._24
);
1621 temp
.u
.s
._31
= (mat
->u
.s
._11
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._34
);
1622 temp
.u
.s
._41
= (mat
->u
.s
._11
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._21
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._31
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._41
* pMatrix
->u
.s
._44
);
1624 temp
.u
.s
._12
= (mat
->u
.s
._12
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._14
);
1625 temp
.u
.s
._22
= (mat
->u
.s
._12
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._24
);
1626 temp
.u
.s
._32
= (mat
->u
.s
._12
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._34
);
1627 temp
.u
.s
._42
= (mat
->u
.s
._12
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._22
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._32
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._42
* pMatrix
->u
.s
._44
);
1629 temp
.u
.s
._13
= (mat
->u
.s
._13
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._14
);
1630 temp
.u
.s
._23
= (mat
->u
.s
._13
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._24
);
1631 temp
.u
.s
._33
= (mat
->u
.s
._13
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._34
);
1632 temp
.u
.s
._43
= (mat
->u
.s
._13
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._23
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._33
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._43
* pMatrix
->u
.s
._44
);
1634 temp
.u
.s
._14
= (mat
->u
.s
._14
* pMatrix
->u
.s
._11
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._12
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._13
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._14
);
1635 temp
.u
.s
._24
= (mat
->u
.s
._14
* pMatrix
->u
.s
._21
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._22
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._23
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._24
);
1636 temp
.u
.s
._34
= (mat
->u
.s
._14
* pMatrix
->u
.s
._31
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._32
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._33
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._34
);
1637 temp
.u
.s
._44
= (mat
->u
.s
._14
* pMatrix
->u
.s
._41
) + (mat
->u
.s
._24
* pMatrix
->u
.s
._42
) + (mat
->u
.s
._34
* pMatrix
->u
.s
._43
) + (mat
->u
.s
._44
* pMatrix
->u
.s
._44
);
1639 /* Apply change via set transform - will reapply to eg. lights this way */
1640 IDirect3DDevice8Impl_SetTransform(iface
, State
, &temp
);
1643 HRESULT WINAPI
IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface
, CONST D3DVIEWPORT8
* pViewport
) {
1644 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1646 TRACE("(%p)\n", This
);
1647 This
->UpdateStateBlock
->Changed
.viewport
= TRUE
;
1648 This
->UpdateStateBlock
->Set
.viewport
= TRUE
;
1649 memcpy(&This
->UpdateStateBlock
->viewport
, pViewport
, sizeof(D3DVIEWPORT8
));
1651 /* Handle recording of state blocks */
1652 if (This
->isRecordingState
) {
1653 TRACE("Recording... not performing anything\n");
1659 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This
,
1660 pViewport
->X
, pViewport
->Y
, pViewport
->Width
, pViewport
->Height
, pViewport
->MinZ
, pViewport
->MaxZ
);
1662 glDepthRange(pViewport
->MinZ
, pViewport
->MaxZ
);
1663 checkGLcall("glDepthRange");
1664 /* Note: GL requires lower left, DirectX supplies upper left */
1665 glViewport(pViewport
->X
, (This
->renderTarget
->myDesc
.Height
- (pViewport
->Y
+ pViewport
->Height
)),
1666 pViewport
->Width
, pViewport
->Height
);
1667 checkGLcall("glViewport");
1674 HRESULT WINAPI
IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface
, D3DVIEWPORT8
* pViewport
) {
1675 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1676 TRACE("(%p)\n", This
);
1677 memcpy(pViewport
, &This
->StateBlock
->viewport
, sizeof(D3DVIEWPORT8
));
1681 HRESULT WINAPI
IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface
, CONST D3DMATERIAL8
* pMaterial
) {
1682 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1684 This
->UpdateStateBlock
->Changed
.material
= TRUE
;
1685 This
->UpdateStateBlock
->Set
.material
= TRUE
;
1686 memcpy(&This
->UpdateStateBlock
->material
, pMaterial
, sizeof(D3DMATERIAL8
));
1688 /* Handle recording of state blocks */
1689 if (This
->isRecordingState
) {
1690 TRACE("Recording... not performing anything\n");
1695 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This
, pMaterial
->Diffuse
.r
, pMaterial
->Diffuse
.g
, pMaterial
->Diffuse
.b
, pMaterial
->Diffuse
.a
);
1696 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This
, pMaterial
->Ambient
.r
, pMaterial
->Ambient
.g
, pMaterial
->Ambient
.b
, pMaterial
->Ambient
.a
);
1697 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This
, pMaterial
->Specular
.r
, pMaterial
->Specular
.g
, pMaterial
->Specular
.b
, pMaterial
->Specular
.a
);
1698 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This
, pMaterial
->Emissive
.r
, pMaterial
->Emissive
.g
, pMaterial
->Emissive
.b
, pMaterial
->Emissive
.a
);
1699 TRACE("(%p) : Power (%f)\n", This
, pMaterial
->Power
);
1701 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, (float*) &This
->UpdateStateBlock
->material
.Ambient
);
1702 checkGLcall("glMaterialfv");
1703 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, (float*) &This
->UpdateStateBlock
->material
.Diffuse
);
1704 checkGLcall("glMaterialfv");
1706 /* Only change material color if specular is enabled, otherwise it is set to black */
1707 if (This
->StateBlock
->renderstate
[D3DRS_SPECULARENABLE
]) {
1708 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, (float*) &This
->UpdateStateBlock
->material
.Specular
);
1709 checkGLcall("glMaterialfv");
1711 float black
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
1712 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, &black
[0]);
1713 checkGLcall("glMaterialfv");
1715 glMaterialfv(GL_FRONT_AND_BACK
, GL_EMISSION
, (float*) &This
->UpdateStateBlock
->material
.Emissive
);
1716 checkGLcall("glMaterialfv");
1717 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, This
->UpdateStateBlock
->material
.Power
);
1718 checkGLcall("glMaterialf");
1723 HRESULT WINAPI
IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface
, D3DMATERIAL8
* pMaterial
) {
1724 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1725 memcpy(pMaterial
, &This
->UpdateStateBlock
->material
, sizeof (D3DMATERIAL8
));
1726 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This
, pMaterial
->Diffuse
.r
, pMaterial
->Diffuse
.g
, pMaterial
->Diffuse
.b
, pMaterial
->Diffuse
.a
);
1727 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This
, pMaterial
->Ambient
.r
, pMaterial
->Ambient
.g
, pMaterial
->Ambient
.b
, pMaterial
->Ambient
.a
);
1728 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This
, pMaterial
->Specular
.r
, pMaterial
->Specular
.g
, pMaterial
->Specular
.b
, pMaterial
->Specular
.a
);
1729 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This
, pMaterial
->Emissive
.r
, pMaterial
->Emissive
.g
, pMaterial
->Emissive
.b
, pMaterial
->Emissive
.a
);
1730 TRACE("(%p) : Power (%f)\n", This
, pMaterial
->Power
);
1734 /* Note lights are real special cases. Although the device caps state only eg. 8 are supported,
1735 you can reference any indexes you want as long as that number max are enabled are any
1736 one point in time! Therefore since the indexes can be anything, we need a linked list of them.
1737 However, this causes stateblock problems. When capturing the state block, I duplicate the list,
1738 but when recording, just build a chain pretty much of commands to be replayed. */
1740 HRESULT WINAPI
IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface
, DWORD Index
, CONST D3DLIGHT8
* pLight
) {
1742 PLIGHTINFOEL
*object
, *temp
;
1744 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1745 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This
, Index
, pLight
);
1747 /* If recording state block, just add to end of lights chain */
1748 if (This
->isRecordingState
) {
1749 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PLIGHTINFOEL
));
1750 if (NULL
== object
) {
1751 return D3DERR_OUTOFVIDEOMEMORY
;
1753 memcpy(&object
->OriginalParms
, pLight
, sizeof(D3DLIGHT8
));
1754 object
->OriginalIndex
= Index
;
1755 object
->glIndex
= -1;
1756 object
->changed
= TRUE
;
1758 /* Add to the END of the chain of lights changes to be replayed */
1759 if (This
->UpdateStateBlock
->lights
== NULL
) {
1760 This
->UpdateStateBlock
->lights
= object
;
1762 temp
= This
->UpdateStateBlock
->lights
;
1763 while (temp
->next
!= NULL
) temp
=temp
->next
;
1764 temp
->next
= object
;
1766 TRACE("Recording... not performing anything more\n");
1770 /* Ok, not recording any longer so do real work */
1771 object
= This
->StateBlock
->lights
;
1772 while (object
!= NULL
&& object
->OriginalIndex
!= Index
) object
= object
->next
;
1774 /* If we didn't find it in the list of lights, time to add it */
1775 if (object
== NULL
) {
1776 PLIGHTINFOEL
*insertAt
,*prevPos
;
1778 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PLIGHTINFOEL
));
1779 if (NULL
== object
) {
1780 return D3DERR_OUTOFVIDEOMEMORY
;
1782 object
->OriginalIndex
= Index
;
1783 object
->glIndex
= -1;
1785 /* Add it to the front of list with the idea that lights will be changed as needed
1786 BUT after any lights currently assigned GL indexes */
1787 insertAt
= This
->StateBlock
->lights
;
1789 while (insertAt
!= NULL
&& insertAt
->glIndex
!= -1) {
1791 insertAt
= insertAt
->next
;
1794 if (insertAt
== NULL
&& prevPos
== NULL
) { /* Start of list */
1795 This
->StateBlock
->lights
= object
;
1796 } else if (insertAt
== NULL
) { /* End of list */
1797 prevPos
->next
= object
;
1798 object
->prev
= prevPos
;
1799 } else { /* Middle of chain */
1800 if (prevPos
== NULL
) {
1801 This
->StateBlock
->lights
= object
;
1803 prevPos
->next
= object
;
1805 object
->prev
= prevPos
;
1806 object
->next
= insertAt
;
1807 insertAt
->prev
= object
;
1811 /* Initialze the object */
1812 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
,
1813 pLight
->Diffuse
.r
, pLight
->Diffuse
.g
, pLight
->Diffuse
.b
, pLight
->Diffuse
.a
,
1814 pLight
->Specular
.r
, pLight
->Specular
.g
, pLight
->Specular
.b
, pLight
->Specular
.a
,
1815 pLight
->Ambient
.r
, pLight
->Ambient
.g
, pLight
->Ambient
.b
, pLight
->Ambient
.a
);
1816 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight
->Position
.x
, pLight
->Position
.y
, pLight
->Position
.z
,
1817 pLight
->Direction
.x
, pLight
->Direction
.y
, pLight
->Direction
.z
);
1818 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight
->Range
, pLight
->Falloff
, pLight
->Theta
, pLight
->Phi
);
1820 /* Save away the information */
1821 memcpy(&object
->OriginalParms
, pLight
, sizeof(D3DLIGHT8
));
1823 switch (pLight
->Type
) {
1824 case D3DLIGHT_POINT
:
1826 object
->lightPosn
[0] = pLight
->Position
.x
;
1827 object
->lightPosn
[1] = pLight
->Position
.y
;
1828 object
->lightPosn
[2] = pLight
->Position
.z
;
1829 object
->lightPosn
[3] = 1.0f
;
1830 object
->cutoff
= 180.0f
;
1834 case D3DLIGHT_DIRECTIONAL
:
1836 object
->lightPosn
[0] = -pLight
->Direction
.x
;
1837 object
->lightPosn
[1] = -pLight
->Direction
.y
;
1838 object
->lightPosn
[2] = -pLight
->Direction
.z
;
1839 object
->lightPosn
[3] = 0.0;
1840 object
->exponent
= 0.0f
;
1841 object
->cutoff
= 180.0f
;
1846 object
->lightPosn
[0] = pLight
->Position
.x
;
1847 object
->lightPosn
[1] = pLight
->Position
.y
;
1848 object
->lightPosn
[2] = pLight
->Position
.z
;
1849 object
->lightPosn
[3] = 1.0;
1852 object
->lightDirn
[0] = pLight
->Direction
.x
;
1853 object
->lightDirn
[1] = pLight
->Direction
.y
;
1854 object
->lightDirn
[2] = pLight
->Direction
.z
;
1855 object
->lightDirn
[3] = 1.0;
1858 * opengl-ish and d3d-ish spot lights use too different models for the
1859 * light "intensity" as a function of the angle towards the main light direction,
1860 * so we only can approximate very roughly.
1861 * however spot lights are rather rarely used in games (if ever used at all).
1862 * furthermore if still used, probably nobody pays attention to such details.
1864 if (pLight
->Falloff
== 0) {
1867 rho
= pLight
->Theta
+ (pLight
->Phi
- pLight
->Theta
)/(2*pLight
->Falloff
);
1869 if (rho
< 0.0001) rho
= 0.0001f
;
1870 object
->exponent
= -0.3/log(cos(rho
/2));
1871 object
->cutoff
= pLight
->Phi
*90/M_PI
;
1877 FIXME("Unrecognized light type %d\n", pLight
->Type
);
1880 /* Update the live definitions if the light is currently assigned a glIndex */
1881 if (object
->glIndex
!= -1) {
1882 setup_light(iface
, object
->glIndex
, object
);
1886 HRESULT WINAPI
IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface
, DWORD Index
,D3DLIGHT8
* pLight
) {
1887 PLIGHTINFOEL
*lightInfo
= NULL
;
1888 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1889 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This
, Index
, pLight
);
1891 /* Locate the light in the live lights */
1892 lightInfo
= This
->StateBlock
->lights
;
1893 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
1895 if (lightInfo
== NULL
) {
1896 TRACE("Light information requested but light not defined\n");
1897 return D3DERR_INVALIDCALL
;
1900 memcpy(pLight
, &lightInfo
->OriginalParms
, sizeof(D3DLIGHT8
));
1903 HRESULT WINAPI
IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface
, DWORD Index
,BOOL Enable
) {
1904 PLIGHTINFOEL
*lightInfo
= NULL
;
1905 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
1906 TRACE("(%p) : Idx(%ld), enable? %d\n", This
, Index
, Enable
);
1908 /* If recording state block, just add to end of lights chain with changedEnable set to true */
1909 if (This
->isRecordingState
) {
1910 lightInfo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PLIGHTINFOEL
));
1911 if (NULL
== lightInfo
) {
1912 return D3DERR_OUTOFVIDEOMEMORY
;
1914 lightInfo
->OriginalIndex
= Index
;
1915 lightInfo
->glIndex
= -1;
1916 lightInfo
->enabledChanged
= TRUE
;
1918 /* Add to the END of the chain of lights changes to be replayed */
1919 if (This
->UpdateStateBlock
->lights
== NULL
) {
1920 This
->UpdateStateBlock
->lights
= lightInfo
;
1922 PLIGHTINFOEL
*temp
= This
->UpdateStateBlock
->lights
;
1923 while (temp
->next
!= NULL
) temp
=temp
->next
;
1924 temp
->next
= lightInfo
;
1926 TRACE("Recording... not performing anything more\n");
1930 /* Not recording... So, locate the light in the live lights */
1931 lightInfo
= This
->StateBlock
->lights
;
1932 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
1934 /* Special case - enabling an undefined light creates one with a strict set of parms! */
1935 if (lightInfo
== NULL
) {
1936 D3DLIGHT8 lightParms
;
1937 /* Warning - untested code :-) Prob safe to change fixme to a trace but
1938 wait until someone confirms it seems to work! */
1939 TRACE("Light enabled requested but light not defined, so defining one!\n");
1940 lightParms
.Type
= D3DLIGHT_DIRECTIONAL
;
1941 lightParms
.Diffuse
.r
= 1.0;
1942 lightParms
.Diffuse
.g
= 1.0;
1943 lightParms
.Diffuse
.b
= 1.0;
1944 lightParms
.Diffuse
.a
= 0.0;
1945 lightParms
.Specular
.r
= 0.0;
1946 lightParms
.Specular
.g
= 0.0;
1947 lightParms
.Specular
.b
= 0.0;
1948 lightParms
.Specular
.a
= 0.0;
1949 lightParms
.Ambient
.r
= 0.0;
1950 lightParms
.Ambient
.g
= 0.0;
1951 lightParms
.Ambient
.b
= 0.0;
1952 lightParms
.Ambient
.a
= 0.0;
1953 lightParms
.Position
.x
= 0.0;
1954 lightParms
.Position
.y
= 0.0;
1955 lightParms
.Position
.z
= 0.0;
1956 lightParms
.Direction
.x
= 0.0;
1957 lightParms
.Direction
.y
= 0.0;
1958 lightParms
.Direction
.z
= 1.0;
1959 lightParms
.Range
= 0.0;
1960 lightParms
.Falloff
= 0.0;
1961 lightParms
.Attenuation0
= 0.0;
1962 lightParms
.Attenuation1
= 0.0;
1963 lightParms
.Attenuation2
= 0.0;
1964 lightParms
.Theta
= 0.0;
1965 lightParms
.Phi
= 0.0;
1966 IDirect3DDevice8Impl_SetLight(iface
, Index
, &lightParms
);
1968 /* Search for it again! Should be fairly quick as near head of list */
1969 lightInfo
= This
->StateBlock
->lights
;
1970 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
1971 if (lightInfo
== NULL
) {
1972 FIXME("Adding default lights has failed dismally\n");
1973 return D3DERR_INVALIDCALL
;
1977 /* OK, we now have a light... */
1978 if (Enable
== FALSE
) {
1980 /* If we are disabling it, check it was enabled, and
1981 still only do something if it has assigned a glIndex (which it should have!) */
1982 if (lightInfo
->lightEnabled
&& (lightInfo
->glIndex
!= -1)) {
1983 TRACE("Disabling light set up at gl idx %ld\n", lightInfo
->glIndex
);
1985 glDisable(GL_LIGHT0
+ lightInfo
->glIndex
);
1986 checkGLcall("glDisable GL_LIGHT0+Index");
1989 TRACE("Nothing to do as light was not enabled\n");
1991 lightInfo
->lightEnabled
= FALSE
;
1994 /* We are enabling it. If it is enabled, its really simple */
1995 if (lightInfo
->lightEnabled
) {
1997 TRACE("Nothing to do as light was enabled\n");
1999 /* If it already has a glIndex, its still simple */
2000 } else if (lightInfo
->glIndex
!= -1) {
2001 TRACE("Reusing light as already set up at gl idx %ld\n", lightInfo
->glIndex
);
2002 lightInfo
->lightEnabled
= TRUE
;
2004 glEnable(GL_LIGHT0
+ lightInfo
->glIndex
);
2005 checkGLcall("glEnable GL_LIGHT0+Index already setup");
2008 /* Otherwise got to find space - lights are ordered gl indexes first */
2010 PLIGHTINFOEL
*bsf
= NULL
;
2011 PLIGHTINFOEL
*pos
= This
->StateBlock
->lights
;
2012 PLIGHTINFOEL
*prev
= NULL
;
2016 /* Try to minimize changes as much as possible */
2017 while (pos
!= NULL
&& pos
->glIndex
!= -1 && Index
< This
->maxConcurrentLights
) {
2019 /* Try to remember which index can be replaced if necessary */
2020 if (bsf
==NULL
&& pos
->lightEnabled
== FALSE
) {
2021 /* Found a light we can replace, save as best replacement */
2025 /* Step to next space */
2031 /* If we have too many active lights, fail the call */
2032 if ((Index
== This
->maxConcurrentLights
) && (bsf
== NULL
)) {
2033 FIXME("Program requests too many concurrent lights\n");
2034 return D3DERR_INVALIDCALL
;
2036 /* If we have allocated all lights, but not all are enabled,
2037 reuse one which is not enabled */
2038 } else if (Index
== This
->maxConcurrentLights
) {
2039 /* use bsf - Simply swap the new light and the BSF one */
2040 PLIGHTINFOEL
*bsfNext
= bsf
->next
;
2041 PLIGHTINFOEL
*bsfPrev
= bsf
->prev
;
2044 if (lightInfo
->next
!= NULL
) lightInfo
->next
->prev
= bsf
;
2045 if (bsf
->prev
!= NULL
) {
2046 bsf
->prev
->next
= lightInfo
;
2048 This
->StateBlock
->lights
= lightInfo
;
2051 /* If not side by side, lots of chains to update */
2052 if (bsf
->next
!= lightInfo
) {
2053 lightInfo
->prev
->next
= bsf
;
2054 bsf
->next
->prev
= lightInfo
;
2055 bsf
->next
= lightInfo
->next
;
2056 bsf
->prev
= lightInfo
->prev
;
2057 lightInfo
->next
= bsfNext
;
2058 lightInfo
->prev
= bsfPrev
;
2062 bsf
->prev
= lightInfo
;
2063 bsf
->next
= lightInfo
->next
;
2064 lightInfo
->next
= bsf
;
2065 lightInfo
->prev
= bsfPrev
;
2070 glIndex
= bsf
->glIndex
;
2072 lightInfo
->glIndex
= glIndex
;
2073 lightInfo
->lightEnabled
= TRUE
;
2075 /* Finally set up the light in gl itself */
2076 TRACE("Replacing light which was set up at gl idx %ld\n", lightInfo
->glIndex
);
2078 setup_light(iface
, glIndex
, lightInfo
);
2079 glEnable(GL_LIGHT0
+ glIndex
);
2080 checkGLcall("glEnable GL_LIGHT0 new setup");
2083 /* If we reached the end of the allocated lights, with space in the
2084 gl lights, setup a new light */
2085 } else if (pos
->glIndex
== -1) {
2087 /* We reached the end of the allocated gl lights, so already
2088 know the index of the next one! */
2090 lightInfo
->glIndex
= glIndex
;
2091 lightInfo
->lightEnabled
= TRUE
;
2093 /* In an ideal world, its already in the right place */
2094 if (lightInfo
->prev
== NULL
|| lightInfo
->prev
->glIndex
!=-1) {
2095 /* No need to move it */
2097 /* Remove this light from the list */
2098 lightInfo
->prev
->next
= lightInfo
->next
;
2099 if (lightInfo
->next
!= NULL
) {
2100 lightInfo
->next
->prev
= lightInfo
->prev
;
2103 /* Add in at appropriate place (inbetween prev and pos) */
2104 lightInfo
->prev
= prev
;
2105 lightInfo
->next
= pos
;
2107 This
->StateBlock
->lights
= lightInfo
;
2109 prev
->next
= lightInfo
;
2112 pos
->prev
= lightInfo
;
2116 /* Finally set up the light in gl itself */
2117 TRACE("Defining new light at gl idx %ld\n", lightInfo
->glIndex
);
2119 setup_light(iface
, glIndex
, lightInfo
);
2120 glEnable(GL_LIGHT0
+ glIndex
);
2121 checkGLcall("glEnable GL_LIGHT0 new setup");
2129 HRESULT WINAPI
IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface
, DWORD Index
,BOOL
* pEnable
) {
2131 PLIGHTINFOEL
*lightInfo
= NULL
;
2132 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
2133 TRACE("(%p) : for idx(%ld)\n", This
, Index
);
2135 /* Locate the light in the live lights */
2136 lightInfo
= This
->StateBlock
->lights
;
2137 while (lightInfo
!= NULL
&& lightInfo
->OriginalIndex
!= Index
) lightInfo
= lightInfo
->next
;
2139 if (lightInfo
== NULL
) {
2140 TRACE("Light enabled state requested but light not defined\n");
2141 return D3DERR_INVALIDCALL
;
2143 *pEnable
= lightInfo
->lightEnabled
;
2146 HRESULT WINAPI
IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface
, DWORD Index
,CONST
float* pPlane
) {
2147 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
2148 TRACE("(%p) : for idx %ld, %p\n", This
, Index
, pPlane
);
2150 /* Validate Index */
2151 if (Index
>= GL_LIMITS(clipplanes
)) {
2152 TRACE("Application has requested clipplane this device doesn't support\n");
2153 return D3DERR_INVALIDCALL
;
2156 This
->UpdateStateBlock
->Changed
.clipplane
[Index
] = TRUE
;
2157 This
->UpdateStateBlock
->Set
.clipplane
[Index
] = TRUE
;
2158 This
->UpdateStateBlock
->clipplane
[Index
][0] = pPlane
[0];
2159 This
->UpdateStateBlock
->clipplane
[Index
][1] = pPlane
[1];
2160 This
->UpdateStateBlock
->clipplane
[Index
][2] = pPlane
[2];
2161 This
->UpdateStateBlock
->clipplane
[Index
][3] = pPlane
[3];
2163 /* Handle recording of state blocks */
2164 if (This
->isRecordingState
) {
2165 TRACE("Recording... not performing anything\n");
2173 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2174 glMatrixMode(GL_MODELVIEW
);
2176 glLoadMatrixf((float *) &This
->StateBlock
->transforms
[D3DTS_VIEW
].u
.m
[0][0]);
2178 TRACE("Clipplane [%f,%f,%f,%f]\n",
2179 This
->UpdateStateBlock
->clipplane
[Index
][0],
2180 This
->UpdateStateBlock
->clipplane
[Index
][1],
2181 This
->UpdateStateBlock
->clipplane
[Index
][2],
2182 This
->UpdateStateBlock
->clipplane
[Index
][3]);
2183 glClipPlane(GL_CLIP_PLANE0
+ Index
, This
->UpdateStateBlock
->clipplane
[Index
]);
2184 checkGLcall("glClipPlane");
2192 HRESULT WINAPI
IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface
, DWORD Index
,float* pPlane
) {
2193 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
2194 TRACE("(%p) : for idx %ld\n", This
, Index
);
2196 /* Validate Index */
2197 if (Index
>= GL_LIMITS(clipplanes
)) {
2198 TRACE("Application has requested clipplane this device doesn't support\n");
2199 return D3DERR_INVALIDCALL
;
2202 pPlane
[0] = This
->StateBlock
->clipplane
[Index
][0];
2203 pPlane
[1] = This
->StateBlock
->clipplane
[Index
][1];
2204 pPlane
[2] = This
->StateBlock
->clipplane
[Index
][2];
2205 pPlane
[3] = This
->StateBlock
->clipplane
[Index
][3];
2208 HRESULT WINAPI
IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface
, D3DRENDERSTATETYPE State
,DWORD Value
) {
2213 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
2214 DWORD OldValue
= This
->StateBlock
->renderstate
[State
];
2216 TRACE("(%p)->state = %s(%d), value = %ld\n", This
, debug_d3drenderstate(State
), State
, Value
);
2217 This
->UpdateStateBlock
->Changed
.renderstate
[State
] = TRUE
;
2218 This
->UpdateStateBlock
->Set
.renderstate
[State
] = TRUE
;
2219 This
->UpdateStateBlock
->renderstate
[State
] = Value
;
2221 /* Handle recording of state blocks */
2222 if (This
->isRecordingState
) {
2223 TRACE("Recording... not performing anything\n");
2230 case D3DRS_FILLMODE
:
2231 switch ((D3DFILLMODE
) Value
) {
2232 case D3DFILL_POINT
: glPolygonMode(GL_FRONT_AND_BACK
, GL_POINT
); break;
2233 case D3DFILL_WIREFRAME
: glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
); break;
2234 case D3DFILL_SOLID
: glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
); break;
2236 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value
);
2238 checkGLcall("glPolygonMode (fillmode)");
2241 case D3DRS_LIGHTING
:
2243 glEnable(GL_LIGHTING
);
2244 checkGLcall("glEnable GL_LIGHTING");
2246 glDisable(GL_LIGHTING
);
2247 checkGLcall("glDisable GL_LIGHTING");
2251 case D3DRS_ZENABLE
:
2252 switch ((D3DZBUFFERTYPE
) Value
) {
2254 glDisable(GL_DEPTH_TEST
);
2255 checkGLcall("glDisable GL_DEPTH_TEST");
2258 glEnable(GL_DEPTH_TEST
);
2259 checkGLcall("glEnable GL_DEPTH_TEST");
2262 glEnable(GL_DEPTH_TEST
);
2263 checkGLcall("glEnable GL_DEPTH_TEST");
2264 FIXME("W buffer is not well handled\n");
2267 FIXME("Unrecognized D3DZBUFFERTYPE value %ld\n", Value
);
2271 case D3DRS_CULLMODE
:
2273 /* If we are culling "back faces with clockwise vertices" then
2274 set front faces to be counter clockwise and enable culling
2276 switch ((D3DCULL
) Value
) {
2278 glDisable(GL_CULL_FACE
);
2279 checkGLcall("glDisable GL_CULL_FACE");
2282 glEnable(GL_CULL_FACE
);
2283 checkGLcall("glEnable GL_CULL_FACE");
2284 if (This
->renderUpsideDown
) {
2286 checkGLcall("glFrontFace GL_CW");
2288 glFrontFace(GL_CCW
);
2289 checkGLcall("glFrontFace GL_CCW");
2291 glCullFace(GL_BACK
);
2294 glEnable(GL_CULL_FACE
);
2295 checkGLcall("glEnable GL_CULL_FACE");
2296 if (This
->renderUpsideDown
) {
2297 glFrontFace(GL_CCW
);
2298 checkGLcall("glFrontFace GL_CCW");
2301 checkGLcall("glFrontFace GL_CW");
2303 glCullFace(GL_BACK
);
2306 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value
);
2310 case D3DRS_SHADEMODE
:
2311 switch ((D3DSHADEMODE
) Value
) {
2313 glShadeModel(GL_FLAT
);
2314 checkGLcall("glShadeModel");
2316 case D3DSHADE_GOURAUD
:
2317 glShadeModel(GL_SMOOTH
);
2318 checkGLcall("glShadeModel");
2320 case D3DSHADE_PHONG
:
2321 FIXME("D3DSHADE_PHONG isn't supported?\n");
2324 return D3DERR_INVALIDCALL
;
2326 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value
);
2330 case D3DRS_DITHERENABLE
:
2332 glEnable(GL_DITHER
);
2333 checkGLcall("glEnable GL_DITHER");
2335 glDisable(GL_DITHER
);
2336 checkGLcall("glDisable GL_DITHER");
2340 case D3DRS_ZWRITEENABLE
:
2343 checkGLcall("glDepthMask");
2346 checkGLcall("glDepthMask");
2352 int glParm
= GL_LESS
;
2354 switch ((D3DCMPFUNC
) Value
) {
2355 case D3DCMP_NEVER
: glParm
=GL_NEVER
; break;
2356 case D3DCMP_LESS
: glParm
=GL_LESS
; break;
2357 case D3DCMP_EQUAL
: glParm
=GL_EQUAL
; break;
2358 case D3DCMP_LESSEQUAL
: glParm
=GL_LEQUAL
; break;
2359 case D3DCMP_GREATER
: glParm
=GL_GREATER
; break;
2360 case D3DCMP_NOTEQUAL
: glParm
=GL_NOTEQUAL
; break;
2361 case D3DCMP_GREATEREQUAL
: glParm
=GL_GEQUAL
; break;
2362 case D3DCMP_ALWAYS
: glParm
=GL_ALWAYS
; break;
2364 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2366 glDepthFunc(glParm
);
2367 checkGLcall("glDepthFunc");
2371 case D3DRS_AMBIENT
:
2374 D3DCOLORTOGLFLOAT4(Value
, col
);
2375 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col
[0], col
[1], col
[2], col
[3]);
2376 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, col
);
2377 checkGLcall("glLightModel for MODEL_AMBIENT");
2382 case D3DRS_ALPHABLENDENABLE
:
2385 checkGLcall("glEnable GL_BLEND");
2387 glDisable(GL_BLEND
);
2388 checkGLcall("glDisable GL_BLEND");
2392 case D3DRS_SRCBLEND
:
2393 case D3DRS_DESTBLEND
:
2395 int newVal
= GL_ZERO
;
2397 case D3DBLEND_ZERO
: newVal
= GL_ZERO
; break;
2398 case D3DBLEND_ONE
: newVal
= GL_ONE
; break;
2399 case D3DBLEND_SRCCOLOR
: newVal
= GL_SRC_COLOR
; break;
2400 case D3DBLEND_INVSRCCOLOR
: newVal
= GL_ONE_MINUS_SRC_COLOR
; break;
2401 case D3DBLEND_SRCALPHA
: newVal
= GL_SRC_ALPHA
; break;
2402 case D3DBLEND_INVSRCALPHA
: newVal
= GL_ONE_MINUS_SRC_ALPHA
; break;
2403 case D3DBLEND_DESTALPHA
: newVal
= GL_DST_ALPHA
; break;
2404 case D3DBLEND_INVDESTALPHA
: newVal
= GL_ONE_MINUS_DST_ALPHA
; break;
2405 case D3DBLEND_DESTCOLOR
: newVal
= GL_DST_COLOR
; break;
2406 case D3DBLEND_INVDESTCOLOR
: newVal
= GL_ONE_MINUS_DST_COLOR
; break;
2407 case D3DBLEND_SRCALPHASAT
: newVal
= GL_SRC_ALPHA_SATURATE
; break;
2409 case D3DBLEND_BOTHSRCALPHA
: newVal
= GL_SRC_ALPHA
;
2410 This
->srcBlend
= newVal
;
2411 This
->dstBlend
= newVal
;
2414 case D3DBLEND_BOTHINVSRCALPHA
: newVal
= GL_ONE_MINUS_SRC_ALPHA
;
2415 This
->srcBlend
= newVal
;
2416 This
->dstBlend
= newVal
;
2419 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value
, State
);
2422 if (State
== D3DRS_SRCBLEND
) This
->srcBlend
= newVal
;
2423 if (State
== D3DRS_DESTBLEND
) This
->dstBlend
= newVal
;
2424 TRACE("glBlendFunc src=%x, dst=%x\n", This
->srcBlend
, This
->dstBlend
);
2425 glBlendFunc(This
->srcBlend
, This
->dstBlend
);
2427 checkGLcall("glBlendFunc");
2431 case D3DRS_ALPHATESTENABLE
:
2433 glEnable(GL_ALPHA_TEST
);
2434 checkGLcall("glEnable GL_ALPHA_TEST");
2436 glDisable(GL_ALPHA_TEST
);
2437 checkGLcall("glDisable GL_ALPHA_TEST");
2441 case D3DRS_ALPHAFUNC
:
2443 int glParm
= GL_LESS
;
2444 float ref
= ((float) This
->StateBlock
->renderstate
[D3DRS_ALPHAREF
]) / 255.0f
;
2446 switch ((D3DCMPFUNC
) Value
) {
2447 case D3DCMP_NEVER
: glParm
= GL_NEVER
; break;
2448 case D3DCMP_LESS
: glParm
= GL_LESS
; break;
2449 case D3DCMP_EQUAL
: glParm
= GL_EQUAL
; break;
2450 case D3DCMP_LESSEQUAL
: glParm
= GL_LEQUAL
; break;
2451 case D3DCMP_GREATER
: glParm
= GL_GREATER
; break;
2452 case D3DCMP_NOTEQUAL
: glParm
= GL_NOTEQUAL
; break;
2453 case D3DCMP_GREATEREQUAL
: glParm
= GL_GEQUAL
; break;
2454 case D3DCMP_ALWAYS
: glParm
= GL_ALWAYS
; break;
2456 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2458 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm
, ref
);
2459 glAlphaFunc(glParm
, ref
);
2460 This
->alphafunc
= glParm
;
2461 checkGLcall("glAlphaFunc");
2465 case D3DRS_ALPHAREF
:
2467 int glParm
= This
->alphafunc
;
2470 ref
= ((float) Value
) / 255.0f
;
2471 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm
, ref
);
2472 glAlphaFunc(glParm
, ref
);
2473 checkGLcall("glAlphaFunc");
2477 case D3DRS_CLIPPLANEENABLE
:
2478 case D3DRS_CLIPPING
:
2480 /* Ensure we only do the changed clip planes */
2481 DWORD enable
= 0xFFFFFFFF;
2482 DWORD disable
= 0x00000000;
2484 /* If enabling / disabling all */
2485 if (State
== D3DRS_CLIPPING
) {
2487 enable
= This
->StateBlock
->renderstate
[D3DRS_CLIPPLANEENABLE
];
2490 disable
= This
->StateBlock
->renderstate
[D3DRS_CLIPPLANEENABLE
];
2494 enable
= Value
& ~OldValue
;
2495 disable
= ~Value
& OldValue
;
2498 if (enable
& D3DCLIPPLANE0
) { glEnable(GL_CLIP_PLANE0
); checkGLcall("glEnable(clip plane 0)"); }
2499 if (enable
& D3DCLIPPLANE1
) { glEnable(GL_CLIP_PLANE1
); checkGLcall("glEnable(clip plane 1)"); }
2500 if (enable
& D3DCLIPPLANE2
) { glEnable(GL_CLIP_PLANE2
); checkGLcall("glEnable(clip plane 2)"); }
2501 if (enable
& D3DCLIPPLANE3
) { glEnable(GL_CLIP_PLANE3
); checkGLcall("glEnable(clip plane 3)"); }
2502 if (enable
& D3DCLIPPLANE4
) { glEnable(GL_CLIP_PLANE4
); checkGLcall("glEnable(clip plane 4)"); }
2503 if (enable
& D3DCLIPPLANE5
) { glEnable(GL_CLIP_PLANE5
); checkGLcall("glEnable(clip plane 5)"); }
2505 if (disable
& D3DCLIPPLANE0
) { glDisable(GL_CLIP_PLANE0
); checkGLcall("glDisable(clip plane 0)"); }
2506 if (disable
& D3DCLIPPLANE1
) { glDisable(GL_CLIP_PLANE1
); checkGLcall("glDisable(clip plane 1)"); }
2507 if (disable
& D3DCLIPPLANE2
) { glDisable(GL_CLIP_PLANE2
); checkGLcall("glDisable(clip plane 2)"); }
2508 if (disable
& D3DCLIPPLANE3
) { glDisable(GL_CLIP_PLANE3
); checkGLcall("glDisable(clip plane 3)"); }
2509 if (disable
& D3DCLIPPLANE4
) { glDisable(GL_CLIP_PLANE4
); checkGLcall("glDisable(clip plane 4)"); }
2510 if (disable
& D3DCLIPPLANE5
) { glDisable(GL_CLIP_PLANE5
); checkGLcall("glDisable(clip plane 5)"); }
2512 /** update clipping status */
2514 This
->StateBlock
->clip_status
.ClipUnion
= 0;
2515 This
->StateBlock
->clip_status
.ClipIntersection
= 0xFFFFFFFF;
2517 This
->StateBlock
->clip_status
.ClipUnion
= 0;
2518 This
->StateBlock
->clip_status
.ClipIntersection
= 0;
2523 case D3DRS_BLENDOP
:
2525 int glParm
= GL_FUNC_ADD
;
2527 switch ((D3DBLENDOP
) Value
) {
2528 case D3DBLENDOP_ADD
: glParm
= GL_FUNC_ADD
; break;
2529 case D3DBLENDOP_SUBTRACT
: glParm
= GL_FUNC_SUBTRACT
; break;
2530 case D3DBLENDOP_REVSUBTRACT
: glParm
= GL_FUNC_REVERSE_SUBTRACT
; break;
2531 case D3DBLENDOP_MIN
: glParm
= GL_MIN
; break;
2532 case D3DBLENDOP_MAX
: glParm
= GL_MAX
; break;
2534 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value
);
2536 TRACE("glBlendEquation(%x)\n", glParm
);
2537 glBlendEquation(glParm
);
2538 checkGLcall("glBlendEquation");
2542 case D3DRS_TEXTUREFACTOR
:
2546 /* Note the texture color applies to all textures whereas
2547 GL_TEXTURE_ENV_COLOR applies to active only */
2549 D3DCOLORTOGLFLOAT4(Value
, col
);
2550 /* Set the default alpha blend color */
2551 glBlendColor(col
[0], col
[1], col
[2], col
[3]);
2552 checkGLcall("glBlendColor");
2554 /* And now the default texture color as well */
2555 for (i
= 0; i
< GL_LIMITS(textures
); i
++) {
2557 /* Note the D3DRS value applies to all textures, but GL has one
2558 per texture, so apply it now ready to be used! */
2559 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
2560 #if defined(GL_VERSION_1_3)
2561 glActiveTexture(GL_TEXTURE0
+ i
);
2563 glActiveTextureARB(GL_TEXTURE0_ARB
+ i
);
2565 checkGLcall("Activate texture.. to update const color");
2567 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2570 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, &col
[0]);
2571 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2576 case D3DRS_SPECULARENABLE
:
2578 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
2579 and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
2580 specular color. This is wrong:
2581 Separate specular color means the specular colour is maintained separately, whereas
2582 single color means it is merged in. However in both cases they are being used to
2584 To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
2585 NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
2589 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, (float*) &This
->UpdateStateBlock
->material
.Specular
);
2590 checkGLcall("glMaterialfv");
2591 if (GL_SUPPORT(EXT_SECONDARY_COLOR
)) {
2592 glEnable(GL_COLOR_SUM_EXT
);
2594 TRACE("Specular colors cannot be enabled in this version of opengl\n");
2596 checkGLcall("glEnable(GL_COLOR_SUM)");
2598 float black
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
2600 /* for the case of enabled lighting: */
2601 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, &black
[0]);
2602 checkGLcall("glMaterialfv");
2604 /* for the case of disabled lighting: */
2605 if (GL_SUPPORT(EXT_SECONDARY_COLOR
)) {
2606 glDisable(GL_COLOR_SUM_EXT
);
2608 TRACE("Specular colors cannot be disabled in this version of opengl\n");
2610 checkGLcall("glDisable(GL_COLOR_SUM)");
2615 case D3DRS_STENCILENABLE
:
2617 glEnable(GL_STENCIL_TEST
);
2618 checkGLcall("glEnable GL_STENCIL_TEST");
2620 glDisable(GL_STENCIL_TEST
);
2621 checkGLcall("glDisable GL_STENCIL_TEST");
2625 case D3DRS_STENCILFUNC
:
2627 int glParm
= GL_ALWAYS
;
2628 int ref
= This
->StateBlock
->renderstate
[D3DRS_STENCILREF
];
2629 GLuint mask
= This
->StateBlock
->renderstate
[D3DRS_STENCILMASK
];
2631 switch ((D3DCMPFUNC
) Value
) {
2632 case D3DCMP_NEVER
: glParm
=GL_NEVER
; break;
2633 case D3DCMP_LESS
: glParm
=GL_LESS
; break;
2634 case D3DCMP_EQUAL
: glParm
=GL_EQUAL
; break;
2635 case D3DCMP_LESSEQUAL
: glParm
=GL_LEQUAL
; break;
2636 case D3DCMP_GREATER
: glParm
=GL_GREATER
; break;
2637 case D3DCMP_NOTEQUAL
: glParm
=GL_NOTEQUAL
; break;
2638 case D3DCMP_GREATEREQUAL
: glParm
=GL_GEQUAL
; break;
2639 case D3DCMP_ALWAYS
: glParm
=GL_ALWAYS
; break;
2641 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value
);
2643 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2644 This
->stencilfunc
= glParm
;
2645 glStencilFunc(glParm
, ref
, mask
);
2646 checkGLcall("glStencilFunc");
2650 case D3DRS_STENCILREF
:
2652 int glParm
= This
->stencilfunc
;
2654 GLuint mask
= This
->StateBlock
->renderstate
[D3DRS_STENCILMASK
];
2657 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2658 glStencilFunc(glParm
, ref
, mask
);
2659 checkGLcall("glStencilFunc");
2663 case D3DRS_STENCILMASK
:
2665 int glParm
= This
->stencilfunc
;
2666 int ref
= This
->StateBlock
->renderstate
[D3DRS_STENCILREF
];
2667 GLuint mask
= Value
;
2669 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm
, ref
, mask
);
2670 glStencilFunc(glParm
, ref
, mask
);
2671 checkGLcall("glStencilFunc");
2675 case D3DRS_STENCILFAIL
:
2681 fail
= StencilOp(Value
);
2682 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS
, &zpass
);
2683 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2684 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL
, &zfail
);
2685 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2687 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2688 glStencilOp(fail
, zfail
, zpass
);
2689 checkGLcall("glStencilOp(fail, zfail, zpass);");
2692 case D3DRS_STENCILZFAIL
:
2698 glGetIntegerv(GL_STENCIL_FAIL
, &fail
);
2699 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2700 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS
, &zpass
);
2701 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2702 zfail
= StencilOp(Value
);
2704 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2705 glStencilOp(fail
, zfail
, zpass
);
2706 checkGLcall("glStencilOp(fail, zfail, zpass);");
2709 case D3DRS_STENCILPASS
:
2715 glGetIntegerv(GL_STENCIL_FAIL
, &fail
);
2716 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2717 zpass
= StencilOp(Value
);
2718 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL
, &zfail
);
2719 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2721 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail
, zfail
, zpass
);
2722 glStencilOp(fail
, zfail
, zpass
);
2723 checkGLcall("glStencilOp(fail, zfail, zpass);");
2727 case D3DRS_STENCILWRITEMASK
:
2729 glStencilMask(Value
);
2730 TRACE("glStencilMask(%lu)\n", Value
);
2731 checkGLcall("glStencilMask");
2735 case D3DRS_FOGENABLE
:
2737 if (Value
/* && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE*/) {
2739 checkGLcall("glEnable GL_FOG");
2742 checkGLcall("glDisable GL_FOG");
2747 case D3DRS_RANGEFOGENABLE
:
2750 TRACE("Enabled RANGEFOG");
2752 TRACE("Disabled RANGEFOG");
2757 case D3DRS_FOGCOLOR
:
2760 D3DCOLORTOGLFLOAT4(Value
, col
);
2761 /* Set the default alpha blend color */
2762 glFogfv(GL_FOG_COLOR
, &col
[0]);
2763 checkGLcall("glFog GL_FOG_COLOR");
2767 case D3DRS_FOGTABLEMODE
:
2769 glHint(GL_FOG_HINT
, GL_NICEST
);
2771 case D3DFOG_NONE
: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2772 case D3DFOG_EXP
: glFogi(GL_FOG_MODE
, GL_EXP
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2773 case D3DFOG_EXP2
: glFogi(GL_FOG_MODE
, GL_EXP2
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
2774 case D3DFOG_LINEAR
: glFogi(GL_FOG_MODE
, GL_LINEAR
); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
2776 FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value
);
2778 if (GL_SUPPORT(NV_FOG_DISTANCE
)) {
2779 glFogi(GL_FOG_DISTANCE_MODE_NV
, GL_EYE_PLANE_ABSOLUTE_NV
);
2784 case D3DRS_FOGVERTEXMODE
:
2786 glHint(GL_FOG_HINT
, GL_FASTEST
);
2788 case D3DFOG_NONE
: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2789 case D3DFOG_EXP
: glFogi(GL_FOG_MODE
, GL_EXP
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2790 case D3DFOG_EXP2
: glFogi(GL_FOG_MODE
, GL_EXP2
); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
2791 case D3DFOG_LINEAR
: glFogi(GL_FOG_MODE
, GL_LINEAR
); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
2793 FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value
);
2795 if (GL_SUPPORT(NV_FOG_DISTANCE
)) {
2796 glFogi(GL_FOG_DISTANCE_MODE_NV
, This
->StateBlock
->renderstate
[D3DRS_RANGEFOGENABLE
] ? GL_EYE_RADIAL_NV
: GL_EYE_PLANE_ABSOLUTE_NV
);
2801 case D3DRS_FOGSTART
:
2804 glFogfv(GL_FOG_START
, &tmpvalue
.f
);
2805 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2806 TRACE("Fog Start == %f\n", tmpvalue
.f
);
2813 glFogfv(GL_FOG_END
, &tmpvalue
.f
);
2814 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2815 TRACE("Fog End == %f\n", tmpvalue
.f
);
2819 case D3DRS_FOGDENSITY
:
2822 glFogfv(GL_FOG_DENSITY
, &tmpvalue
.f
);
2823 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2827 case D3DRS_VERTEXBLEND
:
2829 This
->UpdateStateBlock
->vertex_blend
= (D3DVERTEXBLENDFLAGS
) Value
;
2830 TRACE("Vertex Blending state to %ld\n", Value
);
2834 case D3DRS_TWEENFACTOR
:
2837 This
->UpdateStateBlock
->tween_factor
= tmpvalue
.f
;
2838 TRACE("Vertex Blending Tween Factor to %f\n", This
->UpdateStateBlock
->tween_factor
);
2842 case D3DRS_INDEXEDVERTEXBLENDENABLE
:
2844 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL
) Value
);
2848 case D3DRS_COLORVERTEX
:
2849 case D3DRS_DIFFUSEMATERIALSOURCE
:
2850 case D3DRS_SPECULARMATERIALSOURCE
:
2851 case D3DRS_AMBIENTMATERIALSOURCE
:
2852 case D3DRS_EMISSIVEMATERIALSOURCE
:
2854 GLenum Parm
= GL_AMBIENT_AND_DIFFUSE
;
2856 if (This
->StateBlock
->renderstate
[D3DRS_COLORVERTEX
]) {
2857 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
2858 This
->StateBlock
->renderstate
[D3DRS_DIFFUSEMATERIALSOURCE
],
2859 This
->StateBlock
->renderstate
[D3DRS_AMBIENTMATERIALSOURCE
],
2860 This
->StateBlock
->renderstate
[D3DRS_EMISSIVEMATERIALSOURCE
],
2861 This
->StateBlock
->renderstate
[D3DRS_SPECULARMATERIALSOURCE
]);
2863 if (This
->StateBlock
->renderstate
[D3DRS_DIFFUSEMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2864 if (This
->StateBlock
->renderstate
[D3DRS_AMBIENTMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2865 Parm
= GL_AMBIENT_AND_DIFFUSE
;
2869 } else if (This
->StateBlock
->renderstate
[D3DRS_AMBIENTMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2871 } else if (This
->StateBlock
->renderstate
[D3DRS_EMISSIVEMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2873 } else if (This
->StateBlock
->renderstate
[D3DRS_SPECULARMATERIALSOURCE
] == D3DMCS_COLOR1
) {
2880 if (This
->tracking_color
!= DISABLED_TRACKING
) This
->tracking_color
= NEEDS_DISABLE
;
2882 This
->tracking_color
= NEEDS_TRACKING
;
2883 This
->tracking_parm
= Parm
;
2887 if (This
->tracking_color
!= DISABLED_TRACKING
) This
->tracking_color
= NEEDS_DISABLE
;
2892 case D3DRS_LINEPATTERN
:
2898 tmppattern
.d
= Value
;
2900 TRACE("Line pattern: repeat %d bits %x\n", tmppattern
.lp
.wRepeatFactor
, tmppattern
.lp
.wLinePattern
);
2902 if (tmppattern
.lp
.wRepeatFactor
) {
2903 glLineStipple(tmppattern
.lp
.wRepeatFactor
, tmppattern
.lp
.wLinePattern
);
2904 checkGLcall("glLineStipple(repeat, linepattern)");
2905 glEnable(GL_LINE_STIPPLE
);
2906 checkGLcall("glEnable(GL_LINE_STIPPLE);");
2908 glDisable(GL_LINE_STIPPLE
);
2909 checkGLcall("glDisable(GL_LINE_STIPPLE);");
2918 TRACE("ZBias value %f\n", tmpvalue
.f
);
2919 glPolygonOffset(0, -tmpvalue
.f
);
2920 checkGLcall("glPolygonOffset(0, -Value)");
2921 glEnable(GL_POLYGON_OFFSET_FILL
);
2922 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
2923 glEnable(GL_POLYGON_OFFSET_LINE
);
2924 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
2925 glEnable(GL_POLYGON_OFFSET_POINT
);
2926 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
2928 glDisable(GL_POLYGON_OFFSET_FILL
);
2929 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
2930 glDisable(GL_POLYGON_OFFSET_LINE
);
2931 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
2932 glDisable(GL_POLYGON_OFFSET_POINT
);
2933 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
2938 case D3DRS_NORMALIZENORMALS
:
2940 glEnable(GL_NORMALIZE
);
2941 checkGLcall("glEnable(GL_NORMALIZE);");
2943 glDisable(GL_NORMALIZE
);
2944 checkGLcall("glDisable(GL_NORMALIZE);");
2948 case D3DRS_POINTSIZE
:
2950 TRACE("Set point size to %f\n", tmpvalue
.f
);
2951 glPointSize(tmpvalue
.f
);
2952 checkGLcall("glPointSize(...);");
2955 case D3DRS_POINTSIZE_MIN
:
2956 if (GL_SUPPORT(EXT_POINT_PARAMETERS
)) {
2958 GL_EXTCALL(glPointParameterfEXT
)(GL_POINT_SIZE_MIN_EXT
, tmpvalue
.f
);
2959 checkGLcall("glPointParameterfEXT(...);");
2961 FIXME("D3DRS_POINTSIZE_MIN not supported on this opengl\n");
2965 case D3DRS_POINTSIZE_MAX
:
2966 if (GL_SUPPORT(EXT_POINT_PARAMETERS
)) {
2968 GL_EXTCALL(glPointParameterfEXT
)(GL_POINT_SIZE_MAX_EXT
, tmpvalue
.f
);
2969 checkGLcall("glPointParameterfEXT(...);");
2971 FIXME("D3DRS_POINTSIZE_MAX not supported on this opengl\n");
2975 case D3DRS_POINTSCALE_A
:
2976 case D3DRS_POINTSCALE_B
:
2977 case D3DRS_POINTSCALE_C
:
2978 case D3DRS_POINTSCALEENABLE
:
2981 * POINTSCALEENABLE controls how point size value is treated. If set to
2982 * true, the point size is scaled with respect to height of viewport.
2983 * When set to false point size is in pixels.
2985 * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
2988 /* Default values */
2989 GLfloat att
[3] = {1.0f
, 0.0f
, 0.0f
};
2992 * Minium valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
2993 * This means that OpenGL will clamp really small point sizes to 1.0f.
2994 * To correct for this we need to multiply by the scale factor when sizes
2995 * are less than 1.0f. scale_factor = 1.0f / point_size.
2997 GLfloat pointSize
= *((float*)&This
->StateBlock
->renderstate
[D3DRS_POINTSIZE
]);
2998 GLfloat scaleFactor
;
2999 if(pointSize
< 1.0f
) {
3000 scaleFactor
= pointSize
* pointSize
;
3005 if(This
->StateBlock
->renderstate
[D3DRS_POINTSCALEENABLE
]) {
3006 att
[0] = *((float*)&This
->StateBlock
->renderstate
[D3DRS_POINTSCALE_A
]) /
3007 (This
->StateBlock
->viewport
.Height
* This
->StateBlock
->viewport
.Height
* scaleFactor
);
3008 att
[1] = *((float*)&This
->StateBlock
->renderstate
[D3DRS_POINTSCALE_B
]) /
3009 (This
->StateBlock
->viewport
.Height
* This
->StateBlock
->viewport
.Height
* scaleFactor
);
3010 att
[2] = *((float*)&This
->StateBlock
->renderstate
[D3DRS_POINTSCALE_C
]) /
3011 (This
->StateBlock
->viewport
.Height
* This
->StateBlock
->viewport
.Height
* scaleFactor
);
3014 if(GL_SUPPORT(ARB_POINT_PARAMETERS
)) {
3015 GL_EXTCALL(glPointParameterfvARB
)(GL_POINT_DISTANCE_ATTENUATION_ARB
, att
);
3016 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
3018 else if(GL_SUPPORT(EXT_POINT_PARAMETERS
)) {
3019 GL_EXTCALL(glPointParameterfvEXT
)(GL_DISTANCE_ATTENUATION_EXT
, att
);
3020 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
3023 TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
3027 case D3DRS_COLORWRITEENABLE
:
3029 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
3030 Value
& D3DCOLORWRITEENABLE_RED
? 1 : 0,
3031 Value
& D3DCOLORWRITEENABLE_GREEN
? 1 : 0,
3032 Value
& D3DCOLORWRITEENABLE_BLUE
? 1 : 0,
3033 Value
& D3DCOLORWRITEENABLE_ALPHA
? 1 : 0);
3034 glColorMask(Value
& D3DCOLORWRITEENABLE_RED
? GL_TRUE
: GL_FALSE
,
3035 Value
& D3DCOLORWRITEENABLE_GREEN
? GL_TRUE
: GL_FALSE
,
3036 Value
& D3DCOLORWRITEENABLE_BLUE
? GL_TRUE
: GL_FALSE
,
3037 Value
& D3DCOLORWRITEENABLE_ALPHA
? GL_TRUE
: GL_FALSE
);
3038 checkGLcall("glColorMask(...)");
3042 case D3DRS_LOCALVIEWER
:
3044 GLint state
= (Value
) ? 1 : 0;
3045 TRACE("Local Viewer Enable to %ul\n", (BOOL
) Value
);
3046 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, state
);
3050 case D3DRS_LASTPIXEL
:
3053 TRACE("Last Pixel Drawing Enabled\n");
3055 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
3060 case D3DRS_SOFTWAREVERTEXPROCESSING
:
3063 TRACE("Software Processing Enabled\n");
3065 TRACE("Software Processing Disabled\n");
3070 /** not supported */
3071 case D3DRS_ZVISIBLE
:
3074 return D3DERR_INVALIDCALL
;
3077 /* Unhandled yet...! */
3078 case D3DRS_EDGEANTIALIAS
:
3081 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
3083 checkGLcall("glEnable GL_BLEND");
3084 glEnable(GL_LINE_SMOOTH
);
3085 checkGLcall("glEnable Gl_LINE_SMOOTH");
3087 glDisable(GL_BLEND
);
3088 checkGLcall("glDisable GL_BLEND");
3089 glDisable(GL_LINE_SMOOTH
);
3090 checkGLcall("glDisable GL_LINE_SMOOTH");
3103 FIXME("(%p)->(%d,%ld) not handled yet\n", This
, State
, Value
);
3106 case D3DRS_POINTSPRITEENABLE
:
3108 if (!GL_SUPPORT(ARB_POINT_SPRITE
)) {
3109 TRACE("Point sprites not supported\n");
3114 * Point sprites are always enabled. Value controls texture coordinate
3115 * replacement mode. Must be set true for point sprites to use
3118 glEnable(GL_POINT_SPRITE_ARB
);
3119 checkGLcall("glEnable GL_POINT_SPRITE_ARB");
3122 glTexEnvf(GL_POINT_SPRITE_ARB
, GL_COORD_REPLACE_ARB
, TRUE
);
3124 glTexEnvf(GL_POINT_SPRITE_ARB
, GL_COORD_REPLACE_ARB
, FALSE
);
3128 case D3DRS_MULTISAMPLEANTIALIAS
:
3130 if (!GL_SUPPORT(ARB_MULTISAMPLE
)) {
3131 TRACE("Multisample antialiasing not supported\n");
3136 glEnable(GL_MULTISAMPLE_ARB
);
3137 checkGLcall("glEnable GL_MULTISAMPLE_ARB");
3139 glDisable(GL_MULTISAMPLE_ARB
);
3140 checkGLcall("glDisable GL_MULTISAMPLE_ARB");
3144 case D3DRS_MULTISAMPLEMASK
:
3145 case D3DRS_PATCHEDGESTYLE
:
3146 case D3DRS_PATCHSEGMENTS
:
3147 case D3DRS_DEBUGMONITORTOKEN
:
3148 case D3DRS_POSITIONORDER
:
3149 case D3DRS_NORMALORDER
:
3150 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
3151 FIXME("(%p)->(%d,%ld) not handled yet\n", This
, State
, Value
);
3154 FIXME("(%p)->(%d,%ld) unrecognized\n", This
, State
, Value
);
3161 HRESULT WINAPI
IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface
, D3DRENDERSTATETYPE State
,DWORD
* pValue
) {
3162 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3163 TRACE("(%p) for State %d = %ld\n", This
, State
, This
->UpdateStateBlock
->renderstate
[State
]);
3164 *pValue
= This
->StateBlock
->renderstate
[State
];
3167 HRESULT WINAPI
IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface
) {
3168 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3170 TRACE("(%p)\n", This
);
3172 return IDirect3DDeviceImpl_BeginStateBlock(This
);
3174 HRESULT WINAPI
IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD
* pToken
) {
3175 IDirect3DStateBlockImpl
* pSB
;
3176 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3179 TRACE("(%p)\n", This
);
3181 res
= IDirect3DDeviceImpl_EndStateBlock(This
, &pSB
);
3182 *pToken
= (DWORD
) pSB
;
3186 HRESULT WINAPI
IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD Token
) {
3187 IDirect3DStateBlockImpl
* pSB
= (IDirect3DStateBlockImpl
*) Token
;
3188 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3190 TRACE("(%p)\n", This
);
3192 return IDirect3DDeviceImpl_ApplyStateBlock(This
, pSB
);
3195 HRESULT WINAPI
IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD Token
) {
3196 IDirect3DStateBlockImpl
* pSB
= (IDirect3DStateBlockImpl
*) Token
;
3197 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3199 TRACE("(%p)\n", This
);
3201 return IDirect3DDeviceImpl_CaptureStateBlock(This
, pSB
);
3203 HRESULT WINAPI
IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface
, DWORD Token
) {
3204 IDirect3DStateBlockImpl
* pSB
= (IDirect3DStateBlockImpl
*) Token
;
3205 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3207 TRACE("(%p)\n", This
);
3209 return IDirect3DDeviceImpl_DeleteStateBlock(This
, pSB
);
3212 HRESULT WINAPI
IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface
, D3DSTATEBLOCKTYPE Type
, DWORD
* pToken
) {
3213 IDirect3DStateBlockImpl
* pSB
;
3214 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3217 TRACE("(%p) : for type %d\n", This
, Type
);
3219 res
= IDirect3DDeviceImpl_CreateStateBlock(This
, Type
, &pSB
);
3220 *pToken
= (DWORD
) pSB
;
3224 HRESULT WINAPI
IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface
, CONST D3DCLIPSTATUS8
* pClipStatus
) {
3225 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3226 FIXME("(%p) : stub\n", This
);
3227 if (NULL
== pClipStatus
) {
3228 return D3DERR_INVALIDCALL
;
3230 This
->UpdateStateBlock
->clip_status
.ClipUnion
= pClipStatus
->ClipUnion
;
3231 This
->UpdateStateBlock
->clip_status
.ClipIntersection
= pClipStatus
->ClipIntersection
;
3234 HRESULT WINAPI
IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface
, D3DCLIPSTATUS8
* pClipStatus
) {
3235 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3236 FIXME("(%p) : stub\n", This
);
3237 if (NULL
== pClipStatus
) {
3238 return D3DERR_INVALIDCALL
;
3240 pClipStatus
->ClipUnion
= This
->UpdateStateBlock
->clip_status
.ClipUnion
;
3241 pClipStatus
->ClipIntersection
= This
->UpdateStateBlock
->clip_status
.ClipIntersection
;
3244 HRESULT WINAPI
IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface
, DWORD Stage
,IDirect3DBaseTexture8
** ppTexture
) {
3245 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3246 TRACE("(%p) : returning %p for stage %ld\n", This
, This
->UpdateStateBlock
->textures
[Stage
], Stage
);
3247 *ppTexture
= (LPDIRECT3DBASETEXTURE8
) This
->UpdateStateBlock
->textures
[Stage
];
3249 IDirect3DBaseTexture8Impl_AddRef(*ppTexture
);
3252 HRESULT WINAPI
IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface
, DWORD Stage
, IDirect3DBaseTexture8
* pTexture
) {
3254 IDirect3DBaseTexture8
*oldTxt
;
3255 BOOL reapplyStates
= TRUE
;
3256 INT oldTextureDimensions
= -1;
3257 DWORD reapplyFlags
= 0;
3259 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3260 D3DRESOURCETYPE textureType
;
3262 oldTxt
= This
->UpdateStateBlock
->textures
[Stage
];
3263 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This
, Stage
, pTexture
);
3265 /* Reject invalid texture units */
3266 if (Stage
>= GL_LIMITS(textures
)) {
3267 TRACE("Attempt to access invalid texture rejected\n");
3268 return D3DERR_INVALIDCALL
;
3271 This
->UpdateStateBlock
->Set
.textures
[Stage
] = TRUE
;
3272 This
->UpdateStateBlock
->Changed
.textures
[Stage
] = TRUE
;
3273 This
->UpdateStateBlock
->textures
[Stage
] = pTexture
;
3275 /* Handle recording of state blocks */
3276 if (This
->isRecordingState
) {
3277 TRACE("Recording... not performing anything\n");
3281 oldTextureDimensions
= This
->UpdateStateBlock
->textureDimensions
[Stage
];
3284 /* Make appropriate texture active */
3285 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
3286 #if defined(GL_VERSION_1_3)
3287 glActiveTexture(GL_TEXTURE0
+ Stage
);
3288 checkGLcall("glActiveTexture");
3290 glActiveTextureARB(GL_TEXTURE0_ARB
+ Stage
);
3291 checkGLcall("glActiveTextureARB");
3293 } else if (Stage
>0) {
3294 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3297 /* Decrement the count of the previous texture */
3298 if (NULL
!= oldTxt
) {
3299 IDirect3DBaseTexture8Impl_Release(oldTxt
);
3302 if (NULL
!= pTexture
) {
3303 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8
) This
->UpdateStateBlock
->textures
[Stage
]);
3305 /* Now setup the texture appropraitly */
3306 textureType
= IDirect3DBaseTexture8Impl_GetType(pTexture
);
3308 if (textureType
== D3DRTYPE_TEXTURE
) {
3309 if (oldTxt
== pTexture
&& IDirect3DBaseTexture8Impl_IsDirty(pTexture
)) {
3310 TRACE("Skipping setting texture as old == new\n");
3311 reapplyStates
= FALSE
;
3313 /* Standard 2D texture */
3314 TRACE("Standard 2d texture\n");
3315 This
->UpdateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_2D
;
3317 /* Load up the texture now */
3318 IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8
) pTexture
);
3320 } else if (textureType
== D3DRTYPE_VOLUMETEXTURE
) {
3321 if (oldTxt
== pTexture
&& IDirect3DBaseTexture8Impl_IsDirty(pTexture
)) {
3322 TRACE("Skipping setting texture as old == new\n");
3323 reapplyStates
= FALSE
;
3325 /* Standard 3D (volume) texture */
3326 TRACE("Standard 3d texture\n");
3327 This
->UpdateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_3D
;
3329 /* Load up the texture now */
3330 IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8
) pTexture
);
3332 } else if (textureType
== D3DRTYPE_CUBETEXTURE
) {
3333 if (oldTxt
== pTexture
&& IDirect3DBaseTexture8Impl_IsDirty(pTexture
)) {
3334 TRACE("Skipping setting texture as old == new\n");
3335 reapplyStates
= FALSE
;
3337 /* Standard Cube texture */
3338 TRACE("Standard Cube texture\n");
3339 This
->UpdateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_CUBE_MAP_ARB
;
3341 /* Load up the texture now */
3342 IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8
) pTexture
);
3345 FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This
, textureType
, debug_d3dressourcetype(textureType
));
3348 TRACE("Setting to no texture (ie default texture)\n");
3349 This
->UpdateStateBlock
->textureDimensions
[Stage
] = GL_TEXTURE_1D
;
3350 glBindTexture(GL_TEXTURE_1D
, This
->dummyTextureName
[Stage
]);
3351 checkGLcall("glBindTexture");
3352 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage
, This
->dummyTextureName
[Stage
]);
3355 /* Disable the old texture binding and enable the new one (unless operations are disabled) */
3356 if (oldTextureDimensions
!= This
->UpdateStateBlock
->textureDimensions
[Stage
]) {
3357 glDisable(oldTextureDimensions
);
3358 checkGLcall("Disable oldTextureDimensions");
3359 if (This
->StateBlock
->texture_state
[Stage
][D3DTSS_COLOROP
] != D3DTOP_DISABLE
) {
3360 glEnable(This
->UpdateStateBlock
->textureDimensions
[Stage
]);
3361 checkGLcall("glEnable new texture dimensions");
3364 /* If Alpha arg1 is texture then handle the special case when there changes between a
3365 texture and no texture - See comments in set_tex_op */
3366 if ((This
->StateBlock
->texture_state
[Stage
][D3DTSS_ALPHAARG1
] == D3DTA_TEXTURE
) &&
3367 (((oldTxt
== NULL
) && (pTexture
!= NULL
)) || ((pTexture
== NULL
) && (oldTxt
!= NULL
))))
3369 reapplyFlags
|= REAPPLY_ALPHAOP
;
3374 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
3375 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
3376 if (reapplyStates
) {
3377 setupTextureStates(iface
, Stage
, reapplyFlags
);
3385 HRESULT WINAPI
IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface
, DWORD Stage
,D3DTEXTURESTAGESTATETYPE Type
,DWORD
* pValue
) {
3386 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3387 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This
, Stage
, Type
, This
->UpdateStateBlock
->texture_state
[Stage
][Type
]);
3388 *pValue
= This
->UpdateStateBlock
->texture_state
[Stage
][Type
];
3392 HRESULT WINAPI
IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface
, DWORD Stage
, D3DTEXTURESTAGESTATETYPE Type
, DWORD Value
) {
3393 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3399 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
3401 TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This
, Stage
, debug_d3dtexturestate(Type
), Type
, Value
);
3403 /* Reject invalid texture units */
3404 if (Stage
>= GL_LIMITS(textures
)) {
3405 TRACE("Attempt to access invalid texture rejected\n");
3406 return D3DERR_INVALIDCALL
;
3409 This
->UpdateStateBlock
->Changed
.texture_state
[Stage
][Type
] = TRUE
;
3410 This
->UpdateStateBlock
->Set
.texture_state
[Stage
][Type
] = TRUE
;
3411 This
->UpdateStateBlock
->texture_state
[Stage
][Type
] = Value
;
3413 /* Handle recording of state blocks */
3414 if (This
->isRecordingState
) {
3415 TRACE("Recording... not performing anything\n");
3421 /* Make appropriate texture active */
3422 VTRACE(("Activating appropriate texture state %ld\n", Stage
));
3423 if (GL_SUPPORT(ARB_MULTITEXTURE
)) {
3424 #if defined(GL_VERSION_1_3)
3425 glActiveTexture(GL_TEXTURE0
+ Stage
);
3426 vcheckGLcall("glActiveTexture");
3428 glActiveTextureARB(GL_TEXTURE0_ARB
+ Stage
);
3429 vcheckGLcall("glActiveTextureARB");
3431 } else if (Stage
> 0) {
3432 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3437 case D3DTSS_MINFILTER
:
3438 case D3DTSS_MIPFILTER
:
3440 DWORD ValueMIN
= This
->StateBlock
->texture_state
[Stage
][D3DTSS_MINFILTER
];
3441 DWORD ValueMIP
= This
->StateBlock
->texture_state
[Stage
][D3DTSS_MIPFILTER
];
3442 GLint realVal
= GL_LINEAR
;
3444 if (ValueMIN
== D3DTEXF_NONE
) {
3445 /* Doesn't really make sense - Windows just seems to disable
3446 mipmapping when this occurs */
3447 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
3448 realVal
= GL_LINEAR
;
3449 } else if (ValueMIN
== D3DTEXF_POINT
) {
3451 if (ValueMIP
== D3DTEXF_NONE
) {
3452 realVal
= GL_NEAREST
;
3453 } else if (ValueMIP
== D3DTEXF_POINT
) {
3454 realVal
= GL_NEAREST_MIPMAP_NEAREST
;
3455 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
3456 realVal
= GL_NEAREST_MIPMAP_LINEAR
;
3458 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
3459 realVal
= GL_NEAREST
;
3461 } else if (ValueMIN
== D3DTEXF_LINEAR
) {
3463 if (ValueMIP
== D3DTEXF_NONE
) {
3464 realVal
= GL_LINEAR
;
3465 } else if (ValueMIP
== D3DTEXF_POINT
) {
3466 realVal
= GL_LINEAR_MIPMAP_NEAREST
;
3467 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
3468 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3470 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
3471 realVal
= GL_LINEAR
;
3473 } else if (ValueMIN
== D3DTEXF_ANISOTROPIC
) {
3474 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
3475 if (ValueMIP
== D3DTEXF_NONE
) {
3476 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3477 } else if (ValueMIP
== D3DTEXF_POINT
) {
3478 realVal
= GL_LINEAR_MIPMAP_NEAREST
;
3479 } else if (ValueMIP
== D3DTEXF_LINEAR
) {
3480 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3482 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP
);
3483 realVal
= GL_LINEAR
;
3486 WARN("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MINFILTER. But not supported by OpenGL driver\n");
3487 realVal
= GL_LINEAR
;
3490 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN
);
3491 realVal
= GL_LINEAR_MIPMAP_LINEAR
;
3494 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN
, ValueMIP
, realVal
);
3495 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
], GL_TEXTURE_MIN_FILTER
, realVal
);
3496 checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
3498 * if we juste choose to use ANISOTROPIC filtering, refresh openGL state
3500 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
) && D3DTEXF_ANISOTROPIC
== ValueMIN
) {
3501 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
],
3502 GL_TEXTURE_MAX_ANISOTROPY_EXT
,
3503 This
->StateBlock
->texture_state
[Stage
][D3DTSS_MAXANISOTROPY
]);
3504 checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
3509 case D3DTSS_MAGFILTER
:
3511 DWORD ValueMAG
= This
->StateBlock
->texture_state
[Stage
][D3DTSS_MAGFILTER
];
3512 GLint realVal
= GL_NEAREST
;
3514 if (ValueMAG
== D3DTEXF_POINT
) {
3515 realVal
= GL_NEAREST
;
3516 } else if (ValueMAG
== D3DTEXF_LINEAR
) {
3517 realVal
= GL_LINEAR
;
3518 } else if (ValueMAG
== D3DTEXF_ANISOTROPIC
) {
3519 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
3520 realVal
= GL_LINEAR
;
3522 FIXME("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MAGFILTER. But not supported by current OpenGL driver\n");
3523 realVal
= GL_NEAREST
;
3526 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", ValueMAG
);
3527 realVal
= GL_NEAREST
;
3529 TRACE("ValueMAG=%ld setting MAGFILTER to %x\n", ValueMAG
, realVal
);
3530 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
], GL_TEXTURE_MAG_FILTER
, realVal
);
3531 checkGLcall("glTexParameter GL_TEXTURE_MAG_FILTER, ...");
3533 * if we juste choose to use ANISOTROPIC filtering, refresh openGL state
3535 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
) && D3DTEXF_ANISOTROPIC
== ValueMAG
) {
3536 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
],
3537 GL_TEXTURE_MAX_ANISOTROPY_EXT
,
3538 This
->StateBlock
->texture_state
[Stage
][D3DTSS_MAXANISOTROPY
]);
3539 checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
3544 case D3DTSS_MAXMIPLEVEL
:
3547 * Not really the same, but the more apprioprate than nothing
3549 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
],
3550 GL_TEXTURE_BASE_LEVEL
,
3551 This
->StateBlock
->texture_state
[Stage
][D3DTSS_MAXMIPLEVEL
]);
3552 checkGLcall("glTexParameteri GL_TEXTURE_BASE_LEVEL ...");
3556 case D3DTSS_MAXANISOTROPY
:
3558 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
3559 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
],
3560 GL_TEXTURE_MAX_ANISOTROPY_EXT
,
3561 This
->StateBlock
->texture_state
[Stage
][D3DTSS_MAXANISOTROPY
]);
3562 checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
3567 case D3DTSS_MIPMAPLODBIAS
:
3569 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS
)) {
3571 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
,
3572 GL_TEXTURE_LOD_BIAS_EXT
,
3574 checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
3579 case D3DTSS_ALPHAOP
:
3580 case D3DTSS_COLOROP
:
3583 if ((Value
== D3DTOP_DISABLE
) && (Type
== D3DTSS_COLOROP
)) {
3584 /* TODO: Disable by making this and all later levels disabled */
3585 glDisable(GL_TEXTURE_1D
);
3586 checkGLcall("Disable GL_TEXTURE_1D");
3587 glDisable(GL_TEXTURE_2D
);
3588 checkGLcall("Disable GL_TEXTURE_2D");
3589 glDisable(GL_TEXTURE_3D
);
3590 checkGLcall("Disable GL_TEXTURE_3D");
3591 break; /* Don't bother setting the texture operations */
3593 /* Enable only the appropriate texture dimension */
3594 if (Type
== D3DTSS_COLOROP
) {
3595 if (This
->StateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_1D
) {
3596 glEnable(GL_TEXTURE_1D
);
3597 checkGLcall("Enable GL_TEXTURE_1D");
3599 glDisable(GL_TEXTURE_1D
);
3600 checkGLcall("Disable GL_TEXTURE_1D");
3602 if (This
->StateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_2D
) {
3603 if (GL_SUPPORT(NV_TEXTURE_SHADER
) && This
->texture_shader_active
) {
3604 glTexEnvi(GL_TEXTURE_SHADER_NV
, GL_SHADER_OPERATION_NV
, GL_TEXTURE_2D
);
3605 checkGLcall("Enable GL_TEXTURE_2D");
3607 glEnable(GL_TEXTURE_2D
);
3608 checkGLcall("Enable GL_TEXTURE_2D");
3611 glDisable(GL_TEXTURE_2D
);
3612 checkGLcall("Disable GL_TEXTURE_2D");
3614 if (This
->StateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_3D
) {
3615 glEnable(GL_TEXTURE_3D
);
3616 checkGLcall("Enable GL_TEXTURE_3D");
3618 glDisable(GL_TEXTURE_3D
);
3619 checkGLcall("Disable GL_TEXTURE_3D");
3621 if (This
->StateBlock
->textureDimensions
[Stage
] == GL_TEXTURE_CUBE_MAP_ARB
) {
3622 glEnable(GL_TEXTURE_CUBE_MAP_ARB
);
3623 checkGLcall("Enable GL_TEXTURE_CUBE_MAP");
3625 glDisable(GL_TEXTURE_CUBE_MAP_ARB
);
3626 checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
3630 /* Drop through... (Except disable case) */
3631 case D3DTSS_COLORARG0
:
3632 case D3DTSS_COLORARG1
:
3633 case D3DTSS_COLORARG2
:
3634 case D3DTSS_ALPHAARG0
:
3635 case D3DTSS_ALPHAARG1
:
3636 case D3DTSS_ALPHAARG2
:
3638 BOOL isAlphaArg
= (Type
== D3DTSS_ALPHAOP
|| Type
== D3DTSS_ALPHAARG1
||
3639 Type
== D3DTSS_ALPHAARG2
|| Type
== D3DTSS_ALPHAARG0
);
3641 set_tex_op(iface
, TRUE
, Stage
, This
->StateBlock
->texture_state
[Stage
][D3DTSS_ALPHAOP
],
3642 This
->StateBlock
->texture_state
[Stage
][D3DTSS_ALPHAARG1
],
3643 This
->StateBlock
->texture_state
[Stage
][D3DTSS_ALPHAARG2
],
3644 This
->StateBlock
->texture_state
[Stage
][D3DTSS_ALPHAARG0
]);
3646 set_tex_op(iface
, FALSE
, Stage
, This
->StateBlock
->texture_state
[Stage
][D3DTSS_COLOROP
],
3647 This
->StateBlock
->texture_state
[Stage
][D3DTSS_COLORARG1
],
3648 This
->StateBlock
->texture_state
[Stage
][D3DTSS_COLORARG2
],
3649 This
->StateBlock
->texture_state
[Stage
][D3DTSS_COLORARG0
]);
3655 case D3DTSS_ADDRESSU
:
3656 case D3DTSS_ADDRESSV
:
3657 case D3DTSS_ADDRESSW
:
3659 GLint wrapParm
= GL_REPEAT
;
3662 case D3DTADDRESS_WRAP
: wrapParm
= GL_REPEAT
; break;
3663 case D3DTADDRESS_CLAMP
: wrapParm
= GL_CLAMP_TO_EDGE
; break;
3664 case D3DTADDRESS_BORDER
:
3666 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP
)) {
3667 wrapParm
= GL_CLAMP_TO_BORDER_ARB
;
3669 /* FIXME: Not right, but better */
3670 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value
, Type
);
3671 wrapParm
= GL_REPEAT
;
3675 case D3DTADDRESS_MIRROR
:
3677 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT
)) {
3678 wrapParm
= GL_MIRRORED_REPEAT_ARB
;
3680 /* Unsupported in OpenGL pre-1.4 */
3681 FIXME("Unsupported D3DTADDRESS_MIRROR (needs GL_ARB_texture_mirrored_repeat) state %d\n", Type
);
3682 wrapParm
= GL_REPEAT
;
3686 case D3DTADDRESS_MIRRORONCE
:
3688 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE
)) {
3689 wrapParm
= GL_MIRROR_CLAMP_TO_EDGE_ATI
;
3691 FIXME("Unsupported D3DTADDRESS_MIRRORONCE (needs GL_ATI_texture_mirror_once) state %d\n", Type
);
3692 wrapParm
= GL_REPEAT
;
3698 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value
, Type
);
3699 wrapParm
= GL_REPEAT
;
3703 case D3DTSS_ADDRESSU
:
3704 TRACE("Setting WRAP_S to %d for %x\n", wrapParm
, This
->StateBlock
->textureDimensions
[Stage
]);
3705 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
], GL_TEXTURE_WRAP_S
, wrapParm
);
3706 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3708 case D3DTSS_ADDRESSV
:
3709 TRACE("Setting WRAP_T to %d for %x\n", wrapParm
, This
->StateBlock
->textureDimensions
[Stage
]);
3710 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
], GL_TEXTURE_WRAP_T
, wrapParm
);
3711 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3713 case D3DTSS_ADDRESSW
:
3714 TRACE("Setting WRAP_R to %d for %x\n", wrapParm
, This
->StateBlock
->textureDimensions
[Stage
]);
3715 glTexParameteri(This
->StateBlock
->textureDimensions
[Stage
], GL_TEXTURE_WRAP_R
, wrapParm
);
3716 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3719 break; /** stupic compilator */
3724 case D3DTSS_BORDERCOLOR
:
3727 D3DCOLORTOGLFLOAT4(Value
, col
);
3728 TRACE("Setting border color for %x to %lx\n", This
->StateBlock
->textureDimensions
[Stage
], Value
);
3729 glTexParameterfv(This
->StateBlock
->textureDimensions
[Stage
], GL_TEXTURE_BORDER_COLOR
, &col
[0]);
3730 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3734 case D3DTSS_TEXCOORDINDEX
:
3736 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
3738 /* FIXME: From MSDN: The D3DTSS_TCI_* flags are mutually exclusive. If you include
3739 one flag, you can still specify an index value, which the system uses to
3740 determine the texture wrapping mode.
3741 eg. SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3742 means use the vertex position (camera-space) as the input texture coordinates
3743 for this texture stage, and the wrap mode set in the D3DRS_WRAP1 render
3744 state. We do not (yet) support the D3DRENDERSTATE_WRAPx values, nor tie them up
3745 to the TEXCOORDINDEX value */
3748 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
3750 switch (Value
& 0xFFFF0000) {
3751 case D3DTSS_TCI_PASSTHRU
:
3752 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
3753 glDisable(GL_TEXTURE_GEN_S
);
3754 glDisable(GL_TEXTURE_GEN_T
);
3755 glDisable(GL_TEXTURE_GEN_R
);
3756 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R)");
3759 case D3DTSS_TCI_CAMERASPACEPOSITION
:
3760 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3761 as the input texture coordinates for this stage's texture transformation. This
3762 equates roughly to EYE_LINEAR */
3764 float s_plane
[] = { 1.0, 0.0, 0.0, 0.0 };
3765 float t_plane
[] = { 0.0, 1.0, 0.0, 0.0 };
3766 float r_plane
[] = { 0.0, 0.0, 1.0, 0.0 };
3767 float q_plane
[] = { 0.0, 0.0, 0.0, 1.0 };
3768 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3770 glMatrixMode(GL_MODELVIEW
);
3773 glTexGenfv(GL_S
, GL_EYE_PLANE
, s_plane
);
3774 glTexGenfv(GL_T
, GL_EYE_PLANE
, t_plane
);
3775 glTexGenfv(GL_R
, GL_EYE_PLANE
, r_plane
);
3776 glTexGenfv(GL_Q
, GL_EYE_PLANE
, q_plane
);
3779 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
3780 glEnable(GL_TEXTURE_GEN_S
);
3781 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3782 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
3783 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3784 glEnable(GL_TEXTURE_GEN_T
);
3785 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3786 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
3787 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3788 glEnable(GL_TEXTURE_GEN_R
);
3789 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3790 glTexGeni(GL_R
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
3791 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3795 case D3DTSS_TCI_CAMERASPACENORMAL
:
3797 if (GL_SUPPORT(NV_TEXGEN_REFLECTION
)) {
3798 float s_plane
[] = { 1.0, 0.0, 0.0, 0.0 };
3799 float t_plane
[] = { 0.0, 1.0, 0.0, 0.0 };
3800 float r_plane
[] = { 0.0, 0.0, 1.0, 0.0 };
3801 float q_plane
[] = { 0.0, 0.0, 0.0, 1.0 };
3802 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3804 glMatrixMode(GL_MODELVIEW
);
3807 glTexGenfv(GL_S
, GL_EYE_PLANE
, s_plane
);
3808 glTexGenfv(GL_T
, GL_EYE_PLANE
, t_plane
);
3809 glTexGenfv(GL_R
, GL_EYE_PLANE
, r_plane
);
3810 glTexGenfv(GL_Q
, GL_EYE_PLANE
, q_plane
);
3813 glEnable(GL_TEXTURE_GEN_S
);
3814 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3815 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_NORMAL_MAP_NV
);
3816 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3817 glEnable(GL_TEXTURE_GEN_T
);
3818 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3819 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_NORMAL_MAP_NV
);
3820 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3821 glEnable(GL_TEXTURE_GEN_R
);
3822 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3823 glTexGeni(GL_R
, GL_TEXTURE_GEN_MODE
, GL_NORMAL_MAP_NV
);
3824 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3829 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
:
3831 if (GL_SUPPORT(NV_TEXGEN_REFLECTION
)) {
3832 float s_plane
[] = { 1.0, 0.0, 0.0, 0.0 };
3833 float t_plane
[] = { 0.0, 1.0, 0.0, 0.0 };
3834 float r_plane
[] = { 0.0, 0.0, 1.0, 0.0 };
3835 float q_plane
[] = { 0.0, 0.0, 0.0, 1.0 };
3836 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3838 glMatrixMode(GL_MODELVIEW
);
3841 glTexGenfv(GL_S
, GL_EYE_PLANE
, s_plane
);
3842 glTexGenfv(GL_T
, GL_EYE_PLANE
, t_plane
);
3843 glTexGenfv(GL_R
, GL_EYE_PLANE
, r_plane
);
3844 glTexGenfv(GL_Q
, GL_EYE_PLANE
, q_plane
);
3847 glEnable(GL_TEXTURE_GEN_S
);
3848 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3849 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_REFLECTION_MAP_NV
);
3850 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3851 glEnable(GL_TEXTURE_GEN_T
);
3852 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3853 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_REFLECTION_MAP_NV
);
3854 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3855 glEnable(GL_TEXTURE_GEN_R
);
3856 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3857 glTexGeni(GL_R
, GL_TEXTURE_GEN_MODE
, GL_REFLECTION_MAP_NV
);
3858 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3863 /* Unhandled types: */
3866 /* ? disable GL_TEXTURE_GEN_n ? */
3867 glDisable(GL_TEXTURE_GEN_S
);
3868 glDisable(GL_TEXTURE_GEN_T
);
3869 glDisable(GL_TEXTURE_GEN_R
);
3870 FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value
);
3877 case D3DTSS_TEXTURETRANSFORMFLAGS
:
3878 set_texture_matrix((float *)&This
->StateBlock
->transforms
[D3DTS_TEXTURE0
+ Stage
].u
.m
[0][0], Value
);
3881 case D3DTSS_BUMPENVMAT00
:
3882 case D3DTSS_BUMPENVMAT01
:
3883 TRACE("BUMPENVMAT0%u Stage=%ld, Type=%d, Value =%ld\n", Type
- D3DTSS_BUMPENVMAT00
, Stage
, Type
, Value
);
3885 case D3DTSS_BUMPENVMAT10
:
3886 case D3DTSS_BUMPENVMAT11
:
3887 TRACE("BUMPENVMAT1%u Stage=%ld, Type=%d, Value =%ld\n", Type
- D3DTSS_BUMPENVMAT10
, Stage
, Type
, Value
);
3890 case D3DTSS_BUMPENVLSCALE
:
3891 TRACE("BUMPENVLSCALE Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3894 case D3DTSS_BUMPENVLOFFSET
:
3895 TRACE("BUMPENVLOFFSET Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3898 case D3DTSS_RESULTARG
:
3899 TRACE("RESULTARG Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3903 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3904 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage
, Type
, Value
);
3911 HRESULT WINAPI
IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface
, DWORD
* pNumPasses
) {
3912 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3913 TRACE("(%p) : stub\n", This
); /* FIXME: Needs doing, but called often and is harmless */
3916 HRESULT WINAPI
IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface
, DWORD DevInfoID
, void* pDevInfoStruct
, DWORD DevInfoStructSize
) {
3917 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3918 FIXME("(%p) : stub\n", This
);
3921 HRESULT WINAPI
IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface
, UINT PaletteNumber
, CONST PALETTEENTRY
* pEntries
) {
3922 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3923 FIXME("(%p) : setting p[%u] <= RGBA(%02x,%02x,%02x,%02x)\n", This
, PaletteNumber
,
3924 pEntries
->peRed
, pEntries
->peGreen
, pEntries
->peBlue
, pEntries
->peFlags
);
3925 if (PaletteNumber
>= MAX_PALETTES
) {
3926 return D3DERR_INVALIDCALL
;
3928 memcpy(This
->palettes
[PaletteNumber
], pEntries
, 256 * sizeof(PALETTEENTRY
));
3931 HRESULT WINAPI
IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface
, UINT PaletteNumber
, PALETTEENTRY
* pEntries
) {
3932 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3933 if (PaletteNumber
>= MAX_PALETTES
) {
3934 return D3DERR_INVALIDCALL
;
3936 memcpy(pEntries
, This
->palettes
[PaletteNumber
], 256 * sizeof(PALETTEENTRY
));
3937 FIXME("(%p) : returning p[%u] => RGBA(%02x,%02x,%02x,%02x)\n", This
, PaletteNumber
,
3938 pEntries
->peRed
, pEntries
->peGreen
, pEntries
->peBlue
, pEntries
->peFlags
);
3941 HRESULT WINAPI
IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface
, UINT PaletteNumber
) {
3942 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3943 FIXME("(%p) : Setting to (%u)\n", This
, PaletteNumber
);
3944 if (PaletteNumber
>= MAX_PALETTES
) {
3945 return D3DERR_INVALIDCALL
;
3947 This
->currentPalette
= PaletteNumber
;
3949 #if defined(GL_EXT_paletted_texture)
3950 if (GL_SUPPORT(EXT_PALETTED_TEXTURE
)) {
3954 GL_EXTCALL(glColorTableEXT
)(GL_TEXTURE_2D
, /* target */
3955 GL_RGBA
, /* internal format */
3956 256, /* table size */
3957 GL_RGBA
, /* table format */
3958 GL_UNSIGNED_BYTE
, /* table type */
3959 This
->palettes
[PaletteNumber
]);
3960 checkGLcall("glColorTableEXT");
3965 /* Delayed palette handling ... waiting for software emulation into preload code */
3970 HRESULT WINAPI
IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface
, UINT
*PaletteNumber
) {
3971 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3972 *PaletteNumber
= This
->currentPalette
;
3973 FIXME("(%p) : Returning (%u)\n", This
, *PaletteNumber
);
3976 HRESULT WINAPI
IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
, UINT StartVertex
, UINT PrimitiveCount
) {
3978 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3979 This
->StateBlock
->streamIsUP
= FALSE
;
3981 TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This
, PrimitiveType
, debug_d3dprimitivetype(PrimitiveType
), StartVertex
, PrimitiveCount
);
3982 drawPrimitive(iface
, PrimitiveType
, PrimitiveCount
, StartVertex
, -1, 0, NULL
, 0);
3986 HRESULT WINAPI
IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
,
3987 UINT minIndex
,UINT NumVertices
,UINT startIndex
,UINT primCount
) {
3989 IDirect3DIndexBuffer8
*pIB
;
3990 D3DINDEXBUFFER_DESC IdxBufDsc
;
3992 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
3993 pIB
= This
->StateBlock
->pIndexData
;
3994 This
->StateBlock
->streamIsUP
= FALSE
;
3996 TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d\n", This
,
3997 PrimitiveType
, debug_d3dprimitivetype(PrimitiveType
),
3998 minIndex
, NumVertices
, startIndex
, primCount
);
4000 IDirect3DIndexBuffer8Impl_GetDesc(pIB
, &IdxBufDsc
);
4001 if (IdxBufDsc
.Format
== D3DFMT_INDEX16
) {
4007 drawPrimitive(iface
, PrimitiveType
, primCount
, This
->StateBlock
->baseVertexIndex
, startIndex
, idxStride
, ((IDirect3DIndexBuffer8Impl
*) pIB
)->allocatedMemory
,
4012 HRESULT WINAPI
IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
,UINT PrimitiveCount
,CONST
void* pVertexStreamZeroData
,UINT VertexStreamZeroStride
) {
4013 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4015 TRACE("(%p) : Type=(%d,%s), pCount=%d, pVtxData=%p, Stride=%d\n", This
, PrimitiveType
, debug_d3dprimitivetype(PrimitiveType
),
4016 PrimitiveCount
, pVertexStreamZeroData
, VertexStreamZeroStride
);
4018 if (This
->StateBlock
->stream_source
[0] != NULL
) IDirect3DVertexBuffer8Impl_Release(This
->StateBlock
->stream_source
[0]);
4020 /* Note in the following, its not this type, but thats the purpose of streamIsUP */
4021 This
->StateBlock
->stream_source
[0] = (IDirect3DVertexBuffer8
*)pVertexStreamZeroData
;
4022 This
->StateBlock
->stream_stride
[0] = VertexStreamZeroStride
;
4023 This
->StateBlock
->streamIsUP
= TRUE
;
4024 drawPrimitive(iface
, PrimitiveType
, PrimitiveCount
, 0, 0, 0, NULL
, 0);
4025 This
->StateBlock
->stream_stride
[0] = 0;
4026 This
->StateBlock
->stream_source
[0] = NULL
;
4028 /*stream zero settings set to null at end */
4031 HRESULT WINAPI
IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface
, D3DPRIMITIVETYPE PrimitiveType
,UINT MinVertexIndex
,
4032 UINT NumVertexIndices
,UINT PrimitiveCount
,CONST
void* pIndexData
,
4033 D3DFORMAT IndexDataFormat
,CONST
void* pVertexStreamZeroData
,
4034 UINT VertexStreamZeroStride
) {
4036 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4037 TRACE("(%p) : Type=(%d,%s), MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This
, PrimitiveType
, debug_d3dprimitivetype(PrimitiveType
),
4038 MinVertexIndex
, NumVertexIndices
, PrimitiveCount
, pIndexData
, IndexDataFormat
, pVertexStreamZeroData
, VertexStreamZeroStride
);
4040 if (This
->StateBlock
->stream_source
[0] != NULL
) IDirect3DVertexBuffer8Impl_Release(This
->StateBlock
->stream_source
[0]);
4041 if (IndexDataFormat
== D3DFMT_INDEX16
) {
4047 /* Note in the following, its not this type, but thats the purpose of streamIsUP */
4048 This
->StateBlock
->stream_source
[0] = (IDirect3DVertexBuffer8
*)pVertexStreamZeroData
;
4049 This
->StateBlock
->streamIsUP
= TRUE
;
4050 This
->StateBlock
->stream_stride
[0] = VertexStreamZeroStride
;
4051 drawPrimitive(iface
, PrimitiveType
, PrimitiveCount
, This
->StateBlock
->baseVertexIndex
, 0, idxStride
, pIndexData
, MinVertexIndex
);
4053 /*stream zero settings set to null at end */
4054 This
->StateBlock
->stream_source
[0] = NULL
;
4055 This
->StateBlock
->stream_stride
[0] = 0;
4056 IDirect3DDevice8Impl_SetIndices(iface
, NULL
, 0);
4060 HRESULT WINAPI
IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface
, UINT SrcStartIndex
,UINT DestIndex
,UINT VertexCount
,IDirect3DVertexBuffer8
* pDestBuffer
,DWORD Flags
) {
4061 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4062 FIXME("(%p) : stub\n", This
); return D3D_OK
;
4064 HRESULT WINAPI
IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface
, CONST DWORD
* pDeclaration
, CONST DWORD
* pFunction
, DWORD
* pHandle
, DWORD Usage
) {
4065 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4066 IDirect3DVertexShaderImpl
* object
;
4067 IDirect3DVertexShaderDeclarationImpl
* attached_decl
;
4071 TRACE_(d3d_shader
)("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p, Usage=%lu\n", This
, pDeclaration
, pFunction
, Usage
);
4072 if (NULL
== pDeclaration
|| NULL
== pHandle
) { /* pFunction can be NULL see MSDN */
4073 return D3DERR_INVALIDCALL
;
4075 for (i
= 1; NULL
!= VertexShaders
[i
] && i
< sizeof(VertexShaders
) / sizeof(IDirect3DVertexShaderImpl
*); ++i
) ;
4076 if (i
>= sizeof(VertexShaders
) / sizeof(IDirect3DVertexShaderImpl
*)) {
4077 return D3DERR_OUTOFVIDEOMEMORY
;
4080 /** Create the Vertex Shader */
4081 res
= IDirect3DDeviceImpl_CreateVertexShader(This
, pFunction
, Usage
, &object
);
4082 /** TODO: check FAILED(res) */
4084 /** Create and Bind the Vertex Shader Declaration */
4085 res
= IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This
, pDeclaration
, &attached_decl
);
4086 /** TODO: check FAILED(res) */
4088 VertexShaders
[i
] = object
;
4089 VertexShaderDeclarations
[i
] = attached_decl
;
4090 *pHandle
= VS_HIGHESTFIXEDFXF
+ i
;
4091 TRACE("Finished creating vertex shader %lx\n", *pHandle
);
4095 HRESULT WINAPI
IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
4096 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4098 This
->UpdateStateBlock
->VertexShader
= Handle
;
4099 This
->UpdateStateBlock
->Changed
.vertexShader
= TRUE
;
4100 This
->UpdateStateBlock
->Set
.vertexShader
= TRUE
;
4102 if (Handle
> VS_HIGHESTFIXEDFXF
) { /* only valid with non FVF shaders */
4103 TRACE_(d3d_shader
)("(%p) : Created shader, Handle=%lx\n", This
, Handle
);
4104 This
->UpdateStateBlock
->vertexShaderDecl
= VERTEX_SHADER_DECL(Handle
);
4105 This
->UpdateStateBlock
->Changed
.vertexShaderDecl
= TRUE
;
4106 This
->UpdateStateBlock
->Set
.vertexShaderDecl
= TRUE
;
4107 } else { /* use a fvf, so desactivate the vshader decl */
4108 TRACE("(%p) : FVF Shader, Handle=%lx\n", This
, Handle
);
4109 This
->UpdateStateBlock
->vertexShaderDecl
= NULL
;
4110 This
->UpdateStateBlock
->Changed
.vertexShaderDecl
= TRUE
;
4111 This
->UpdateStateBlock
->Set
.vertexShaderDecl
= TRUE
;
4113 /* Handle recording of state blocks */
4114 if (This
->isRecordingState
) {
4115 TRACE("Recording... not performing anything\n");
4119 * TODO: merge HAL shaders context switching from prototype
4123 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface
, DWORD
* pHandle
) {
4124 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4125 TRACE_(d3d_shader
)("(%p) : GetVertexShader returning %ld\n", This
, This
->StateBlock
->VertexShader
);
4126 *pHandle
= This
->StateBlock
->VertexShader
;
4130 HRESULT WINAPI
IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
4131 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4132 IDirect3DVertexShaderImpl
* object
;
4133 IDirect3DVertexShaderDeclarationImpl
* attached_decl
;
4135 if (Handle
<= VS_HIGHESTFIXEDFXF
) { /* only delete user defined shaders */
4136 return D3DERR_INVALIDCALL
;
4140 * Delete Vertex Shader
4142 object
= VertexShaders
[Handle
- VS_HIGHESTFIXEDFXF
];
4143 if (NULL
== object
) {
4144 return D3DERR_INVALIDCALL
;
4146 TRACE_(d3d_shader
)("(%p) : freing VertexShader %p\n", This
, object
);
4147 /* TODO: check validity of object */
4148 HeapFree(GetProcessHeap(), 0, (void *)object
->function
);
4149 if (object
->prgId
!= 0) {
4150 GL_EXTCALL(glDeleteProgramsARB( 1, &object
->prgId
));
4152 HeapFree(GetProcessHeap(), 0, (void *)object
->data
);
4153 HeapFree(GetProcessHeap(), 0, (void *)object
);
4154 VertexShaders
[Handle
- VS_HIGHESTFIXEDFXF
] = NULL
;
4157 * Delete Vertex Shader Declaration
4159 attached_decl
= VertexShaderDeclarations
[Handle
- VS_HIGHESTFIXEDFXF
];
4160 if (NULL
== attached_decl
) {
4161 return D3DERR_INVALIDCALL
;
4163 TRACE_(d3d_shader
)("(%p) : freing VertexShaderDeclaration %p\n", This
, attached_decl
);
4164 /* TODO: check validity of object */
4165 HeapFree(GetProcessHeap(), 0, (void *)attached_decl
->pDeclaration8
);
4166 HeapFree(GetProcessHeap(), 0, (void *)attached_decl
);
4167 VertexShaderDeclarations
[Handle
- VS_HIGHESTFIXEDFXF
] = NULL
;
4172 HRESULT WINAPI
IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
, CONST
void* pConstantData
, DWORD ConstantCount
) {
4173 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4175 if (Register
+ ConstantCount
> D3D8_VSHADER_MAX_CONSTANTS
) {
4176 ERR_(d3d_shader
)("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This
, Register
);
4177 return D3DERR_INVALIDCALL
;
4179 if (NULL
== pConstantData
) {
4180 return D3DERR_INVALIDCALL
;
4182 if (ConstantCount
> 1) {
4183 const FLOAT
* f
= (const FLOAT
*)pConstantData
;
4185 TRACE_(d3d_shader
)("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This
, Register
, Register
+ ConstantCount
- 1);
4186 for (i
= 0; i
< ConstantCount
; ++i
) {
4187 TRACE_(d3d_shader
)("{%f, %f, %f, %f}\n", f
[0], f
[1], f
[2], f
[3]);
4191 const FLOAT
* f
= (const FLOAT
*) pConstantData
;
4192 TRACE_(d3d_shader
)("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This
, Register
, f
[0], f
[1], f
[2], f
[3]);
4194 This
->UpdateStateBlock
->Changed
.vertexShaderConstant
= TRUE
;
4195 memcpy(&This
->UpdateStateBlock
->vertexShaderConstant
[Register
], pConstantData
, ConstantCount
* 4 * sizeof(FLOAT
));
4198 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
, void* pConstantData
, DWORD ConstantCount
) {
4199 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4201 TRACE_(d3d_shader
)("(%p) : C[%lu] count=%ld\n", This
, Register
, ConstantCount
);
4202 if (Register
+ ConstantCount
> D3D8_VSHADER_MAX_CONSTANTS
) {
4203 return D3DERR_INVALIDCALL
;
4205 if (NULL
== pConstantData
) {
4206 return D3DERR_INVALIDCALL
;
4208 memcpy(pConstantData
, &This
->UpdateStateBlock
->vertexShaderConstant
[Register
], ConstantCount
* 4 * sizeof(FLOAT
));
4211 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface
, DWORD Handle
, void* pData
, DWORD
* pSizeOfData
) {
4212 /*IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;*/
4213 IDirect3DVertexShaderDeclarationImpl
* attached_decl
;
4215 attached_decl
= VERTEX_SHADER_DECL(Handle
);
4216 if (NULL
== attached_decl
) {
4217 return D3DERR_INVALIDCALL
;
4219 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl
, pData
, (UINT
*) pSizeOfData
);
4221 HRESULT WINAPI
IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface
, DWORD Handle
, void* pData
, DWORD
* pSizeOfData
) {
4222 /*IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;*/
4223 IDirect3DVertexShaderImpl
* object
;
4225 object
= VERTEX_SHADER(Handle
);
4226 if (NULL
== object
) {
4227 return D3DERR_INVALIDCALL
;
4229 return IDirect3DVertexShaderImpl_GetFunction(object
, pData
, (UINT
*) pSizeOfData
);
4232 HRESULT WINAPI
IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface
, IDirect3DIndexBuffer8
* pIndexData
, UINT BaseVertexIndex
) {
4233 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4234 IDirect3DIndexBuffer8
*oldIdxs
;
4236 TRACE("(%p) : Setting to %p, base %d\n", This
, pIndexData
, BaseVertexIndex
);
4237 oldIdxs
= This
->StateBlock
->pIndexData
;
4239 This
->UpdateStateBlock
->Changed
.Indices
= TRUE
;
4240 This
->UpdateStateBlock
->Set
.Indices
= TRUE
;
4241 This
->UpdateStateBlock
->pIndexData
= pIndexData
;
4242 This
->UpdateStateBlock
->baseVertexIndex
= BaseVertexIndex
;
4244 /* Handle recording of state blocks */
4245 if (This
->isRecordingState
) {
4246 TRACE("Recording... not performing anything\n");
4250 if (pIndexData
) IDirect3DIndexBuffer8Impl_AddRefInt(This
->StateBlock
->pIndexData
);
4251 if (oldIdxs
) IDirect3DIndexBuffer8Impl_ReleaseInt(oldIdxs
);
4254 HRESULT WINAPI
IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface
, IDirect3DIndexBuffer8
** ppIndexData
,UINT
* pBaseVertexIndex
) {
4255 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4256 FIXME("(%p) : stub\n", This
);
4258 *ppIndexData
= This
->StateBlock
->pIndexData
;
4259 /* up ref count on ppindexdata */
4260 if (*ppIndexData
) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData
);
4261 *pBaseVertexIndex
= This
->StateBlock
->baseVertexIndex
;
4265 HRESULT WINAPI
IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface
, CONST DWORD
* pFunction
, DWORD
* pHandle
) {
4266 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4267 IDirect3DPixelShaderImpl
* object
;
4271 TRACE_(d3d_shader
)("(%p) : PixelShader not fully supported yet : Func=%p\n", This
, pFunction
);
4272 if (NULL
== pFunction
|| NULL
== pHandle
) {
4273 return D3DERR_INVALIDCALL
;
4275 for (i
= 1; NULL
!= PixelShaders
[i
] && i
< sizeof(PixelShaders
) / sizeof(IDirect3DPixelShaderImpl
*); ++i
) ;
4276 if (i
>= sizeof(PixelShaders
) / sizeof(IDirect3DPixelShaderImpl
*)) {
4277 return D3DERR_OUTOFVIDEOMEMORY
;
4280 /** Create the Pixel Shader */
4281 res
= IDirect3DDeviceImpl_CreatePixelShader(This
, pFunction
, &object
);
4282 if (SUCCEEDED(res
)) {
4283 PixelShaders
[i
] = object
;
4284 *pHandle
= VS_HIGHESTFIXEDFXF
+ i
;
4287 *pHandle
= 0xFFFFFFFF;
4291 HRESULT WINAPI
IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
4292 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4294 This
->UpdateStateBlock
->PixelShader
= Handle
;
4295 This
->UpdateStateBlock
->Changed
.pixelShader
= TRUE
;
4296 This
->UpdateStateBlock
->Set
.pixelShader
= TRUE
;
4298 /* Handle recording of state blocks */
4299 if (This
->isRecordingState
) {
4300 TRACE_(d3d_shader
)("Recording... not performing anything\n");
4305 TRACE_(d3d_shader
)("(%p) : Set pixel shader with handle %lx\n", This
, Handle
);
4307 TRACE_(d3d_shader
)("(%p) : Remove pixel shader\n", This
);
4313 HRESULT WINAPI
IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface
, DWORD
* pHandle
) {
4314 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4315 TRACE_(d3d_shader
)("(%p) : GetPixelShader returning %ld\n", This
, This
->StateBlock
->PixelShader
);
4316 *pHandle
= This
->StateBlock
->PixelShader
;
4320 HRESULT WINAPI
IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface
, DWORD Handle
) {
4321 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4322 IDirect3DPixelShaderImpl
* object
;
4324 if (Handle
<= VS_HIGHESTFIXEDFXF
) { /* only delete user defined shaders */
4325 return D3DERR_INVALIDCALL
;
4327 object
= PixelShaders
[Handle
- VS_HIGHESTFIXEDFXF
];
4328 if (NULL
== object
) {
4329 return D3DERR_INVALIDCALL
;
4331 TRACE_(d3d_shader
)("(%p) : freeing PixelShader %p\n", This
, object
);
4332 /* TODO: check validity of object before free */
4333 HeapFree(GetProcessHeap(), 0, (void *)object
->function
);
4334 if (object
->prgId
!= 0) {
4335 GL_EXTCALL(glDeleteProgramsARB( 1, &object
->prgId
));
4337 HeapFree(GetProcessHeap(), 0, (void *)object
->data
);
4338 HeapFree(GetProcessHeap(), 0, (void *)object
);
4339 PixelShaders
[Handle
- VS_HIGHESTFIXEDFXF
] = NULL
;
4344 HRESULT WINAPI
IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
, CONST
void* pConstantData
, DWORD ConstantCount
) {
4345 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4347 if (Register
+ ConstantCount
> D3D8_PSHADER_MAX_CONSTANTS
) {
4348 ERR_(d3d_shader
)("(%p) : SetPixelShaderConstant C[%lu] invalid\n", This
, Register
);
4349 return D3DERR_INVALIDCALL
;
4351 if (NULL
== pConstantData
) {
4352 return D3DERR_INVALIDCALL
;
4354 if (ConstantCount
> 1) {
4355 const FLOAT
* f
= (const FLOAT
*)pConstantData
;
4357 TRACE_(d3d_shader
)("(%p) : SetPixelShaderConstant C[%lu..%lu]=\n", This
, Register
, Register
+ ConstantCount
- 1);
4358 for (i
= 0; i
< ConstantCount
; ++i
) {
4359 TRACE_(d3d_shader
)("{%f, %f, %f, %f}\n", f
[0], f
[1], f
[2], f
[3]);
4363 const FLOAT
* f
= (const FLOAT
*) pConstantData
;
4364 TRACE_(d3d_shader
)("(%p) : SetPixelShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This
, Register
, f
[0], f
[1], f
[2], f
[3]);
4366 This
->UpdateStateBlock
->Changed
.pixelShaderConstant
= TRUE
;
4367 memcpy(&This
->UpdateStateBlock
->pixelShaderConstant
[Register
], pConstantData
, ConstantCount
* 4 * sizeof(FLOAT
));
4370 HRESULT WINAPI
IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface
, DWORD Register
, void* pConstantData
, DWORD ConstantCount
) {
4371 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4373 TRACE_(d3d_shader
)("(%p) : C[%lu] count=%ld\n", This
, Register
, ConstantCount
);
4374 if (Register
+ ConstantCount
> D3D8_PSHADER_MAX_CONSTANTS
) {
4375 return D3DERR_INVALIDCALL
;
4377 if (NULL
== pConstantData
) {
4378 return D3DERR_INVALIDCALL
;
4380 memcpy(pConstantData
, &This
->UpdateStateBlock
->pixelShaderConstant
[Register
], ConstantCount
* 4 * sizeof(FLOAT
));
4383 HRESULT WINAPI
IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface
, DWORD Handle
, void* pData
, DWORD
* pSizeOfData
) {
4384 IDirect3DPixelShaderImpl
* object
;
4386 object
= PIXEL_SHADER(Handle
);
4387 if (NULL
== object
) {
4388 return D3DERR_INVALIDCALL
;
4390 return IDirect3DPixelShaderImpl_GetFunction(object
, pData
, (UINT
*) pSizeOfData
);
4392 HRESULT WINAPI
IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface
, UINT Handle
,CONST
float* pNumSegs
,CONST D3DRECTPATCH_INFO
* pRectPatchInfo
) {
4393 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4394 FIXME("(%p) : stub\n", This
); return D3D_OK
;
4396 HRESULT WINAPI
IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface
, UINT Handle
,CONST
float* pNumSegs
,CONST D3DTRIPATCH_INFO
* pTriPatchInfo
) {
4397 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4398 FIXME("(%p) : stub\n", This
); return D3D_OK
;
4400 HRESULT WINAPI
IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface
, UINT Handle
) {
4401 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4402 FIXME("(%p) : stub\n", This
); return D3D_OK
;
4405 HRESULT WINAPI
IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface
, UINT StreamNumber
,IDirect3DVertexBuffer8
* pStreamData
,UINT Stride
) {
4406 IDirect3DVertexBuffer8
*oldSrc
;
4407 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4409 oldSrc
= This
->StateBlock
->stream_source
[StreamNumber
];
4410 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This
, StreamNumber
, oldSrc
, pStreamData
, Stride
);
4412 This
->UpdateStateBlock
->Changed
.stream_source
[StreamNumber
] = TRUE
;
4413 This
->UpdateStateBlock
->Set
.stream_source
[StreamNumber
] = TRUE
;
4414 This
->UpdateStateBlock
->stream_stride
[StreamNumber
] = Stride
;
4415 This
->UpdateStateBlock
->stream_source
[StreamNumber
] = pStreamData
;
4417 /* Handle recording of state blocks */
4418 if (This
->isRecordingState
) {
4419 TRACE("Recording... not performing anything\n");
4423 if (pStreamData
!= NULL
) IDirect3DVertexBuffer8Impl_AddRefInt(pStreamData
);
4424 if (oldSrc
!= NULL
) IDirect3DVertexBuffer8Impl_ReleaseInt(oldSrc
);
4427 HRESULT WINAPI
IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface
, UINT StreamNumber
,IDirect3DVertexBuffer8
** pStream
,UINT
* pStride
) {
4428 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4429 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This
, StreamNumber
, This
->StateBlock
->stream_source
[StreamNumber
], This
->StateBlock
->stream_stride
[StreamNumber
]);
4430 *pStream
= This
->StateBlock
->stream_source
[StreamNumber
];
4431 *pStride
= This
->StateBlock
->stream_stride
[StreamNumber
];
4432 if (*pStream
!= NULL
) IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8
) *pStream
);
4437 const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl
=
4439 IDirect3DDevice8Impl_QueryInterface
,
4440 IDirect3DDevice8Impl_AddRef
,
4441 IDirect3DDevice8Impl_Release
,
4442 IDirect3DDevice8Impl_TestCooperativeLevel
,
4443 IDirect3DDevice8Impl_GetAvailableTextureMem
,
4444 IDirect3DDevice8Impl_ResourceManagerDiscardBytes
,
4445 IDirect3DDevice8Impl_GetDirect3D
,
4446 IDirect3DDevice8Impl_GetDeviceCaps
,
4447 IDirect3DDevice8Impl_GetDisplayMode
,
4448 IDirect3DDevice8Impl_GetCreationParameters
,
4449 IDirect3DDevice8Impl_SetCursorProperties
,
4450 IDirect3DDevice8Impl_SetCursorPosition
,
4451 IDirect3DDevice8Impl_ShowCursor
,
4452 IDirect3DDevice8Impl_CreateAdditionalSwapChain
,
4453 IDirect3DDevice8Impl_Reset
,
4454 IDirect3DDevice8Impl_Present
,
4455 IDirect3DDevice8Impl_GetBackBuffer
,
4456 IDirect3DDevice8Impl_GetRasterStatus
,
4457 IDirect3DDevice8Impl_SetGammaRamp
,
4458 IDirect3DDevice8Impl_GetGammaRamp
,
4459 IDirect3DDevice8Impl_CreateTexture
,
4460 IDirect3DDevice8Impl_CreateVolumeTexture
,
4461 IDirect3DDevice8Impl_CreateCubeTexture
,
4462 IDirect3DDevice8Impl_CreateVertexBuffer
,
4463 IDirect3DDevice8Impl_CreateIndexBuffer
,
4464 IDirect3DDevice8Impl_CreateRenderTarget
,
4465 IDirect3DDevice8Impl_CreateDepthStencilSurface
,
4466 IDirect3DDevice8Impl_CreateImageSurface
,
4467 IDirect3DDevice8Impl_CopyRects
,
4468 IDirect3DDevice8Impl_UpdateTexture
,
4469 IDirect3DDevice8Impl_GetFrontBuffer
,
4470 IDirect3DDevice8Impl_SetRenderTarget
,
4471 IDirect3DDevice8Impl_GetRenderTarget
,
4472 IDirect3DDevice8Impl_GetDepthStencilSurface
,
4473 IDirect3DDevice8Impl_BeginScene
,
4474 IDirect3DDevice8Impl_EndScene
,
4475 IDirect3DDevice8Impl_Clear
,
4476 IDirect3DDevice8Impl_SetTransform
,
4477 IDirect3DDevice8Impl_GetTransform
,
4478 IDirect3DDevice8Impl_MultiplyTransform
,
4479 IDirect3DDevice8Impl_SetViewport
,
4480 IDirect3DDevice8Impl_GetViewport
,
4481 IDirect3DDevice8Impl_SetMaterial
,
4482 IDirect3DDevice8Impl_GetMaterial
,
4483 IDirect3DDevice8Impl_SetLight
,
4484 IDirect3DDevice8Impl_GetLight
,
4485 IDirect3DDevice8Impl_LightEnable
,
4486 IDirect3DDevice8Impl_GetLightEnable
,
4487 IDirect3DDevice8Impl_SetClipPlane
,
4488 IDirect3DDevice8Impl_GetClipPlane
,
4489 IDirect3DDevice8Impl_SetRenderState
,
4490 IDirect3DDevice8Impl_GetRenderState
,
4491 IDirect3DDevice8Impl_BeginStateBlock
,
4492 IDirect3DDevice8Impl_EndStateBlock
,
4493 IDirect3DDevice8Impl_ApplyStateBlock
,
4494 IDirect3DDevice8Impl_CaptureStateBlock
,
4495 IDirect3DDevice8Impl_DeleteStateBlock
,
4496 IDirect3DDevice8Impl_CreateStateBlock
,
4497 IDirect3DDevice8Impl_SetClipStatus
,
4498 IDirect3DDevice8Impl_GetClipStatus
,
4499 IDirect3DDevice8Impl_GetTexture
,
4500 IDirect3DDevice8Impl_SetTexture
,
4501 IDirect3DDevice8Impl_GetTextureStageState
,
4502 IDirect3DDevice8Impl_SetTextureStageState
,
4503 IDirect3DDevice8Impl_ValidateDevice
,
4504 IDirect3DDevice8Impl_GetInfo
,
4505 IDirect3DDevice8Impl_SetPaletteEntries
,
4506 IDirect3DDevice8Impl_GetPaletteEntries
,
4507 IDirect3DDevice8Impl_SetCurrentTexturePalette
,
4508 IDirect3DDevice8Impl_GetCurrentTexturePalette
,
4509 IDirect3DDevice8Impl_DrawPrimitive
,
4510 IDirect3DDevice8Impl_DrawIndexedPrimitive
,
4511 IDirect3DDevice8Impl_DrawPrimitiveUP
,
4512 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP
,
4513 IDirect3DDevice8Impl_ProcessVertices
,
4514 IDirect3DDevice8Impl_CreateVertexShader
,
4515 IDirect3DDevice8Impl_SetVertexShader
,
4516 IDirect3DDevice8Impl_GetVertexShader
,
4517 IDirect3DDevice8Impl_DeleteVertexShader
,
4518 IDirect3DDevice8Impl_SetVertexShaderConstant
,
4519 IDirect3DDevice8Impl_GetVertexShaderConstant
,
4520 IDirect3DDevice8Impl_GetVertexShaderDeclaration
,
4521 IDirect3DDevice8Impl_GetVertexShaderFunction
,
4522 IDirect3DDevice8Impl_SetStreamSource
,
4523 IDirect3DDevice8Impl_GetStreamSource
,
4524 IDirect3DDevice8Impl_SetIndices
,
4525 IDirect3DDevice8Impl_GetIndices
,
4526 IDirect3DDevice8Impl_CreatePixelShader
,
4527 IDirect3DDevice8Impl_SetPixelShader
,
4528 IDirect3DDevice8Impl_GetPixelShader
,
4529 IDirect3DDevice8Impl_DeletePixelShader
,
4530 IDirect3DDevice8Impl_SetPixelShaderConstant
,
4531 IDirect3DDevice8Impl_GetPixelShaderConstant
,
4532 IDirect3DDevice8Impl_GetPixelShaderFunction
,
4533 IDirect3DDevice8Impl_DrawRectPatch
,
4534 IDirect3DDevice8Impl_DrawTriPatch
,
4535 IDirect3DDevice8Impl_DeletePatch
4538 HRESULT WINAPI
IDirect3DDevice8Impl_CleanRender(LPDIRECT3DDEVICE8 iface
)
4540 #if defined(GL_VERSION_1_3) /* @see comments on ActiveRender */
4541 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4546 if (This
->glCtx
!= This
->render_ctx
) {
4547 glXDestroyContext(This
->display
, This
->render_ctx
);
4548 This
->render_ctx
= This
->glCtx
;
4551 if (This
->win
!= This
->drawable
) {
4552 glXDestroyPbuffer(This
->display
, This
->drawable
);
4553 This
->drawable
= This
->win
;
4562 HRESULT WINAPI
IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface
,
4563 IDirect3DSurface8
* RenderSurface
,
4564 IDirect3DSurface8
* StencilSurface
) {
4566 HRESULT ret
= D3DERR_INVALIDCALL
;
4568 * Currently only active for GLX >= 1.3
4569 * for others versions we'll have to use GLXPixmaps
4571 * normally we must test GLX_VERSION_1_3 but nvidia headers are not correct
4572 * as they implements GLX 1.3 but only define GLX_VERSION_1_2
4573 * so only check OpenGL version
4575 #if defined(GL_VERSION_1_3)
4576 GLXFBConfig
* cfgs
= NULL
;
4580 D3DFORMAT BackBufferFormat
= ((IDirect3DSurface8Impl
*) RenderSurface
)->myDesc
.Format
;
4581 D3DFORMAT StencilBufferFormat
= (NULL
!= StencilSurface
) ? ((IDirect3DSurface8Impl
*) StencilSurface
)->myDesc
.Format
: 0;
4582 UINT Width
= ((IDirect3DSurface8Impl
*) RenderSurface
)->myDesc
.Width
;
4583 UINT Height
= ((IDirect3DSurface8Impl
*) RenderSurface
)->myDesc
.Height
;
4584 IDirect3DSurface8Impl
* tmp
;
4586 IDirect3DDevice8Impl
*This
= (IDirect3DDevice8Impl
*)iface
;
4588 #define PUSH1(att) attribs[nAttribs++] = (att);
4589 #define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
4591 PUSH2(GLX_DRAWABLE_TYPE
, GLX_PBUFFER_BIT
);
4592 PUSH2(GLX_X_RENDERABLE
, TRUE
);
4593 PUSH2(GLX_DOUBLEBUFFER
, TRUE
);
4595 switch (BackBufferFormat
) {
4598 PUSH2(GLX_RENDER_TYPE
, GLX_COLOR_INDEX_BIT
);
4599 PUSH2(GLX_BUFFER_SIZE
, 8);
4600 PUSH2(GLX_DOUBLEBUFFER
, TRUE
);
4604 PUSH2(GLX_RENDER_TYPE
, GLX_RGBA_BIT
);
4605 PUSH2(GLX_RED_SIZE
, 3);
4606 PUSH2(GLX_GREEN_SIZE
, 3);
4607 PUSH2(GLX_BLUE_SIZE
, 2);
4610 case D3DFMT_A1R5G5B5
:
4611 PUSH2(GLX_ALPHA_SIZE
, 1);
4612 case D3DFMT_X1R5G5B5
:
4613 PUSH2(GLX_RED_SIZE
, 5);
4614 PUSH2(GLX_GREEN_SIZE
, 5);
4615 PUSH2(GLX_BLUE_SIZE
, 5);
4619 PUSH2(GLX_RED_SIZE
, 5);
4620 PUSH2(GLX_GREEN_SIZE
, 6);
4621 PUSH2(GLX_BLUE_SIZE
, 5);
4624 case D3DFMT_A4R4G4B4
:
4625 PUSH2(GLX_ALPHA_SIZE
, 4);
4626 case D3DFMT_X4R4G4B4
:
4627 PUSH2(GLX_RED_SIZE
, 4);
4628 PUSH2(GLX_GREEN_SIZE
, 4);
4629 PUSH2(GLX_BLUE_SIZE
, 4);
4632 case D3DFMT_A8R8G8B8
:
4633 PUSH2(GLX_ALPHA_SIZE
, 8);
4635 case D3DFMT_X8R8G8B8
:
4636 PUSH2(GLX_RED_SIZE
, 8);
4637 PUSH2(GLX_GREEN_SIZE
, 8);
4638 PUSH2(GLX_BLUE_SIZE
, 8);
4645 switch (StencilBufferFormat
) {
4646 case D3DFMT_D16_LOCKABLE
:
4648 PUSH2(GLX_DEPTH_SIZE
, 16);
4652 PUSH2(GLX_DEPTH_SIZE
, 15);
4656 PUSH2(GLX_DEPTH_SIZE
, 24);
4659 case D3DFMT_D24X4S4
:
4660 PUSH2(GLX_DEPTH_SIZE
, 24);
4661 PUSH2(GLX_STENCIL_SIZE
, 4);
4665 PUSH2(GLX_DEPTH_SIZE
, 24);
4666 PUSH2(GLX_STENCIL_SIZE
, 8);
4670 PUSH2(GLX_DEPTH_SIZE
, 24);
4681 cfgs
= glXChooseFBConfig(This
->display
, DefaultScreen(This
->display
), attribs
, &nCfgs
);
4685 for (i
= 0; i
< nCfgs
; ++i
) {
4686 TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat
, debug_d3dformat(BackBufferFormat
), StencilBufferFormat
, debug_d3dformat(StencilBufferFormat
), i
, cfgs
[i
]);
4690 if (NULL
!= This
->renderTarget
) {
4691 /*GLenum prev_read; */
4693 vcheckGLcall("glFlush");
4696 /** very very useful debug code */
4697 glXSwapBuffers(This
->display
, This
->drawable
);
4698 printf("Hit Enter to get next frame ...\n");
4703 glGetIntegerv(GL_READ_BUFFER
, &prev_read
);
4704 vcheckGLcall("glIntegerv");
4705 glReadBuffer(GL_BACK
);
4706 vcheckGLcall("glReadBuffer");
4709 long pitch
= This
->renderTarget
->myDesc
.Width
* This
->renderTarget
->bytesPerPixel
;
4711 if (This
->renderTarget
->myDesc
.Format
== D3DFMT_DXT1
) /* DXT1 is half byte per pixel */
4714 for (j
= 0; j
< This
->renderTarget
->myDesc
.Height
; ++j
) {
4716 This
->renderTarget
->myDesc
.Height
- j
- 1,
4717 This
->renderTarget
->myDesc
.Width
,
4719 D3DFmt2GLFmt(This
, This
->renderTarget
->myDesc
.Format
),
4720 D3DFmt2GLType(This
, This
->renderTarget
->myDesc
.Format
),
4721 This
->renderTarget
->allocatedMemory
+ j
* pitch
);
4722 vcheckGLcall("glReadPixels");
4725 glReadBuffer(prev_read
);
4726 vcheckGLcall("glReadBuffer");
4730 if (BackBufferFormat
!= This
->renderTarget
->myDesc
.Format
&&
4731 StencilBufferFormat
!= This
->stencilBufferTarget
->myDesc
.Format
) {
4733 PUSH2(GLX_PBUFFER_WIDTH
, Width
);
4734 PUSH2(GLX_PBUFFER_HEIGHT
, Height
);
4736 This
->drawable
= glXCreatePbuffer(This
->display
, cfgs
[0], attribs
);
4738 This
->render_ctx
= glXCreateNewContext(This
->display
, cfgs
[0], GLX_RGBA_TYPE
, This
->glCtx
, TRUE
);
4739 if (NULL
== This
->render_ctx
) {
4740 ERR("cannot create glxContext\n");
4744 glXSwapBuffers(This
->display
, This
->drawable
);
4745 if (glXMakeContextCurrent(This
->display
, This
->drawable
, This
->drawable
, This
->render_ctx
) == False
) {
4746 TRACE("Error in setting current context: context %p drawable %ld (default %ld)!\n", This
->glCtx
, This
->drawable
, This
->win
);
4748 checkGLcall("glXMakeContextCurrent");
4751 tmp
= This
->renderTarget
;
4752 This
->renderTarget
= (IDirect3DSurface8Impl
*) RenderSurface
;
4753 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) This
->renderTarget
);
4754 IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8
) tmp
);
4756 tmp
= This
->stencilBufferTarget
;
4757 This
->stencilBufferTarget
= (IDirect3DSurface8Impl
*) StencilSurface
;
4758 if (NULL
!= This
->stencilBufferTarget
) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) This
->stencilBufferTarget
);
4759 if (NULL
!= tmp
) IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8
) tmp
);
4763 /* The surface must be rendered upside down to cancel the flip produce by glCopyTexImage */
4764 This
->renderUpsideDown
= (This
->renderTarget
!= This
->frontBuffer
) && (This
->renderTarget
!= This
->backBuffer
);
4765 /* Force updating the cull mode */
4766 IDirect3DDevice8_GetRenderState(iface
, D3DRS_CULLMODE
, &value
);
4767 IDirect3DDevice8_SetRenderState(iface
, D3DRS_CULLMODE
, value
);
4768 /* Force updating projection matrix */
4769 This
->last_was_rhw
= FALSE
;
4770 This
->proj_valid
= FALSE
;
4776 ERR("cannot get valides GLXFBConfig for (%u,%s)/(%u,%s)\n", BackBufferFormat
, debug_d3dformat(BackBufferFormat
), StencilBufferFormat
, debug_d3dformat(StencilBufferFormat
));