2 * IDirect3DDevice8 implementation
4 * Copyright 2002 Jason Edmeades
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
32 #include "wine/debug.h"
34 /** define GL_GLEXT_PROTOTYPES for having extensions prototypes defined */
35 /*#define GL_GLEXT_PROTOTYPES*/
36 /*#undef GLX_GLXEXT_LEGACY*/
37 #include "d3d8_private.h"
39 /** currently desactiving 1_4 support as mesa doesn't implement all 1_4 support while defining it */
42 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
43 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
44 WINE_DECLARE_DEBUG_CHANNEL(fps);
46 IDirect3DVertexShaderImpl* VertexShaders[64];
47 IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
48 IDirect3DPixelShaderImpl* PixelShaders[64];
51 #ifdef FRAME_DEBUGGING
53 BOOL isDumpingFrames = FALSE;
58 * Utility functions or macros
60 #define conv_mat(mat,gl_mat) \
62 TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
63 TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
64 TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
65 TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
66 memcpy(gl_mat, (mat), 16 * sizeof(float)); \
69 /* Apply the current values to the specified texture stage */
70 void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage, DWORD Flags) {
71 ICOM_THIS(IDirect3DDevice8Impl,iface);
74 BOOL changeTexture = TRUE;
76 TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
77 for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
82 /* Performance: For texture states where multiples effect the outcome, only bother
83 applying the last one as it will pick up all the other values */
84 case D3DTSS_COLORARG0: /* Will be picked up when setting color op */
85 case D3DTSS_COLORARG1: /* Will be picked up when setting color op */
86 case D3DTSS_COLORARG2: /* Will be picked up when setting color op */
87 case D3DTSS_ALPHAARG0: /* Will be picked up when setting alpha op */
88 case D3DTSS_ALPHAARG1: /* Will be picked up when setting alpha op */
89 case D3DTSS_ALPHAARG2: /* Will be picked up when setting alpha op */
93 /* Performance: If the texture states only impact settings for the texture unit
94 (compared to the texture object) then there is no need to reapply them. The
95 only time they need applying is the first time, since we cheat and put the
96 values into the stateblock without applying.
97 Per-texture unit: texture function (eg. combine), ops and args
99 texture generation settings
100 Note: Due to some special conditions there may be a need to do particular ones
101 of these, which is what the Flags allows */
103 case D3DTSS_TEXCOORDINDEX:
104 if (!(Flags == REAPPLY_ALL)) skip=TRUE;
108 if (!(Flags & REAPPLY_ALPHAOP)) skip=TRUE;
116 /* Performance: Only change to this texture if we have to */
118 /* Make appropriate texture active */
119 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
120 #if defined(GL_VERSION_1_3)
121 glActiveTexture(GL_TEXTURE0 + Stage);
123 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
125 checkGLcall("glActiveTextureARB");
126 } else if (Stage > 0) {
127 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
129 changeTexture = FALSE;
132 /* Now apply the change */
133 IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
137 /* Note the D3DRS value applies to all textures, but GL has one
138 * per texture, so apply it now ready to be used!
140 D3DCOLORTOGLFLOAT4(This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR], col);
141 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
142 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
144 TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
147 /* Setup this textures matrix */
148 static void set_texture_matrix(float *smat, DWORD flags)
152 glMatrixMode(GL_TEXTURE);
154 if (flags == D3DTTFF_DISABLE) {
156 checkGLcall("glLoadIdentity()");
160 if (flags == (D3DTTFF_COUNT1|D3DTTFF_PROJECTED)) {
161 ERR("Invalid texture transform flags: D3DTTFF_COUNT1|D3DTTFF_PROJECTED\n");
162 checkGLcall("glLoadIdentity()");
166 memcpy(mat, smat, 16*sizeof(float));
168 switch (flags & ~D3DTTFF_PROJECTED) {
169 case D3DTTFF_COUNT1: mat[1] = mat[5] = mat[9] = mat[13] = 0;
170 case D3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
171 default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
174 if (flags & D3DTTFF_PROJECTED) switch (flags & ~D3DTTFF_PROJECTED) {
176 mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
177 mat[1] = mat[5] = mat[9] = mat[13] = 0;
180 mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
181 mat[2] = mat[6] = mat[10] = mat[14] = 0;
185 checkGLcall("glLoadMatrixf(mat)");
188 /* IDirect3D IUnknown parts follow: */
189 HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
191 ICOM_THIS(IDirect3DDevice8Impl,iface);
193 if (IsEqualGUID(riid, &IID_IUnknown)
194 || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
195 IDirect3DDevice8Impl_AddRef(iface);
200 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
201 return E_NOINTERFACE;
204 ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
205 ICOM_THIS(IDirect3DDevice8Impl,iface);
206 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
207 return ++(This->ref);
210 ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
211 ICOM_THIS(IDirect3DDevice8Impl,iface);
212 ULONG ref = --This->ref;
213 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
215 IDirect3DDevice8Impl_CleanRender(iface);
216 HeapFree(GetProcessHeap(), 0, This);
221 /* IDirect3DDevice Interface follow: */
222 HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
223 ICOM_THIS(IDirect3DDevice8Impl,iface);
224 TRACE("(%p) : stub\n", This); /* No way of notifying yet! */
228 UINT WINAPI IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
229 ICOM_THIS(IDirect3DDevice8Impl,iface);
230 TRACE("(%p) : stub, emulating 32Mb for now\n", This);
232 * pretend we have 32MB of any type of memory queried.
234 return (1024*1024*32);
237 HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
238 ICOM_THIS(IDirect3DDevice8Impl,iface);
239 FIXME("(%p) : stub\n", This); return D3D_OK;
241 HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
242 ICOM_THIS(IDirect3DDevice8Impl,iface);
243 TRACE("(%p) : returning %p\n", This, This->direct3d8);
246 IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
248 *ppD3D8 = (IDirect3D8 *)This->direct3d8;
251 HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
252 ICOM_THIS(IDirect3DDevice8Impl,iface);
253 FIXME("(%p) : stub, calling idirect3d for now\n", This);
254 IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
257 HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
262 ICOM_THIS(IDirect3DDevice8Impl,iface);
263 pMode->Width = GetSystemMetrics(SM_CXSCREEN);
264 pMode->Height = GetSystemMetrics(SM_CYSCREEN);
265 pMode->RefreshRate = 85; /*FIXME: How to identify? */
267 hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
268 bpp = GetDeviceCaps(hdc, BITSPIXEL);
272 case 8: pMode->Format = D3DFMT_R8G8B8; break;
273 case 16: pMode->Format = D3DFMT_R5G6B5; break;
274 case 24: /*pMode->Format = D3DFMT_R8G8B8; break; */
275 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
277 FIXME("Unrecognized display mode format\n");
278 pMode->Format = D3DFMT_UNKNOWN;
281 FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
282 pMode->Format, debug_d3dformat(pMode->Format));
285 HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
286 ICOM_THIS(IDirect3DDevice8Impl,iface);
287 TRACE("(%p) copying to %p\n", This, pParameters);
288 memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
291 HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
292 IDirect3DSurface8Impl* pSur = (IDirect3DSurface8Impl*) pCursorBitmap;
293 ICOM_THIS(IDirect3DDevice8Impl,iface);
294 TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot);
296 if (D3DFMT_A8R8G8B8 != pSur->myDesc.Format) {
297 ERR("(%p) : surface(%p) have a invalid format\n", This, pCursorBitmap);
298 return D3DERR_INVALIDCALL;
300 if (32 != pSur->myDesc.Height || 32 != pSur->myDesc.Width) {
301 ERR("(%p) : surface(%p) have a invalid size\n", This, pCursorBitmap);
302 return D3DERR_INVALIDCALL;
305 This->xHotSpot = XHotSpot;
306 This->yHotSpot = YHotSpot;
309 void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace, DWORD Flags) {
310 ICOM_THIS(IDirect3DDevice8Impl,iface);
311 TRACE("(%p) : SetPos to (%u,%u)\n", This, XScreenSpace, YScreenSpace);
312 This->xScreenSpace = XScreenSpace;
313 This->yScreenSpace = YScreenSpace;
316 BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
317 ICOM_THIS(IDirect3DDevice8Impl,iface);
318 TRACE("(%p) : visible(%d)\n", This, bShow);
319 This->bCursorVisible = bShow;
322 HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
323 IDirect3DSwapChain8Impl* object;
324 ICOM_THIS(IDirect3DDevice8Impl,iface);
325 FIXME("(%p) : stub\n", This);
327 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl));
328 if (NULL == object) {
329 return D3DERR_OUTOFVIDEOMEMORY;
331 object->lpVtbl = &Direct3DSwapChain8_Vtbl;
334 TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This,
335 pPresentationParameters->AutoDepthStencilFormat, debug_d3dformat(pPresentationParameters->AutoDepthStencilFormat),
336 pPresentationParameters->BackBufferFormat, debug_d3dformat(pPresentationParameters->BackBufferFormat));
338 if (pPresentationParameters->Windowed && ((pPresentationParameters->BackBufferWidth == 0) ||
339 (pPresentationParameters->BackBufferHeight == 0))) {
342 GetClientRect(This->win_handle, &Rect);
344 if (pPresentationParameters->BackBufferWidth == 0) {
345 pPresentationParameters->BackBufferWidth = Rect.right;
346 TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth);
348 if (pPresentationParameters->BackBufferHeight == 0) {
349 pPresentationParameters->BackBufferHeight = Rect.bottom;
350 TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight);
354 /* Save the presentation parms now filled in correctly */
355 memcpy(&object->PresentParms, pPresentationParameters, sizeof(D3DPRESENT_PARAMETERS));
357 IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
358 pPresentationParameters->BackBufferWidth,
359 pPresentationParameters->BackBufferHeight,
360 pPresentationParameters->BackBufferFormat,
361 pPresentationParameters->MultiSampleType,
363 (LPDIRECT3DSURFACE8*) &object->frontBuffer);
365 IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
366 pPresentationParameters->BackBufferWidth,
367 pPresentationParameters->BackBufferHeight,
368 pPresentationParameters->BackBufferFormat,
369 pPresentationParameters->MultiSampleType,
371 (LPDIRECT3DSURFACE8*) &object->backBuffer);
373 if (pPresentationParameters->EnableAutoDepthStencil) {
374 IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8) object,
375 pPresentationParameters->BackBufferWidth,
376 pPresentationParameters->BackBufferHeight,
377 pPresentationParameters->AutoDepthStencilFormat,
379 (LPDIRECT3DSURFACE8*) &object->depthStencilBuffer);
381 object->depthStencilBuffer = NULL;
384 *pSwapChain = (IDirect3DSwapChain8*) object;
387 HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
388 ICOM_THIS(IDirect3DDevice8Impl,iface);
389 FIXME("(%p) : stub\n", This); return D3D_OK;
391 HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
392 ICOM_THIS(IDirect3DDevice8Impl,iface);
393 TRACE("(%p) : complete stub!\n", This);
397 glXSwapBuffers(This->display, This->drawable);
398 /* Dont call checkGLcall, as glGetError is not applicable here */
399 TRACE("glXSwapBuffers called, Starting new frame\n");
404 static long prev_time, frames;
406 DWORD time = GetTickCount();
408 /* every 1.5 seconds */
409 if (time - prev_time > 1500) {
410 TRACE_(fps)("@@@ %.2ffps\n", 1000.0*frames/(time - prev_time));
416 #if defined(FRAME_DEBUGGING)
418 if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
421 FIXME("Enabling D3D Trace\n");
422 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
423 #if defined(SHOW_FRAME_MAKEUP)
424 FIXME("Singe Frame snapshots Starting\n");
425 isDumpingFrames = TRUE;
426 glClear(GL_COLOR_BUFFER_BIT);
429 #if defined(SINGLE_FRAME_DEBUGGING)
431 #if defined(SHOW_FRAME_MAKEUP)
432 FIXME("Singe Frame snapshots Finishing\n");
433 isDumpingFrames = FALSE;
435 FIXME("Singe Frame trace complete\n");
436 DeleteFileA("C:\\D3DTRACE");
437 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
443 #if defined(SHOW_FRAME_MAKEUP)
444 FIXME("Singe Frame snapshots Finishing\n");
445 isDumpingFrames = FALSE;
447 FIXME("Disabling D3D Trace\n");
448 __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
458 HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
459 ICOM_THIS(IDirect3DDevice8Impl,iface);
460 *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
461 TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
463 if (BackBuffer > This->PresentParms.BackBufferCount - 1) {
464 FIXME("Only one backBuffer currently supported\n");
465 return D3DERR_INVALIDCALL;
468 /* Note inc ref on returned surface */
469 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
473 HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
474 ICOM_THIS(IDirect3DDevice8Impl,iface);
475 FIXME("(%p) : stub\n", This);
478 void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
480 ICOM_THIS(IDirect3DDevice8Impl,iface);
482 FIXME("(%p) : pRamp@%p\n", This, pRamp);
483 hDC = GetDC(This->win_handle);
484 SetDeviceGammaRamp(hDC, (LPVOID) pRamp);
485 ReleaseDC(This->win_handle, hDC);
488 void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
490 ICOM_THIS(IDirect3DDevice8Impl,iface);
492 FIXME("(%p) : pRamp@%p\n", This, pRamp);
493 hDC = GetDC(This->win_handle);
494 GetDeviceGammaRamp(hDC, pRamp);
495 ReleaseDC(This->win_handle, hDC);
498 HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
499 D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture8** ppTexture) {
500 IDirect3DTexture8Impl *object;
505 ICOM_THIS(IDirect3DDevice8Impl,iface);
507 /* Allocate the storage for the device */
508 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);
509 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
510 object->lpVtbl = &Direct3DTexture8_Vtbl;
511 object->Device = This;
512 object->ResourceType = D3DRTYPE_TEXTURE;
514 object->width = Width;
515 object->height = Height;
516 object->levels = Levels;
517 object->usage = Usage;
518 object->format = Format;
520 /* Calculate levels for mip mapping */
525 while (tmpW > 1 && tmpH > 1) {
526 tmpW = max(1, tmpW / 2);
527 tmpH = max(1, tmpH / 2);
530 TRACE("Calculated levels = %d\n", object->levels);
533 /* Generate all the surfaces */
536 for (i = 0; i < object->levels; i++)
538 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
539 object->surfaces[i]->Container = (IUnknown*) object;
540 object->surfaces[i]->myDesc.Usage = Usage;
541 object->surfaces[i]->myDesc.Pool = Pool;
543 * As written in msdn in IDirect3DTexture8::LockRect
544 * Textures created in D3DPOOL_DEFAULT are not lockable.
546 if (D3DPOOL_DEFAULT == Pool) {
547 object->surfaces[i]->lockable = FALSE;
550 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
551 tmpW = max(1, tmpW / 2);
552 tmpH = max(1, tmpH / 2);
555 *ppTexture = (LPDIRECT3DTEXTURE8) object;
556 TRACE("(%p) : Created texture %p\n", This, object);
559 HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface,
560 UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage,
561 D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture8** ppVolumeTexture) {
563 IDirect3DVolumeTexture8Impl *object;
569 ICOM_THIS(IDirect3DDevice8Impl,iface);
571 /* Allocate the storage for it */
572 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));
573 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
574 object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
575 object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
576 object->Device = This;
579 object->width = Width;
580 object->height = Height;
581 object->depth = Depth;
582 object->levels = Levels;
583 object->usage = Usage;
584 object->format = Format;
586 /* Calculate levels for mip mapping */
592 while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
593 tmpW = max(1, tmpW / 2);
594 tmpH = max(1, tmpH / 2);
595 tmpD = max(1, tmpD / 2);
598 TRACE("Calculated levels = %d\n", object->levels);
601 /* Generate all the surfaces */
606 for (i = 0; i < object->levels; i++)
608 IDirect3DVolume8Impl* volume;
610 /* Create the volume - No entry point for this seperately?? */
611 volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
612 object->volumes[i] = (IDirect3DVolume8Impl *) volume;
614 volume->lpVtbl = &Direct3DVolume8_Vtbl;
615 volume->Device = This;
616 volume->ResourceType = D3DRTYPE_VOLUME;
617 volume->Container = (IUnknown*) object;
620 volume->myDesc.Width = Width;
621 volume->myDesc.Height = Height;
622 volume->myDesc.Depth = Depth;
623 volume->myDesc.Format = Format;
624 volume->myDesc.Type = D3DRTYPE_VOLUME;
625 volume->myDesc.Pool = Pool;
626 volume->myDesc.Usage = Usage;
627 volume->bytesPerPixel = D3DFmtGetBpp(This, Format);
628 /* Note: Volume textures cannot be dxtn, hence no need to check here */
629 volume->myDesc.Size = (Width * volume->bytesPerPixel) * Height * Depth;
630 volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
632 volume->lockable = TRUE;
633 volume->locked = FALSE;
634 memset(&volume->lockedBox, 0, sizeof(D3DBOX));
635 volume->Dirty = FALSE;
636 IDirect3DVolume8Impl_CleanDirtyBox((LPDIRECT3DVOLUME8) volume);
638 TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%u,%s) surf@%p, surfmem@%p, %d bytes\n",
639 This, Width, Height, Depth, Format, debug_d3dformat(Format),
640 volume, volume->allocatedMemory, volume->myDesc.Size);
642 tmpW = max(1, tmpW / 2);
643 tmpH = max(1, tmpH / 2);
644 tmpD = max(1, tmpD / 2);
647 *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8) object;
648 TRACE("(%p) : Created volume texture %p\n", This, object);
651 HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage,
652 D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
654 IDirect3DCubeTexture8Impl *object;
655 ICOM_THIS(IDirect3DDevice8Impl,iface);
659 /* Allocate the storage for it */
660 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));
661 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
662 object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
664 object->Device = This;
665 object->ResourceType = D3DRTYPE_CUBETEXTURE;
667 object->edgeLength = EdgeLength;
668 object->levels = Levels;
669 object->usage = Usage;
670 object->format = Format;
672 /* Calculate levels for mip mapping */
677 tmpW = max(1, tmpW / 2);
680 TRACE("Calculated levels = %d\n", object->levels);
683 /* Generate all the surfaces */
685 for (i = 0; i < object->levels; i++) {
686 /* Create the 6 faces */
687 for (j = 0; j < 6; j++) {
688 IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
689 object->surfaces[j][i]->Container = (IUnknown*) object;
690 object->surfaces[j][i]->myDesc.Usage = Usage;
691 object->surfaces[j][i]->myDesc.Pool = Pool;
693 * As written in msdn in IDirect3DCubeTexture8::LockRect
694 * Textures created in D3DPOOL_DEFAULT are not lockable.
696 if (D3DPOOL_DEFAULT == Pool) {
697 object->surfaces[j][i]->lockable = FALSE;
700 TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
702 tmpW = max(1, tmpW / 2);
705 TRACE("(%p) : Iface@%p\n", This, object);
706 *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8) object;
709 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
710 IDirect3DVertexBuffer8Impl *object;
712 ICOM_THIS(IDirect3DDevice8Impl,iface);
714 /* Allocate the storage for the device */
715 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
716 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
717 object->Device = This;
718 object->ResourceType = D3DRTYPE_VERTEXBUFFER;
720 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
721 object->currentDesc.Usage = Usage;
722 object->currentDesc.Pool = Pool;
723 object->currentDesc.FVF = FVF;
724 object->currentDesc.Size = Size;
726 TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
728 *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8) object;
732 HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) {
733 IDirect3DIndexBuffer8Impl *object;
735 ICOM_THIS(IDirect3DDevice8Impl,iface);
736 TRACE("(%p) : Len=%d, Use=%lx, Format=(%u,%s), Pool=%d\n", This, Length, Usage, Format, debug_d3dformat(Format), Pool);
738 /* Allocate the storage for the device */
739 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
740 object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
741 object->Device = This;
743 object->ResourceType = D3DRTYPE_INDEXBUFFER;
745 object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
746 object->currentDesc.Usage = Usage;
747 object->currentDesc.Pool = Pool;
748 object->currentDesc.Format = Format;
749 object->currentDesc.Size = Length;
751 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
753 TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
755 *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8) object;
759 HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
760 IDirect3DSurface8Impl *object;
761 ICOM_THIS(IDirect3DDevice8Impl,iface);
763 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
764 if (NULL == object) {
766 return D3DERR_OUTOFVIDEOMEMORY;
768 *ppSurface = (LPDIRECT3DSURFACE8) object;
769 object->lpVtbl = &Direct3DSurface8_Vtbl;
770 object->Device = This;
771 object->ResourceType = D3DRTYPE_SURFACE;
772 object->Container = (IUnknown*) This;
775 object->myDesc.Width = Width;
776 object->myDesc.Height = Height;
777 object->myDesc.Format = Format;
778 object->myDesc.Type = D3DRTYPE_SURFACE;
779 object->myDesc.Usage = D3DUSAGE_RENDERTARGET;
780 object->myDesc.Pool = D3DPOOL_DEFAULT;
781 object->myDesc.MultiSampleType = MultiSample;
782 object->bytesPerPixel = D3DFmtGetBpp(This, Format);
783 if (Format == D3DFMT_DXT1) {
784 object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height; /* DXT1 is half byte per pixel */
786 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
788 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
789 object->lockable = Lockable;
790 object->locked = FALSE;
791 memset(&object->lockedRect, 0, sizeof(RECT));
792 IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
794 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);
797 HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
798 IDirect3DSurface8Impl *object;
800 ICOM_THIS(IDirect3DDevice8Impl,iface);
802 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
803 if (NULL == object) {
805 return D3DERR_OUTOFVIDEOMEMORY;
807 *ppSurface = (LPDIRECT3DSURFACE8) object;
808 object->lpVtbl = &Direct3DSurface8_Vtbl;
809 object->Device = This;
810 object->ResourceType = D3DRTYPE_SURFACE;
811 object->Container = (IUnknown*) This;
814 object->myDesc.Width = Width;
815 object->myDesc.Height = Height;
816 object->myDesc.Format = Format;
817 object->myDesc.Type = D3DRTYPE_SURFACE;
818 object->myDesc.Usage = D3DUSAGE_DEPTHSTENCIL;
819 object->myDesc.Pool = D3DPOOL_DEFAULT;
820 object->myDesc.MultiSampleType = MultiSample;
821 object->bytesPerPixel = D3DFmtGetBpp(This, Format);
822 if (Format == D3DFMT_DXT1) {
823 object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height; /* DXT1 is half byte per pixel */
825 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
827 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
828 object->lockable = (D3DFMT_D16_LOCKABLE == Format) ? TRUE : FALSE;
829 object->locked = FALSE;
830 memset(&object->lockedRect, 0, sizeof(RECT));
831 IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
833 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);
836 HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
837 IDirect3DSurface8Impl *object;
839 ICOM_THIS(IDirect3DDevice8Impl,iface);
841 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
842 *ppSurface = (LPDIRECT3DSURFACE8) object;
843 object->lpVtbl = &Direct3DSurface8_Vtbl;
844 object->Device = This;
845 object->ResourceType = D3DRTYPE_SURFACE;
846 object->Container = (IUnknown*) This;
849 object->myDesc.Width = Width;
850 object->myDesc.Height = Height;
851 object->myDesc.Format = Format;
852 object->myDesc.Type = D3DRTYPE_SURFACE;
853 object->myDesc.Usage = 0;
854 object->myDesc.Pool = D3DPOOL_SYSTEMMEM;
855 object->bytesPerPixel = D3DFmtGetBpp(This, Format);
856 /* DXTn mipmaps use the same number of 'levels' down to eg. 8x1, but since
857 it is based around 4x4 pixel blocks it requires padding, so allocate enough
859 if (Format == D3DFMT_DXT1) {
860 object->myDesc.Size = ((max(Width,4) * object->bytesPerPixel) * max(Height,4)) / 2; /* DXT1 is half byte per pixel */
861 } else if (Format == D3DFMT_DXT2 || Format == D3DFMT_DXT3 ||
862 Format == D3DFMT_DXT4 || Format == D3DFMT_DXT5) {
863 object->myDesc.Size = ((max(Width,4) * object->bytesPerPixel) * max(Height,4));
865 object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
867 object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
868 object->lockable = TRUE;
869 object->locked = FALSE;
870 memset(&object->lockedRect, 0, sizeof(RECT));
871 IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
873 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);
876 HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface,
877 IDirect3DSurface8* pSourceSurface, CONST RECT* pSourceRectsArray, UINT cRects,
878 IDirect3DSurface8* pDestinationSurface, CONST POINT* pDestPointsArray) {
881 IDirect3DBaseTexture8* texture = NULL;
884 IDirect3DSurface8Impl* src = (IDirect3DSurface8Impl*) pSourceSurface;
885 IDirect3DSurface8Impl* dst = (IDirect3DSurface8Impl*) pDestinationSurface;
887 ICOM_THIS(IDirect3DDevice8Impl,iface);
888 TRACE("(%p) pSrcSur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
889 pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
891 /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
892 a sample and doesnt seem to break anything as far as I can tell */
893 if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
894 TRACE("Formats do not match (%x,%s) / (%x,%s)\n",
895 src->myDesc.Format, debug_d3dformat(src->myDesc.Format),
896 dst->myDesc.Format, debug_d3dformat(dst->myDesc.Format));
897 rc = D3DERR_INVALIDCALL;
899 } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
900 TRACE("Converting dest to same format as source, since dest was unknown\n");
901 dst->myDesc.Format = src->myDesc.Format;
903 /* Convert container as well */
904 IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
905 if (texture != NULL) {
906 ((IDirect3DBaseTexture8Impl*) texture)->format = src->myDesc.Format;
907 /** Releasing texture after GetContainer */
908 IDirect3DBaseTexture8_Release(texture);
913 /* Quick if complete copy ... */
914 if (rc == D3D_OK && cRects == 0 && pSourceRectsArray == NULL && pDestPointsArray == NULL) {
916 if (src->myDesc.Width == dst->myDesc.Width && src->myDesc.Height == dst->myDesc.Height) {
918 D3DLOCKED_RECT lrSrc;
919 D3DLOCKED_RECT lrDst;
920 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, NULL, D3DLOCK_READONLY);
921 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, NULL, 0L);
922 TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
924 memcpy(lrDst.pBits, lrSrc.pBits, src->myDesc.Size);
926 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
927 rc = IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
928 TRACE("Unlocked src and dst\n");
932 FIXME("Wanted to copy all surfaces but size not compatible\n");
933 rc = D3DERR_INVALIDCALL;
939 if (NULL != pSourceRectsArray && NULL != pDestPointsArray) {
941 int bytesPerPixel = ((IDirect3DSurface8Impl*) pSourceSurface)->bytesPerPixel;
944 /* Copy rect by rect */
945 for (i = 0; i < cRects; i++) {
946 CONST RECT* r = &pSourceRectsArray[i];
947 CONST POINT* p = &pDestPointsArray[i];
950 D3DLOCKED_RECT lrSrc;
951 D3DLOCKED_RECT lrDst;
955 TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top, r->right, r->bottom, p->x, p->y);
956 if (src->myDesc.Format == D3DFMT_DXT1) {
957 copyperline = ((r->right - r->left) * bytesPerPixel)/2; /* DXT1 is half byte per pixel */
959 copyperline = ((r->right - r->left) * bytesPerPixel);
961 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, r, D3DLOCK_READONLY);
962 dest_rect.left = p->x;
963 dest_rect.top = p->y;
964 dest_rect.right = p->x + (r->right - r->left);
965 dest_rect.left = p->y + (r->bottom - r->top);
966 IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, &dest_rect, 0L);
967 TRACE("Locked src and dst\n");
969 /* Find where to start */
970 for (j = 0; j < (r->bottom - r->top); j++) {
971 memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline);
974 IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
975 rc = IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
976 TRACE("Unlocked src and dst\n");
981 FIXME("Wanted to copy partial surfaces not implemented\n");
982 rc = D3DERR_INVALIDCALL;
989 HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
990 IDirect3DBaseTexture8Impl* src = (IDirect3DBaseTexture8Impl*) pSourceTexture;
991 IDirect3DBaseTexture8Impl* dst = (IDirect3DBaseTexture8Impl*) pDestinationTexture;
992 D3DRESOURCETYPE srcType;
993 D3DRESOURCETYPE dstType;
995 ICOM_THIS(IDirect3DDevice8Impl,iface);
996 TRACE("(%p) : first try\n", This);
998 srcType = IDirect3DBaseTexture8Impl_GetType(pSourceTexture);
999 dstType = IDirect3DBaseTexture8Impl_GetType(pDestinationTexture);
1001 if (srcType != dstType) {
1002 return D3DERR_INVALIDCALL;
1004 if (D3DPOOL_SYSTEMMEM != IDirect3DResource8Impl_GetPool((LPDIRECT3DRESOURCE8) src)) {
1005 return D3DERR_INVALIDCALL;
1007 if (D3DPOOL_DEFAULT != IDirect3DResource8Impl_GetPool((LPDIRECT3DRESOURCE8) dst)) {
1008 return D3DERR_INVALIDCALL;
1010 if (IDirect3DBaseTexture8Impl_IsDirty(pSourceTexture)) {
1011 /** Only copy Dirty textures */
1012 DWORD srcLevelCnt = IDirect3DBaseTexture8Impl_GetLevelCount(pSourceTexture);
1013 DWORD dstLevelCnt = IDirect3DBaseTexture8Impl_GetLevelCount(pDestinationTexture);
1014 DWORD skipLevels = (dstLevelCnt < srcLevelCnt) ? srcLevelCnt - dstLevelCnt : 0;
1017 for (i = skipLevels; i < srcLevelCnt; ++i) {
1021 case D3DRTYPE_TEXTURE:
1023 IDirect3DSurface8* srcSur = NULL;
1024 IDirect3DSurface8* dstSur = NULL;
1025 hr = IDirect3DTexture8Impl_GetSurfaceLevel((LPDIRECT3DTEXTURE8) src, i, &srcSur);
1026 hr = IDirect3DTexture8Impl_GetSurfaceLevel((LPDIRECT3DTEXTURE8) dst, i - skipLevels, &dstSur);
1028 /* Fixme: Work out how to just do the dirty regions (src or dst dirty region, and what
1029 about dst with less levels than the source?) */
1030 IDirect3DDevice8Impl_CopyRects(iface, srcSur, NULL, 0, dstSur, NULL);
1032 IDirect3DSurface8Impl_Release(srcSur);
1033 IDirect3DSurface8Impl_Release(dstSur);
1036 case D3DRTYPE_VOLUMETEXTURE:
1038 FIXME("D3DRTYPE_VOLUMETEXTURE reload currently not implemented\n");
1041 case D3DRTYPE_CUBETEXTURE:
1043 IDirect3DSurface8* srcSur = NULL;
1044 IDirect3DSurface8* dstSur = NULL;
1045 for (j = 0; j < 5; ++j) {
1046 hr = IDirect3DCubeTexture8Impl_GetCubeMapSurface((LPDIRECT3DCUBETEXTURE8) src, j, i, &srcSur);
1047 hr = IDirect3DCubeTexture8Impl_GetCubeMapSurface((LPDIRECT3DCUBETEXTURE8) dst, j, i - skipLevels, &srcSur);
1048 FIXME("D3DRTYPE_CUBETEXTURE does not support UpdateTexture yet\n");
1049 IDirect3DSurface8Impl_Release(srcSur);
1050 IDirect3DSurface8Impl_Release(dstSur);
1058 IDirect3DBaseTexture8Impl_SetDirty(pSourceTexture, FALSE);
1063 HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
1065 D3DLOCKED_RECT lockedRect;
1070 ICOM_THIS(IDirect3DDevice8Impl,iface);
1072 FIXME("(%p) : see if behavior correct\n", This);
1074 if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) {
1075 ERR("(%p) : surface(%p) have a invalid format\n", This, pDestSurface);
1076 return D3DERR_INVALIDCALL;
1079 wantedRect.left = 0;
1081 wantedRect.right = This->PresentParms.BackBufferWidth;
1082 wantedRect.bottom = This->PresentParms.BackBufferHeight;
1084 hr = IDirect3DSurface8Impl_LockRect(pDestSurface, &lockedRect, &wantedRect, 0);
1086 ERR("(%p) : cannot lock surface\n", This);
1087 return D3DERR_INVALIDCALL;
1093 vcheckGLcall("glFlush");
1094 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1095 vcheckGLcall("glIntegerv");
1096 glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
1097 vcheckGLcall("glIntegerv");
1099 glReadBuffer(GL_FRONT);
1100 vcheckGLcall("glReadBuffer");
1101 glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
1102 vcheckGLcall("glPixelStorei");
1106 for (j = 0; j < This->PresentParms.BackBufferHeight; ++j) {
1107 /*memcpy(lockedRect.pBits + (j * lockedRect.Pitch), This->frontBuffer->allocatedMemory + (j * i), i);*/
1108 glReadPixels(0, This->PresentParms.BackBufferHeight - j - 1, This->PresentParms.BackBufferWidth, 1,
1109 GL_BGRA, GL_UNSIGNED_BYTE, ((char*) lockedRect.pBits) + (j * lockedRect.Pitch));
1110 vcheckGLcall("glReadPixels");
1113 glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
1114 vcheckGLcall("glPixelStorei");
1115 glReadBuffer(prev_read);
1116 vcheckGLcall("glReadBuffer");
1120 hr = IDirect3DSurface8Impl_UnlockRect(pDestSurface);
1123 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
1126 ICOM_THIS(IDirect3DDevice8Impl,iface);
1128 if ((IDirect3DSurface8Impl*) pRenderTarget == This->renderTarget && (IDirect3DSurface8Impl*) pNewZStencil == This->stencilBufferTarget) {
1129 TRACE("Trying to do a NOP SetRenderTarget operation\n");
1133 IDirect3DDevice8Impl_CleanRender(iface);
1135 if ((IDirect3DSurface8Impl*) pRenderTarget == This->frontBuffer && (IDirect3DSurface8Impl*) pNewZStencil == This->depthStencilBuffer) {
1136 IDirect3DSurface8Impl* tmp;
1138 TRACE("retoring SetRenderTarget defaults\n");
1140 tmp = This->renderTarget;
1141 This->renderTarget = (IDirect3DSurface8Impl*) This->frontBuffer;
1142 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->renderTarget);
1143 IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
1145 tmp = This->stencilBufferTarget;
1146 This->stencilBufferTarget = (IDirect3DSurface8Impl*) This->depthStencilBuffer;
1147 if (NULL != This->stencilBufferTarget) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->stencilBufferTarget);
1148 if (NULL != tmp) IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
1153 TRACE("(%p) : expect crash newRender@%p newZStencil@%p\n", This, pRenderTarget, pNewZStencil);
1155 hr = IDirect3DDevice8Impl_ActiveRender(iface, pRenderTarget, pNewZStencil);
1160 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
1161 ICOM_THIS(IDirect3DDevice8Impl,iface);
1163 TRACE("(%p)->(%p) default(%p)\n", This, This->renderTarget, This->frontBuffer);
1165 *ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
1166 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
1171 HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
1172 ICOM_THIS(IDirect3DDevice8Impl,iface);
1174 TRACE("(%p)->(%p) default(%p)\n", This, This->stencilBufferTarget, This->depthStencilBuffer);
1176 /* Note inc ref on returned surface */
1177 *ppZStencilSurface = (LPDIRECT3DSURFACE8) This->stencilBufferTarget;
1178 if (NULL != *ppZStencilSurface) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppZStencilSurface);
1183 HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
1184 ICOM_THIS(IDirect3DDevice8Impl,iface);
1185 TRACE("(%p) : stub\n", This);
1188 HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
1189 IDirect3DBaseTexture8* cont = NULL;
1191 ICOM_THIS(IDirect3DDevice8Impl,iface);
1192 TRACE("(%p)\n", This);
1197 checkGLcall("glFlush");
1199 /* Useful for debugging sometimes!
1200 printf("Hit Enter ...\n");
1203 if (This->frontBuffer != This->renderTarget) {
1206 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1207 vcheckGLcall("glIntegerv");
1208 glReadBuffer(GL_BACK);
1209 vcheckGLcall("glReadBuffer");
1212 long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel;
1214 if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */
1217 for (j = 0; j < This->renderTarget->myDesc.Height; ++j) {
1219 This->renderTarget->myDesc.Height - j - 1,
1220 This->renderTarget->myDesc.Width,
1222 D3DFmt2GLFmt(This, This->renderTarget->myDesc.Format),
1223 D3DFmt2GLType(This, This->renderTarget->myDesc.Format),
1224 This->renderTarget->allocatedMemory + j * pitch);
1225 vcheckGLcall("glReadPixels");
1228 glReadBuffer(prev_read);
1229 vcheckGLcall("glReadBuffer");
1232 hr = IDirect3DSurface8_GetContainer((LPDIRECT3DSURFACE8) This->renderTarget, &IID_IDirect3DBaseTexture8, (void**) &cont);
1233 if (SUCCEEDED(hr) && NULL != cont) {
1234 /** always dirtify for now. we must find a better way to see that surface have been modified */
1235 IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE);
1236 IDirect3DBaseTexture8_PreLoad(cont);
1237 IDirect3DBaseTexture8Impl_Release(cont);
1245 HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
1246 ICOM_THIS(IDirect3DDevice8Impl,iface);
1248 /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
1249 render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
1250 when the depth-buffer format does not contain stencil buffer information, this method fails. */
1251 GLbitfield glMask = 0;
1252 GLboolean old_ztest;
1253 GLfloat old_z_clear_value;
1254 GLint old_stencil_clear_value;
1255 GLfloat old_color_clear_value[4];
1257 CONST D3DRECT* curRect;
1259 TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
1260 Count, pRects, Flags, Z, Stencil);
1263 if (Count > 0 && pRects) {
1264 glEnable(GL_SCISSOR_TEST);
1265 checkGLcall("glEnable GL_SCISSOR_TEST");
1271 /* Only set the values up once, as they are not changing */
1272 if (Flags & D3DCLEAR_STENCIL) {
1273 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1274 glClearStencil(Stencil);
1275 checkGLcall("glClearStencil");
1276 glMask = glMask | GL_STENCIL_BUFFER_BIT;
1279 if (Flags & D3DCLEAR_ZBUFFER) {
1280 glGetBooleanv(GL_DEPTH_WRITEMASK, &old_ztest);
1281 glDepthMask(GL_TRUE);
1282 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1284 checkGLcall("glClearDepth");
1285 glMask = glMask | GL_DEPTH_BUFFER_BIT;
1288 if (Flags & D3DCLEAR_TARGET) {
1289 TRACE("Clearing screen with glClear to color %lx\n", Color);
1290 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1291 glClearColor(((Color >> 16) & 0xFF) / 255.0f,
1292 ((Color >> 8) & 0xFF) / 255.0f,
1293 ((Color >> 0) & 0xFF) / 255.0f,
1294 ((Color >> 24) & 0xFF) / 255.0f);
1295 checkGLcall("glClearColor");
1296 glMask = glMask | GL_COLOR_BUFFER_BIT;
1299 /* Now process each rect in turn */
1300 for (i = 0; i < Count || i == 0; i++) {
1303 /* Note gl uses lower left, width/height */
1304 TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
1305 curRect->x1, curRect->y1, curRect->x2, curRect->y2,
1306 curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2),
1307 curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1308 glScissor(curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2),
1309 curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
1310 checkGLcall("glScissor");
1313 /* Clear the selected rectangle (or full screen) */
1315 checkGLcall("glClear");
1317 /* Step to the next rectangle */
1318 if (curRect) curRect = curRect + sizeof(D3DRECT);
1321 /* Restore the old values (why..?) */
1322 if (Flags & D3DCLEAR_STENCIL) {
1323 glClearStencil(old_stencil_clear_value);
1325 if (Flags & D3DCLEAR_ZBUFFER) {
1326 glDepthMask(old_ztest);
1327 glClearDepth(old_z_clear_value);
1329 if (Flags & D3DCLEAR_TARGET) {
1330 glClearColor(old_color_clear_value[0],
1331 old_color_clear_value[1],
1332 old_color_clear_value[2],
1333 old_color_clear_value[3]);
1336 if (Count > 0 && pRects) {
1337 glDisable(GL_SCISSOR_TEST);
1338 checkGLcall("glDisable");
1344 HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts, CONST D3DMATRIX* lpmatrix) {
1345 ICOM_THIS(IDirect3DDevice8Impl,iface);
1348 /* Most of this routine, comments included copied from ddraw tree initially: */
1349 TRACE("(%p) : State=%d\n", This, d3dts);
1351 /* Handle recording of state blocks */
1352 if (This->isRecordingState) {
1353 TRACE("Recording... not performing anything\n");
1354 This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
1355 This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
1356 memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
1361 * if the new matrix is the same as the current one,
1362 * we cut off any further processing. this seems to be a reasonable
1363 * optimization because as was noticed, some apps (warcraft3 for example)
1364 * tend towards setting the same matrix repeatedly for some dumb reason.
1366 * From here on we assume that the new matrix is different, wherever it matters
1369 if (!memcmp(&This->StateBlock->transforms[d3dts].u.m[0][0], lpmatrix, sizeof(D3DMATRIX))) {
1370 TRACE("The app is setting the same matrix over again\n");
1373 conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts].u.m[0][0]);
1377 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
1378 where ViewMat = Camera space, WorldMat = world space.
1380 In OpenGL, camera and world space is combined into GL_MODELVIEW
1381 matrix. The Projection matrix stay projection matrix.
1384 /* Capture the times we can just ignore the change */
1385 if (d3dts == D3DTS_WORLDMATRIX(0)) {
1386 This->modelview_valid = FALSE;
1389 } else if (d3dts == D3DTS_PROJECTION) {
1390 This->proj_valid = FALSE;
1393 } else if (d3dts >= D3DTS_WORLDMATRIX(1) && d3dts <= D3DTS_WORLDMATRIX(255)) { /* Indexed Vertex Blending Matrices 256 -> 511 */
1394 /* Use arb_vertex_blend or NV_VERTEX_WEIGHTING? */
1395 FIXME("D3DTS_WORLDMATRIX(1..255) not handled\n");
1399 /* Chances are we really are going to have to change a matrix */
1402 if (d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) { /* handle texture matrices */
1403 if (d3dts < GL_LIMITS(textures)) {
1404 int tex = d3dts - D3DTS_TEXTURE0;
1405 #if defined(GL_VERSION_1_3)
1406 glActiveTexture(GL_TEXTURE0 + tex);
1408 glActiveTextureARB(GL_TEXTURE0_ARB + tex);
1410 set_texture_matrix((float *)lpmatrix, This->UpdateStateBlock->texture_state[tex][D3DTSS_TEXTURETRANSFORMFLAGS]);
1413 } else if (d3dts == D3DTS_VIEW) { /* handle the VIEW matrice */
1414 float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
1415 This->modelview_valid = FALSE;
1416 This->view_ident = !memcmp(lpmatrix, identity, 16*sizeof(float));
1417 glMatrixMode(GL_MODELVIEW);
1418 checkGLcall("glMatrixMode(GL_MODELVIEW)");
1420 glLoadMatrixf((float *)lpmatrix);
1421 checkGLcall("glLoadMatrixf(...)");
1423 /* If we are changing the View matrix, reset the light and clipping planes to the new view
1424 * NOTE: We have to reset the positions even if the light/plane is not currently
1425 * enabled, since the call to enable it will not reset the position.
1426 * NOTE2: Apparently texture transforms do NOT need reapplying
1430 for (k = 0; k < GL_LIMITS(lights); k++) {
1431 glLightfv(GL_LIGHT0 + k, GL_POSITION, This->lightPosn[k]);
1432 checkGLcall("glLightfv posn");
1433 glLightfv(GL_LIGHT0 + k, GL_SPOT_DIRECTION, This->lightDirn[k]);
1434 checkGLcall("glLightfv dirn");
1436 /* Reset Clipping Planes if clipping is enabled */
1437 for (k = 0; k < GL_LIMITS(clipplanes); k++) {
1438 glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
1439 checkGLcall("glClipPlane");
1443 } else { /* What was requested!?? */
1444 WARN("invalid matrix specified: %i\n", d3dts);
1448 /* Release lock, all done */
1453 HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
1454 ICOM_THIS(IDirect3DDevice8Impl,iface);
1455 TRACE("(%p) : for State %d\n", This, State);
1456 memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX));
1460 HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1461 D3DMATRIX *mat = NULL;
1464 /* Note: Using UpdateStateBlock means it would be recorded in a state block change,
1465 but works regardless of recording being on.
1466 If this is found to be wrong, change to StateBlock. */
1467 ICOM_THIS(IDirect3DDevice8Impl,iface);
1468 TRACE("(%p) : For state %u\n", This, State);
1470 if (State < HIGHEST_TRANSFORMSTATE)
1472 mat = &This->UpdateStateBlock->transforms[State];
1474 FIXME("Unhandled transform state!!\n");
1477 /* Copied from ddraw code: */
1478 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);
1479 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);
1480 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);
1481 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);
1483 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);
1484 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);
1485 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);
1486 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);
1488 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);
1489 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);
1490 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);
1491 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);
1493 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);
1494 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);
1495 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);
1496 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);
1498 /* Apply change via set transform - will reapply to eg. lights this way */
1499 IDirect3DDevice8Impl_SetTransform(iface, State, &temp);
1502 HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
1503 ICOM_THIS(IDirect3DDevice8Impl,iface);
1505 TRACE("(%p)\n", This);
1506 This->UpdateStateBlock->Changed.viewport = TRUE;
1507 This->UpdateStateBlock->Set.viewport = TRUE;
1508 memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
1510 /* Handle recording of state blocks */
1511 if (This->isRecordingState) {
1512 TRACE("Recording... not performing anything\n");
1518 TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
1519 pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
1521 glDepthRange(pViewport->MinZ, pViewport->MaxZ);
1522 checkGLcall("glDepthRange");
1523 /* Note: GL requires lower left, DirectX supplies upper left */
1524 glViewport(pViewport->X, (This->PresentParms.BackBufferHeight - (pViewport->Y + pViewport->Height)),
1525 pViewport->Width, pViewport->Height);
1526 checkGLcall("glViewport");
1533 HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
1534 ICOM_THIS(IDirect3DDevice8Impl,iface);
1535 TRACE("(%p)\n", This);
1536 memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8));
1540 HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
1541 ICOM_THIS(IDirect3DDevice8Impl,iface);
1543 This->UpdateStateBlock->Changed.material = TRUE;
1544 This->UpdateStateBlock->Set.material = TRUE;
1545 memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
1547 /* Handle recording of state blocks */
1548 if (This->isRecordingState) {
1549 TRACE("Recording... not performing anything\n");
1554 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1555 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1556 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1557 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1558 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1560 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->UpdateStateBlock->material.Ambient);
1561 checkGLcall("glMaterialfv");
1562 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->UpdateStateBlock->material.Diffuse);
1563 checkGLcall("glMaterialfv");
1565 /* Only change material color if specular is enabled, otherwise it is set to black */
1566 if (This->StateBlock->renderstate[D3DRS_SPECULARENABLE]) {
1567 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular);
1568 checkGLcall("glMaterialfv");
1570 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->UpdateStateBlock->material.Emissive);
1571 checkGLcall("glMaterialfv");
1572 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
1573 checkGLcall("glMaterialf");
1578 HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
1579 ICOM_THIS(IDirect3DDevice8Impl,iface);
1580 memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
1581 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
1582 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
1583 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
1584 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
1585 TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
1589 HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) {
1590 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
1594 ICOM_THIS(IDirect3DDevice8Impl,iface);
1595 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1597 if (Index >= GL_LIMITS(lights)) {
1598 TRACE("Cannot handle more lights than device supports\n");
1599 return D3DERR_INVALIDCALL;
1602 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,
1603 pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
1604 pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
1605 pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
1606 TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
1607 pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
1608 TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
1610 This->UpdateStateBlock->Changed.lights[Index] = TRUE;
1611 This->UpdateStateBlock->Set.lights[Index] = TRUE;
1612 memcpy(&This->UpdateStateBlock->lights[Index], pLight, sizeof(D3DLIGHT8));
1614 /* Handle recording of state blocks */
1615 if (This->isRecordingState) {
1616 TRACE("Recording... not performing anything\n");
1623 colRGBA[0] = pLight->Diffuse.r;
1624 colRGBA[1] = pLight->Diffuse.g;
1625 colRGBA[2] = pLight->Diffuse.b;
1626 colRGBA[3] = pLight->Diffuse.a;
1627 glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
1628 checkGLcall("glLightfv");
1631 colRGBA[0] = pLight->Specular.r;
1632 colRGBA[1] = pLight->Specular.g;
1633 colRGBA[2] = pLight->Specular.b;
1634 colRGBA[3] = pLight->Specular.a;
1635 glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
1636 checkGLcall("glLightfv");
1639 colRGBA[0] = pLight->Ambient.r;
1640 colRGBA[1] = pLight->Ambient.g;
1641 colRGBA[2] = pLight->Ambient.b;
1642 colRGBA[3] = pLight->Ambient.a;
1643 glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
1644 checkGLcall("glLightfv");
1646 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
1647 glMatrixMode(GL_MODELVIEW);
1649 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
1651 /* Attenuation - Are these right? guessing... */
1652 glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION, pLight->Attenuation0);
1653 checkGLcall("glLightf");
1654 glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION, pLight->Attenuation1);
1655 checkGLcall("glLightf");
1657 quad_att = 1.4/(pLight->Range*pLight->Range);
1658 if (quad_att < pLight->Attenuation2) quad_att = pLight->Attenuation2;
1659 glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
1660 checkGLcall("glLightf");
1662 switch (pLight->Type) {
1663 case D3DLIGHT_POINT:
1665 This->lightPosn[Index][0] = pLight->Position.x;
1666 This->lightPosn[Index][1] = pLight->Position.y;
1667 This->lightPosn[Index][2] = pLight->Position.z;
1668 This->lightPosn[Index][3] = 1.0;
1669 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1670 checkGLcall("glLightfv");
1672 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, 180);
1673 checkGLcall("glLightf");
1680 This->lightPosn[Index][0] = pLight->Position.x;
1681 This->lightPosn[Index][1] = pLight->Position.y;
1682 This->lightPosn[Index][2] = pLight->Position.z;
1683 This->lightPosn[Index][3] = 1.0;
1684 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]);
1685 checkGLcall("glLightfv");
1688 This->lightDirn[Index][0] = pLight->Direction.x;
1689 This->lightDirn[Index][1] = pLight->Direction.y;
1690 This->lightDirn[Index][2] = pLight->Direction.z;
1691 This->lightDirn[Index][3] = 1.0;
1692 glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &This->lightDirn[Index][0]);
1693 checkGLcall("glLightfv");
1696 * opengl-ish and d3d-ish spot lights use too different models for the
1697 * light "intensity" as a function of the angle towards the main light direction,
1698 * so we only can approximate very roughly.
1699 * however spot lights are rather rarely used in games (if ever used at all).
1700 * furthermore if still used, probably nobody pays attention to such details.
1702 if (pLight->Falloff == 0) {
1705 rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
1707 if (rho < 0.0001) rho = 0.0001f;
1708 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, -0.3/log(cos(rho/2)));
1709 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, pLight->Phi*90/M_PI);
1713 case D3DLIGHT_DIRECTIONAL:
1715 This->lightPosn[Index][0] = -pLight->Direction.x;
1716 This->lightPosn[Index][1] = -pLight->Direction.y;
1717 This->lightPosn[Index][2] = -pLight->Direction.z;
1718 This->lightPosn[Index][3] = 0.0;
1719 glLightfv(GL_LIGHT0+Index, GL_POSITION, &This->lightPosn[Index][0]); /* Note gl uses w position of 0 for direction! */
1720 checkGLcall("glLightfv");
1722 glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, 180.0f);
1723 glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
1728 FIXME("Unrecognized light type %d\n", pLight->Type);
1731 /* Restore the modelview matrix */
1738 HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
1739 ICOM_THIS(IDirect3DDevice8Impl,iface);
1740 TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
1742 if (Index >= GL_LIMITS(lights)) {
1743 TRACE("Cannot handle more lights than device supports\n");
1744 return D3DERR_INVALIDCALL;
1747 memcpy(pLight, &This->StateBlock->lights[Index], sizeof(D3DLIGHT8));
1750 HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
1751 ICOM_THIS(IDirect3DDevice8Impl,iface);
1752 TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
1754 if (Index >= GL_LIMITS(lights)) {
1755 TRACE("Cannot handle more lights than device supports\n");
1756 return D3DERR_INVALIDCALL;
1759 This->UpdateStateBlock->Changed.lightEnable[Index] = TRUE;
1760 This->UpdateStateBlock->Set.lightEnable[Index] = TRUE;
1761 This->UpdateStateBlock->lightEnable[Index] = Enable;
1763 /* Handle recording of state blocks */
1764 if (This->isRecordingState) {
1765 TRACE("Recording... not performing anything\n");
1771 glEnable(GL_LIGHT0 + Index);
1772 checkGLcall("glEnable GL_LIGHT0+Index");
1774 glDisable(GL_LIGHT0 + Index);
1775 checkGLcall("glDisable GL_LIGHT0+Index");
1781 HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
1782 ICOM_THIS(IDirect3DDevice8Impl,iface);
1783 TRACE("(%p) : for idx(%ld)\n", This, Index);
1785 if (Index >= GL_LIMITS(lights)) {
1786 TRACE("Cannot handle more lights than device supports\n");
1787 return D3DERR_INVALIDCALL;
1790 *pEnable = This->StateBlock->lightEnable[Index];
1793 HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
1794 ICOM_THIS(IDirect3DDevice8Impl,iface);
1795 TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
1797 /* Validate Index */
1798 if (Index >= GL_LIMITS(clipplanes)) {
1799 TRACE("Application has requested clipplane this device doesnt support\n");
1800 return D3DERR_INVALIDCALL;
1803 This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
1804 This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
1805 This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
1806 This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
1807 This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
1808 This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
1810 /* Handle recording of state blocks */
1811 if (This->isRecordingState) {
1812 TRACE("Recording... not performing anything\n");
1820 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
1821 glMatrixMode(GL_MODELVIEW);
1823 glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
1825 TRACE("Clipplane [%f,%f,%f,%f]\n",
1826 This->UpdateStateBlock->clipplane[Index][0],
1827 This->UpdateStateBlock->clipplane[Index][1],
1828 This->UpdateStateBlock->clipplane[Index][2],
1829 This->UpdateStateBlock->clipplane[Index][3]);
1830 glClipPlane(GL_CLIP_PLANE0 + Index, This->UpdateStateBlock->clipplane[Index]);
1831 checkGLcall("glClipPlane");
1839 HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
1840 ICOM_THIS(IDirect3DDevice8Impl,iface);
1841 TRACE("(%p) : for idx %ld\n", This, Index);
1843 /* Validate Index */
1844 if (Index >= GL_LIMITS(clipplanes)) {
1845 TRACE("Application has requested clipplane this device doesnt support\n");
1846 return D3DERR_INVALIDCALL;
1849 pPlane[0] = This->StateBlock->clipplane[Index][0];
1850 pPlane[1] = This->StateBlock->clipplane[Index][1];
1851 pPlane[2] = This->StateBlock->clipplane[Index][2];
1852 pPlane[3] = This->StateBlock->clipplane[Index][3];
1855 HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
1856 ICOM_THIS(IDirect3DDevice8Impl,iface);
1857 DWORD OldValue = This->StateBlock->renderstate[State];
1859 TRACE("(%p)->state = %s(%d), value = %ld\n", This, debug_d3drenderstate(State), State, Value);
1860 This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
1861 This->UpdateStateBlock->Set.renderstate[State] = TRUE;
1862 This->UpdateStateBlock->renderstate[State] = Value;
1864 /* Handle recording of state blocks */
1865 if (This->isRecordingState) {
1866 TRACE("Recording... not performing anything\n");
1873 case D3DRS_FILLMODE :
1874 switch ((D3DFILLMODE) Value) {
1875 case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
1876 case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
1877 case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
1879 FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
1881 checkGLcall("glPolygonMode (fillmode)");
1884 case D3DRS_LIGHTING :
1886 glEnable(GL_LIGHTING);
1887 checkGLcall("glEnable GL_LIGHTING");
1889 glDisable(GL_LIGHTING);
1890 checkGLcall("glDisable GL_LIGHTING");
1894 case D3DRS_ZENABLE :
1895 switch ((D3DZBUFFERTYPE) Value) {
1897 glDisable(GL_DEPTH_TEST);
1898 checkGLcall("glDisable GL_DEPTH_TEST");
1901 glEnable(GL_DEPTH_TEST);
1902 checkGLcall("glEnable GL_DEPTH_TEST");
1907 FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
1911 case D3DRS_CULLMODE :
1913 /* If we are culling "back faces with clockwise vertices" then
1914 set front faces to be counter clockwise and enable culling
1916 switch ((D3DCULL) Value) {
1918 glDisable(GL_CULL_FACE);
1919 checkGLcall("glDisable GL_CULL_FACE");
1922 glEnable(GL_CULL_FACE);
1923 checkGLcall("glEnable GL_CULL_FACE");
1924 glFrontFace(GL_CCW);
1925 checkGLcall("glFrontFace GL_CCW");
1926 glCullFace(GL_BACK);
1929 glEnable(GL_CULL_FACE);
1930 checkGLcall("glEnable GL_CULL_FACE");
1932 checkGLcall("glFrontFace GL_CW");
1933 glCullFace(GL_BACK);
1936 FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
1940 case D3DRS_SHADEMODE :
1941 switch ((D3DSHADEMODE) Value) {
1943 glShadeModel(GL_FLAT);
1944 checkGLcall("glShadeModel");
1946 case D3DSHADE_GOURAUD:
1947 glShadeModel(GL_SMOOTH);
1948 checkGLcall("glShadeModel");
1950 case D3DSHADE_PHONG:
1951 FIXME("D3DSHADE_PHONG isnt supported?\n");
1954 return D3DERR_INVALIDCALL;
1956 FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
1960 case D3DRS_DITHERENABLE :
1962 glEnable(GL_DITHER);
1963 checkGLcall("glEnable GL_DITHER");
1965 glDisable(GL_DITHER);
1966 checkGLcall("glDisable GL_DITHER");
1970 case D3DRS_ZWRITEENABLE :
1973 checkGLcall("glDepthMask");
1976 checkGLcall("glDepthMask");
1982 int glParm = GL_LESS;
1984 switch ((D3DCMPFUNC) Value) {
1985 case D3DCMP_NEVER: glParm=GL_NEVER; break;
1986 case D3DCMP_LESS: glParm=GL_LESS; break;
1987 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
1988 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
1989 case D3DCMP_GREATER: glParm=GL_GREATER; break;
1990 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
1991 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
1992 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
1994 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
1996 glDepthFunc(glParm);
1997 checkGLcall("glDepthFunc");
2001 case D3DRS_AMBIENT :
2004 D3DCOLORTOGLFLOAT4(Value, col);
2005 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
2006 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
2007 checkGLcall("glLightModel for MODEL_AMBIENT");
2012 case D3DRS_ALPHABLENDENABLE :
2015 checkGLcall("glEnable GL_BLEND");
2017 glDisable(GL_BLEND);
2018 checkGLcall("glDisable GL_BLEND");
2022 case D3DRS_SRCBLEND :
2023 case D3DRS_DESTBLEND :
2025 int newVal = GL_ZERO;
2027 case D3DBLEND_ZERO : newVal = GL_ZERO; break;
2028 case D3DBLEND_ONE : newVal = GL_ONE; break;
2029 case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
2030 case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
2031 case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
2032 case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
2033 case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
2034 case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
2035 case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
2036 case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
2037 case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
2039 case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
2040 This->srcBlend = newVal;
2041 This->dstBlend = newVal;
2044 case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
2045 This->srcBlend = newVal;
2046 This->dstBlend = newVal;
2049 FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
2052 if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
2053 if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
2054 TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
2055 glBlendFunc(This->srcBlend, This->dstBlend);
2057 checkGLcall("glBlendFunc");
2061 case D3DRS_ALPHATESTENABLE :
2063 glEnable(GL_ALPHA_TEST);
2064 checkGLcall("glEnable GL_ALPHA_TEST");
2066 glDisable(GL_ALPHA_TEST);
2067 checkGLcall("glDisable GL_ALPHA_TEST");
2071 case D3DRS_ALPHAFUNC :
2073 int glParm = GL_LESS;
2074 float ref = ((float) This->StateBlock->renderstate[D3DRS_ALPHAREF]) / 255.0f;
2076 switch ((D3DCMPFUNC) Value) {
2077 case D3DCMP_NEVER: glParm = GL_NEVER; break;
2078 case D3DCMP_LESS: glParm = GL_LESS; break;
2079 case D3DCMP_EQUAL: glParm = GL_EQUAL; break;
2080 case D3DCMP_LESSEQUAL: glParm = GL_LEQUAL; break;
2081 case D3DCMP_GREATER: glParm = GL_GREATER; break;
2082 case D3DCMP_NOTEQUAL: glParm = GL_NOTEQUAL; break;
2083 case D3DCMP_GREATEREQUAL: glParm = GL_GEQUAL; break;
2084 case D3DCMP_ALWAYS: glParm = GL_ALWAYS; break;
2086 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2088 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2089 glAlphaFunc(glParm, ref);
2090 This->alphafunc = glParm;
2091 checkGLcall("glAlphaFunc");
2095 case D3DRS_ALPHAREF :
2097 int glParm = This->alphafunc;
2100 ref = ((float) Value) / 255.0f;
2101 TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
2102 glAlphaFunc(glParm, ref);
2103 checkGLcall("glAlphaFunc");
2107 case D3DRS_CLIPPLANEENABLE :
2108 case D3DRS_CLIPPING :
2110 /* Ensure we only do the changed clip planes */
2111 DWORD enable = 0xFFFFFFFF;
2112 DWORD disable = 0x00000000;
2114 /* If enabling / disabling all */
2115 if (State == D3DRS_CLIPPING) {
2117 enable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2120 disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
2124 enable = Value & ~OldValue;
2125 disable = ~Value & OldValue;
2128 if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
2129 if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
2130 if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
2131 if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
2132 if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
2133 if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
2135 if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
2136 if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
2137 if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
2138 if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
2139 if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
2140 if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
2144 case D3DRS_BLENDOP :
2146 int glParm = GL_FUNC_ADD;
2148 switch ((D3DBLENDOP) Value) {
2149 case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
2150 case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
2151 case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
2152 case D3DBLENDOP_MIN : glParm = GL_MIN; break;
2153 case D3DBLENDOP_MAX : glParm = GL_MAX; break;
2155 FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
2157 TRACE("glBlendEquation(%x)\n", glParm);
2158 glBlendEquation(glParm);
2159 checkGLcall("glBlendEquation");
2163 case D3DRS_TEXTUREFACTOR :
2167 /* Note the texture color applies to all textures whereas
2168 GL_TEXTURE_ENV_COLOR applies to active only */
2170 D3DCOLORTOGLFLOAT4(Value, col);
2171 /* Set the default alpha blend color */
2172 glBlendColor(col[0], col[1], col[2], col[3]);
2173 checkGLcall("glBlendColor");
2175 /* And now the default texture color as well */
2176 for (i = 0; i < GL_LIMITS(textures); i++) {
2178 /* Note the D3DRS value applies to all textures, but GL has one
2179 per texture, so apply it now ready to be used! */
2180 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2181 #if defined(GL_VERSION_1_3)
2182 glActiveTexture(GL_TEXTURE0 + i);
2184 glActiveTextureARB(GL_TEXTURE0_ARB + i);
2186 checkGLcall("Activate texture.. to update const color");
2188 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2191 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
2192 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
2197 case D3DRS_SPECULARENABLE :
2199 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
2200 and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
2201 specular color. This is wrong:
2202 Separate specular color means the specular colour is maintained separately, whereas
2203 single color means it is merged in. However in both cases they are being used to
2205 To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
2206 NOTE: If not supported dont give FIXME as very minimal impact and very few people are
2210 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular);
2211 checkGLcall("glMaterialfv");
2212 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2213 glEnable(GL_COLOR_SUM_EXT);
2215 TRACE("Specular colors cannot be enabled in this version of opengl\n");
2217 checkGLcall("glEnable(GL_COLOR_SUM)");
2219 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
2221 /* for the case of enabled lighting: */
2222 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
2223 checkGLcall("glMaterialfv");
2225 /* for the case of disabled lighting: */
2226 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2227 glDisable(GL_COLOR_SUM_EXT);
2229 TRACE("Specular colors cannot be disabled in this version of opengl\n");
2231 checkGLcall("glDisable(GL_COLOR_SUM)");
2236 case D3DRS_STENCILENABLE :
2238 glEnable(GL_STENCIL_TEST);
2239 checkGLcall("glEnable GL_STENCIL_TEST");
2241 glDisable(GL_STENCIL_TEST);
2242 checkGLcall("glDisable GL_STENCIL_TEST");
2246 case D3DRS_STENCILFUNC :
2248 int glParm = GL_ALWAYS;
2249 int ref = This->StateBlock->renderstate[D3DRS_STENCILREF];
2250 GLuint mask = This->StateBlock->renderstate[D3DRS_STENCILMASK];
2252 switch ((D3DCMPFUNC) Value) {
2253 case D3DCMP_NEVER: glParm=GL_NEVER; break;
2254 case D3DCMP_LESS: glParm=GL_LESS; break;
2255 case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
2256 case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
2257 case D3DCMP_GREATER: glParm=GL_GREATER; break;
2258 case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
2259 case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
2260 case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
2262 FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
2264 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2265 This->stencilfunc = glParm;
2266 glStencilFunc(glParm, ref, mask);
2267 checkGLcall("glStencilFunc");
2271 case D3DRS_STENCILREF :
2273 int glParm = This->stencilfunc;
2275 GLuint mask = This->StateBlock->renderstate[D3DRS_STENCILMASK];
2278 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2279 glStencilFunc(glParm, ref, mask);
2280 checkGLcall("glStencilFunc");
2284 case D3DRS_STENCILMASK :
2286 int glParm = This->stencilfunc;
2287 int ref = This->StateBlock->renderstate[D3DRS_STENCILREF];
2288 GLuint mask = Value;
2290 TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
2291 glStencilFunc(glParm, ref, mask);
2292 checkGLcall("glStencilFunc");
2296 case D3DRS_STENCILFAIL :
2302 fail = StencilOp(Value);
2303 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2304 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2305 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2306 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2308 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2309 glStencilOp(fail, zfail, zpass);
2310 checkGLcall("glStencilOp(fail, zfail, zpass);");
2313 case D3DRS_STENCILZFAIL :
2319 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2320 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2321 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
2322 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
2323 zfail = StencilOp(Value);
2325 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2326 glStencilOp(fail, zfail, zpass);
2327 checkGLcall("glStencilOp(fail, zfail, zpass);");
2330 case D3DRS_STENCILPASS :
2336 glGetIntegerv(GL_STENCIL_FAIL, &fail);
2337 checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
2338 zpass = StencilOp(Value);
2339 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
2340 checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
2342 TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
2343 glStencilOp(fail, zfail, zpass);
2344 checkGLcall("glStencilOp(fail, zfail, zpass);");
2348 case D3DRS_STENCILWRITEMASK :
2350 glStencilMask(Value);
2351 TRACE("glStencilMask(%lu)\n", Value);
2352 checkGLcall("glStencilMask");
2356 case D3DRS_FOGENABLE :
2358 if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
2360 checkGLcall("glEnable GL_FOG");
2363 checkGLcall("glDisable GL_FOG");
2368 case D3DRS_FOGCOLOR :
2371 D3DCOLORTOGLFLOAT4(Value, col);
2372 /* Set the default alpha blend color */
2373 glFogfv(GL_FOG_COLOR, &col[0]);
2374 checkGLcall("glFog GL_FOG_COLOR");
2378 case D3DRS_FOGTABLEMODE :
2381 case D3DFOG_NONE: /* I don't know what to do here */ break;
2382 case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
2383 case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
2384 case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
2386 FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value);
2391 case D3DRS_FOGSTART :
2393 float *f = (float*) &Value;
2394 glFogfv(GL_FOG_START, f);
2395 checkGLcall("glFogf(GL_FOG_START, (float) Value)");
2396 TRACE("Fog Start == %f\n", *f);
2402 float *f = (float*) &Value;
2403 glFogfv(GL_FOG_END, f);
2404 checkGLcall("glFogf(GL_FOG_END, (float) Value)");
2405 TRACE("Fog End == %f\n", *f);
2409 case D3DRS_FOGDENSITY :
2411 float *f = (float*) &Value;
2412 glFogfv(GL_FOG_DENSITY, f);
2413 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
2417 case D3DRS_VERTEXBLEND :
2419 This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
2420 TRACE("Vertex Blending state to %ld\n", Value);
2424 case D3DRS_TWEENFACTOR :
2426 This->UpdateStateBlock->tween_factor = *((float*) &Value);
2427 TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
2431 case D3DRS_INDEXEDVERTEXBLENDENABLE :
2433 TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
2437 case D3DRS_COLORVERTEX :
2438 case D3DRS_DIFFUSEMATERIALSOURCE :
2439 case D3DRS_SPECULARMATERIALSOURCE :
2440 case D3DRS_AMBIENTMATERIALSOURCE :
2441 case D3DRS_EMISSIVEMATERIALSOURCE :
2443 GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
2445 if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
2446 TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
2447 This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
2448 This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
2449 This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE],
2450 This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]);
2452 if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
2453 if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
2454 Parm = GL_AMBIENT_AND_DIFFUSE;
2458 } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
2460 } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
2462 } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
2469 if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
2471 This->tracking_color = NEEDS_TRACKING;
2472 This->tracking_parm = Parm;
2476 if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
2481 case D3DRS_LINEPATTERN :
2483 D3DLINEPATTERN *pattern = (D3DLINEPATTERN *)&Value;
2484 TRACE("Line pattern: repeat %d bits %x\n", pattern->wRepeatFactor, pattern->wLinePattern);
2486 if (pattern->wRepeatFactor) {
2487 glLineStipple(pattern->wRepeatFactor, pattern->wLinePattern);
2488 checkGLcall("glLineStipple(repeat, linepattern)");
2489 glEnable(GL_LINE_STIPPLE);
2490 checkGLcall("glEnable(GL_LINE_STIPPLE);");
2492 glDisable(GL_LINE_STIPPLE);
2493 checkGLcall("glDisable(GL_LINE_STIPPLE);");
2501 TRACE("ZBias value %f\n", *((float*)&Value));
2502 glPolygonOffset(0, -*((float*)&Value));
2503 checkGLcall("glPolygonOffset(0, -Value)");
2504 glEnable(GL_POLYGON_OFFSET_FILL);
2505 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
2506 glEnable(GL_POLYGON_OFFSET_LINE);
2507 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
2508 glEnable(GL_POLYGON_OFFSET_POINT);
2509 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
2511 glDisable(GL_POLYGON_OFFSET_FILL);
2512 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
2513 glDisable(GL_POLYGON_OFFSET_LINE);
2514 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
2515 glDisable(GL_POLYGON_OFFSET_POINT);
2516 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
2521 case D3DRS_NORMALIZENORMALS :
2523 glEnable(GL_NORMALIZE);
2524 checkGLcall("glEnable(GL_NORMALIZE);");
2526 glDisable(GL_NORMALIZE);
2527 checkGLcall("glDisable(GL_NORMALIZE);");
2531 case D3DRS_POINTSIZE :
2532 TRACE("Set point size to %f\n", *((float*)&Value));
2533 glPointSize(*((float*)&Value));
2534 checkGLcall("glPointSize(...);");
2537 case D3DRS_POINTSIZE_MIN :
2538 if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
2539 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, *((float*)&Value));
2540 checkGLcall("glPointParameterfEXT(...);");
2542 FIXME("D3DRS_POINTSIZE_MIN not supported on this opengl\n");
2546 case D3DRS_POINTSIZE_MAX :
2547 if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
2548 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, *((float*)&Value));
2549 checkGLcall("glPointParameterfEXT(...);");
2551 FIXME("D3DRS_POINTSIZE_MAX not supported on this opengl\n");
2555 case D3DRS_POINTSCALE_A :
2556 case D3DRS_POINTSCALE_B :
2557 case D3DRS_POINTSCALE_C :
2558 case D3DRS_POINTSCALEENABLE :
2560 /* If enabled, supply the parameters, otherwise fall back to defaults */
2561 if (This->StateBlock->renderstate[D3DRS_POINTSCALEENABLE]) {
2562 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
2563 att[0] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_A]);
2564 att[1] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_B]);
2565 att[2] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_C]);
2567 if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
2568 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
2569 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
2571 TRACE("D3DRS_POINTSCALEENABLE not supported on this opengl\n");
2574 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
2575 if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
2576 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
2577 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
2579 TRACE("D3DRS_POINTSCALEENABLE not supported, but not on either\n");
2585 case D3DRS_COLORWRITEENABLE :
2586 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
2587 Value & D3DCOLORWRITEENABLE_RED ? 1 : 0,
2588 Value & D3DCOLORWRITEENABLE_GREEN ? 1 : 0,
2589 Value & D3DCOLORWRITEENABLE_BLUE ? 1 : 0,
2590 Value & D3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
2591 glColorMask(Value & D3DCOLORWRITEENABLE_RED,
2592 Value & D3DCOLORWRITEENABLE_GREEN,
2593 Value & D3DCOLORWRITEENABLE_BLUE,
2594 Value & D3DCOLORWRITEENABLE_ALPHA);
2595 checkGLcall("glColorMask(...)");
2598 /* Unhandled yet...! */
2599 case D3DRS_LASTPIXEL :
2600 case D3DRS_ZVISIBLE :
2601 case D3DRS_EDGEANTIALIAS :
2602 case D3DRS_RANGEFOGENABLE :
2611 case D3DRS_FOGVERTEXMODE :
2612 case D3DRS_LOCALVIEWER :
2613 case D3DRS_SOFTWAREVERTEXPROCESSING :
2614 case D3DRS_POINTSPRITEENABLE :
2615 case D3DRS_MULTISAMPLEANTIALIAS :
2616 case D3DRS_MULTISAMPLEMASK :
2617 case D3DRS_PATCHEDGESTYLE :
2618 case D3DRS_PATCHSEGMENTS :
2619 case D3DRS_DEBUGMONITORTOKEN :
2620 case D3DRS_POSITIONORDER :
2621 case D3DRS_NORMALORDER :
2622 /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
2623 TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
2626 FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
2633 HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
2634 ICOM_THIS(IDirect3DDevice8Impl,iface);
2635 TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
2636 *pValue = This->StateBlock->renderstate[State];
2639 HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
2640 ICOM_THIS(IDirect3DDevice8Impl,iface);
2642 TRACE("(%p)\n", This);
2644 return IDirect3DDeviceImpl_BeginStateBlock(This);
2646 HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
2647 IDirect3DStateBlockImpl* pSB;
2648 ICOM_THIS(IDirect3DDevice8Impl,iface);
2651 TRACE("(%p)\n", This);
2653 res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB);
2654 *pToken = (DWORD) pSB;
2658 HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2659 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2660 ICOM_THIS(IDirect3DDevice8Impl,iface);
2662 TRACE("(%p)\n", This);
2664 return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB);
2667 HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2668 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2669 ICOM_THIS(IDirect3DDevice8Impl,iface);
2671 TRACE("(%p)\n", This);
2673 return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB);
2675 HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
2676 IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
2677 ICOM_THIS(IDirect3DDevice8Impl,iface);
2679 TRACE("(%p)\n", This);
2681 return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB);
2684 HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
2685 IDirect3DStateBlockImpl* pSB;
2686 ICOM_THIS(IDirect3DDevice8Impl,iface);
2689 TRACE("(%p) : for type %d\n", This, Type);
2691 res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB);
2692 *pToken = (DWORD) pSB;
2696 HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
2697 ICOM_THIS(IDirect3DDevice8Impl,iface);
2698 FIXME("(%p) : stub\n", This); return D3D_OK;
2700 HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
2701 ICOM_THIS(IDirect3DDevice8Impl,iface);
2702 FIXME("(%p) : stub\n", This); return D3D_OK;
2704 HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
2705 ICOM_THIS(IDirect3DDevice8Impl,iface);
2706 TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage);
2707 *ppTexture = (LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage];
2708 IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
2711 HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) {
2713 IDirect3DBaseTexture8 *oldTxt;
2714 BOOL reapplyStates = TRUE;
2715 DWORD oldTextureDimensions = -1;
2716 DWORD reapplyFlags = 0;
2718 ICOM_THIS(IDirect3DDevice8Impl,iface);
2719 D3DRESOURCETYPE textureType;
2721 oldTxt = This->UpdateStateBlock->textures[Stage];
2722 TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
2724 /* Reject invalid texture units */
2725 if (Stage >= GL_LIMITS(textures)) {
2726 TRACE("Attempt to access invalid texture rejected\n");
2727 return D3DERR_INVALIDCALL;
2730 This->UpdateStateBlock->Set.textures[Stage] = TRUE;
2731 This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
2732 This->UpdateStateBlock->textures[Stage] = pTexture;
2734 /* Handle recording of state blocks */
2735 if (This->isRecordingState) {
2736 TRACE("Recording... not performing anything\n");
2740 oldTextureDimensions = This->UpdateStateBlock->textureDimensions[Stage];
2743 /* Make appropriate texture active */
2744 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2745 #if defined(GL_VERSION_1_3)
2746 glActiveTexture(GL_TEXTURE0 + Stage);
2748 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2750 checkGLcall("glActiveTextureARB");
2751 } else if (Stage>0) {
2752 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2755 /* Decrement the count of the previous texture */
2756 if (NULL != oldTxt) {
2757 IDirect3DBaseTexture8Impl_Release(oldTxt);
2760 if (NULL != pTexture) {
2761 IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage]);
2763 /* Now setup the texture appropraitly */
2764 textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
2766 if (textureType == D3DRTYPE_TEXTURE) {
2767 if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
2768 TRACE("Skipping setting texture as old == new\n");
2769 reapplyStates = FALSE;
2771 /* Standard 2D texture */
2772 TRACE("Standard 2d texture\n");
2773 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D;
2775 /* Load up the texture now */
2776 IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture);
2778 } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
2779 if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
2780 TRACE("Skipping setting texture as old == new\n");
2781 reapplyStates = FALSE;
2783 /* Standard 3D (volume) texture */
2784 TRACE("Standard 3d texture\n");
2785 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
2787 /* Load up the texture now */
2788 IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture);
2790 } else if (textureType == D3DRTYPE_CUBETEXTURE) {
2791 if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
2792 TRACE("Skipping setting texture as old == new\n");
2793 reapplyStates = FALSE;
2795 /* Standard Cube texture */
2796 TRACE("Standard Cube texture\n");
2797 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_CUBE_MAP_ARB;
2799 /* Load up the texture now */
2800 IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture);
2803 FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType));
2806 TRACE("Setting to no texture (ie default texture)\n");
2807 This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D;
2808 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
2809 checkGLcall("glBindTexture");
2810 TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
2813 /* Disable the old texture binding and enable the new one (unless operations are disabled) */
2814 if (oldTextureDimensions != This->UpdateStateBlock->textureDimensions[Stage]) {
2815 glDisable(oldTextureDimensions);
2816 checkGLcall("Disable oldTextureDimensions");
2817 if (This->StateBlock->texture_state[Stage][D3DTSS_COLOROP] != D3DTOP_DISABLE) {
2818 glEnable(This->UpdateStateBlock->textureDimensions[Stage]);
2819 checkGLcall("Disable new texture dimensions");
2822 /* If Alpha arg1 is texture then handle the special case when there changes between a
2823 texture and no texture - See comments in set_tex_op */
2824 if ((This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE) &&
2825 (((oldTxt == NULL) && (pTexture != NULL)) || ((pTexture == NULL) && (oldTxt != NULL))))
2827 reapplyFlags |= REAPPLY_ALPHAOP;
2832 /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
2833 a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
2834 if (reapplyStates) {
2835 setupTextureStates(iface, Stage, reapplyFlags);
2843 HRESULT WINAPI IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
2844 ICOM_THIS(IDirect3DDevice8Impl,iface);
2845 TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
2846 *pValue = This->UpdateStateBlock->texture_state[Stage][Type];
2850 HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
2851 ICOM_THIS(IDirect3DDevice8Impl,iface);
2853 /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
2855 TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
2857 /* Reject invalid texture units */
2858 if (Stage >= GL_LIMITS(textures)) {
2859 TRACE("Attempt to access invalid texture rejected\n");
2860 return D3DERR_INVALIDCALL;
2863 This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
2864 This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
2865 This->UpdateStateBlock->texture_state[Stage][Type] = Value;
2867 /* Handle recording of state blocks */
2868 if (This->isRecordingState) {
2869 TRACE("Recording... not performing anything\n");
2875 /* Make appropriate texture active */
2876 VTRACE(("Activating appropriate texture state %ld\n", Stage));
2877 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2878 #if defined(GL_VERSION_1_3)
2879 glActiveTexture(GL_TEXTURE0 + Stage);
2880 vcheckGLcall("glActiveTexture");
2882 glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
2883 vcheckGLcall("glActiveTextureARB");
2885 } else if (Stage > 0) {
2886 FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
2891 case D3DTSS_MINFILTER :
2892 case D3DTSS_MIPFILTER :
2894 DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER];
2895 DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER];
2896 GLint realVal = GL_LINEAR;
2898 if (ValueMIN == D3DTEXF_POINT) {
2900 if (ValueMIP == D3DTEXF_POINT) {
2901 realVal = GL_NEAREST_MIPMAP_NEAREST;
2902 } else if (ValueMIP == D3DTEXF_LINEAR) {
2903 realVal = GL_NEAREST_MIPMAP_LINEAR;
2904 } else if (ValueMIP == D3DTEXF_NONE) {
2905 realVal = GL_NEAREST;
2907 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
2908 realVal = GL_NEAREST_MIPMAP_LINEAR;
2910 } else if (ValueMIN == D3DTEXF_LINEAR) {
2912 if (ValueMIP == D3DTEXF_POINT) {
2913 realVal = GL_LINEAR_MIPMAP_NEAREST;
2914 } else if (ValueMIP == D3DTEXF_LINEAR) {
2915 realVal = GL_LINEAR_MIPMAP_LINEAR;
2916 } else if (ValueMIP == D3DTEXF_NONE) {
2917 realVal = GL_LINEAR;
2919 FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
2920 realVal = GL_LINEAR_MIPMAP_LINEAR;
2922 } else if (ValueMIN == D3DTEXF_NONE) {
2923 /* Doesnt really make sense - Windows just seems to disable
2924 mipmapping when this occurs */
2925 FIXME("Odd - minfilter of none, just disabling mipmaps\n");
2926 realVal = GL_LINEAR;
2929 FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
2930 realVal = GL_LINEAR_MIPMAP_LINEAR;
2933 TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
2934 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
2935 checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
2939 case D3DTSS_MAXANISOTROPY :
2941 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
2942 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAX_ANISOTROPY_EXT, This->StateBlock->texture_state[Stage][D3DTSS_MAXANISOTROPY]);
2943 checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
2948 case D3DTSS_MAGFILTER :
2949 if (Value == D3DTEXF_POINT) {
2950 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2951 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
2952 } else if (Value == D3DTEXF_LINEAR) {
2953 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2954 checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
2956 FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
2960 case D3DTSS_ALPHAOP :
2961 case D3DTSS_COLOROP :
2964 if ((Value == D3DTOP_DISABLE) && (Type == D3DTSS_COLOROP)) {
2965 /* TODO: Disable by making this and all later levels disabled */
2966 glDisable(GL_TEXTURE_1D);
2967 checkGLcall("Disable GL_TEXTURE_1D");
2968 glDisable(GL_TEXTURE_2D);
2969 checkGLcall("Disable GL_TEXTURE_2D");
2970 glDisable(GL_TEXTURE_3D);
2971 checkGLcall("Disable GL_TEXTURE_3D");
2972 break; /* Dont bother setting the texture operations */
2974 /* Enable only the appropriate texture dimension */
2975 if (Type == D3DTSS_COLOROP) {
2976 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
2977 glEnable(GL_TEXTURE_1D);
2978 checkGLcall("Enable GL_TEXTURE_1D");
2980 glDisable(GL_TEXTURE_1D);
2981 checkGLcall("Disable GL_TEXTURE_1D");
2983 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
2984 glEnable(GL_TEXTURE_2D);
2985 checkGLcall("Enable GL_TEXTURE_2D");
2987 glDisable(GL_TEXTURE_2D);
2988 checkGLcall("Disable GL_TEXTURE_2D");
2990 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
2991 glEnable(GL_TEXTURE_3D);
2992 checkGLcall("Enable GL_TEXTURE_3D");
2994 glDisable(GL_TEXTURE_3D);
2995 checkGLcall("Disable GL_TEXTURE_3D");
2997 if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_CUBE_MAP_ARB) {
2998 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2999 checkGLcall("Enable GL_TEXTURE_CUBE_MAP");
3001 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3002 checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
3006 /* Drop through... (Except disable case) */
3007 case D3DTSS_COLORARG0 :
3008 case D3DTSS_COLORARG1 :
3009 case D3DTSS_COLORARG2 :
3010 case D3DTSS_ALPHAARG0 :
3011 case D3DTSS_ALPHAARG1 :
3012 case D3DTSS_ALPHAARG2 :
3014 BOOL isAlphaArg = (Type == D3DTSS_ALPHAOP || Type == D3DTSS_ALPHAARG1 ||
3015 Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
3017 set_tex_op(iface, TRUE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_ALPHAOP],
3018 This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1],
3019 This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG2],
3020 This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG0]);
3022 set_tex_op(iface, FALSE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_COLOROP],
3023 This->StateBlock->texture_state[Stage][D3DTSS_COLORARG1],
3024 This->StateBlock->texture_state[Stage][D3DTSS_COLORARG2],
3025 This->StateBlock->texture_state[Stage][D3DTSS_COLORARG0]);
3031 case D3DTSS_ADDRESSU :
3032 case D3DTSS_ADDRESSV :
3033 case D3DTSS_ADDRESSW :
3035 GLint wrapParm = GL_REPEAT;
3037 case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
3038 case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break;
3039 case D3DTADDRESS_BORDER: wrapParm = GL_REPEAT; break; /* FIXME: Not right, but better */
3040 #if defined(GL_VERSION_1_4)
3041 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT; break;
3042 #elif defined(GL_ARB_texture_mirrored_repeat)
3043 case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT_ARB; break;
3045 case D3DTADDRESS_MIRROR: /* Unsupported in OpenGL pre-1.4 */
3047 case D3DTADDRESS_MIRRORONCE: /* Unsupported in OpenGL */
3049 FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
3050 wrapParm = GL_REPEAT;
3054 case D3DTSS_ADDRESSU:
3055 TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3056 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
3057 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
3059 case D3DTSS_ADDRESSV:
3060 TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3061 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
3062 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
3064 case D3DTSS_ADDRESSW:
3065 TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
3066 glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
3067 checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
3070 break; /** stupic compilator */
3075 case D3DTSS_BORDERCOLOR :
3078 D3DCOLORTOGLFLOAT4(Value, col);
3079 TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value);
3080 glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
3081 checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
3085 case D3DTSS_TEXCOORDINDEX :
3087 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
3089 /* FIXME: From MSDN: The D3DTSS_TCI_* flags are mutually exclusive. If you include
3090 one flag, you can still specify an index value, which the system uses to
3091 determine the texture wrapping mode.
3092 eg. SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3093 means use the vertex position (camera-space) as the input texture coordinates
3094 for this texture stage, and the wrap mode set in the D3DRS_WRAP1 render
3095 state. We do not (yet) support the D3DRENDERSTATE_WRAPx values, nor tie them up
3096 to the TEXCOORDINDEX value */
3099 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
3101 switch (Value & 0xFFFF0000) {
3102 case D3DTSS_TCI_PASSTHRU:
3103 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
3104 glDisable(GL_TEXTURE_GEN_S);
3105 glDisable(GL_TEXTURE_GEN_T);
3106 glDisable(GL_TEXTURE_GEN_R);
3107 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R)");
3110 case D3DTSS_TCI_CAMERASPACEPOSITION:
3111 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3112 as the input texture coordinates for this stage's texture transformation. This
3113 equates roughly to EYE_LINEAR */
3115 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
3116 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
3117 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
3118 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
3119 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3121 glMatrixMode(GL_MODELVIEW);
3124 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3125 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3126 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3127 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3130 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
3131 glEnable(GL_TEXTURE_GEN_S);
3132 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3133 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3134 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3135 glEnable(GL_TEXTURE_GEN_T);
3136 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3137 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3138 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3139 glEnable(GL_TEXTURE_GEN_R);
3140 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3141 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3142 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3146 #if defined(GL_ARB_texture_cube_map) || defined(GL_NV_texgen_reflection)
3147 case D3DTSS_TCI_CAMERASPACENORMAL:
3149 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
3150 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
3151 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
3152 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
3153 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3155 glMatrixMode(GL_MODELVIEW);
3158 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3159 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3160 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3161 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3164 glEnable(GL_TEXTURE_GEN_S);
3165 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3166 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
3167 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
3168 glEnable(GL_TEXTURE_GEN_T);
3169 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3170 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
3171 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
3172 glEnable(GL_TEXTURE_GEN_R);
3173 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3174 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
3175 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
3180 #if defined(GL_ARB_texture_cube_map) || defined(GL_NV_texgen_reflection)
3181 case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3184 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
3185 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
3186 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
3187 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
3188 TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3190 glMatrixMode(GL_MODELVIEW);
3193 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3194 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3195 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3196 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3199 glEnable(GL_TEXTURE_GEN_S);
3200 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
3201 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
3202 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
3203 glEnable(GL_TEXTURE_GEN_T);
3204 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
3205 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
3206 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
3207 glEnable(GL_TEXTURE_GEN_R);
3208 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
3209 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
3210 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
3215 /* Unhandled types: */
3218 /* ? disable GL_TEXTURE_GEN_n ? */
3219 glDisable(GL_TEXTURE_GEN_S);
3220 glDisable(GL_TEXTURE_GEN_T);
3221 glDisable(GL_TEXTURE_GEN_R);
3222 FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value);
3229 case D3DTSS_BUMPENVMAT00 :
3230 case D3DTSS_BUMPENVMAT01 :
3231 TRACE("BUMPENVMAT0%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT00, Stage, Type, Value);
3233 case D3DTSS_BUMPENVMAT10 :
3234 case D3DTSS_BUMPENVMAT11 :
3235 TRACE("BUMPENVMAT1%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT10, Stage, Type, Value);
3238 case D3DTSS_TEXTURETRANSFORMFLAGS :
3239 set_texture_matrix((float *)&This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], Value);
3242 case D3DTSS_MIPMAPLODBIAS :
3243 case D3DTSS_MAXMIPLEVEL :
3244 case D3DTSS_BUMPENVLSCALE :
3245 case D3DTSS_BUMPENVLOFFSET :
3246 case D3DTSS_RESULTARG :
3248 /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
3249 TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
3256 HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
3257 ICOM_THIS(IDirect3DDevice8Impl,iface);
3258 TRACE("(%p) : stub\n", This); /* FIXME: Needs doing, but called often and is harmless */
3261 HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID, void* pDevInfoStruct, DWORD DevInfoStructSize) {
3262 ICOM_THIS(IDirect3DDevice8Impl,iface);
3263 FIXME("(%p) : stub\n", This);
3266 HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
3267 ICOM_THIS(IDirect3DDevice8Impl,iface);
3268 FIXME("(%p) : setting p[%u] <= RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber,
3269 pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags);
3270 memcpy(This->palettes[PaletteNumber], pEntries, 256 * sizeof(PALETTEENTRY));
3273 HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
3274 ICOM_THIS(IDirect3DDevice8Impl,iface);
3275 memcpy(pEntries, This->palettes[PaletteNumber], 256 * sizeof(PALETTEENTRY));
3276 FIXME("(%p) : returning p[%u] => RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber,
3277 pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags);
3280 HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
3281 ICOM_THIS(IDirect3DDevice8Impl,iface);
3282 FIXME("(%p) : Setting to (%u)\n", This, PaletteNumber);
3283 This->currentPalette = PaletteNumber;
3285 #if defined(GL_EXT_paletted_texture)
3286 if (GL_SUPPORT(EXT_PALETTED_TEXTURE)) {
3290 GL_EXTCALL(glColorTableEXT)(GL_TEXTURE_2D, /* target */
3291 GL_RGBA, /* internal format */
3292 256, /* table size */
3293 GL_RGBA, /* table format */
3294 GL_UNSIGNED_BYTE, /* table type */
3295 This->palettes[PaletteNumber]);
3296 checkGLcall("glColorTableEXT");
3301 /* Delayed palette handling ... waiting for software emulation into preload code */
3306 HRESULT WINAPI IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
3307 ICOM_THIS(IDirect3DDevice8Impl,iface);
3308 *PaletteNumber = This->currentPalette;
3309 FIXME("(%p) : Returning (%u)\n", This, *PaletteNumber);
3312 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
3314 ICOM_THIS(IDirect3DDevice8Impl,iface);
3315 This->StateBlock->streamIsUP = FALSE;
3317 TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), StartVertex, PrimitiveCount);
3318 drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, -1, 0, NULL, 0);
3322 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
3323 UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
3325 IDirect3DIndexBuffer8 *pIB;
3326 D3DINDEXBUFFER_DESC IdxBufDsc;
3328 ICOM_THIS(IDirect3DDevice8Impl,iface);
3329 pIB = This->StateBlock->pIndexData;
3330 This->StateBlock->streamIsUP = FALSE;
3332 TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d \n", This,
3333 PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
3334 minIndex, NumVertices, startIndex, primCount);
3336 IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
3337 if (IdxBufDsc.Format == D3DFMT_INDEX16) {
3343 drawPrimitive(iface, PrimitiveType, primCount, This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
3348 HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
3349 ICOM_THIS(IDirect3DDevice8Impl,iface);
3351 TRACE("(%p) : Type=(%d,%s), pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
3352 PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
3354 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3356 /* Note in the following, its not this type, but thats the purpose of streamIsUP */
3357 This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData;
3358 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3359 This->StateBlock->streamIsUP = TRUE;
3360 drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, NULL, 0);
3361 This->StateBlock->stream_stride[0] = 0;
3362 This->StateBlock->stream_source[0] = NULL;
3364 /*stream zero settings set to null at end */
3367 HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
3368 UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
3369 D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
3370 UINT VertexStreamZeroStride) {
3372 ICOM_THIS(IDirect3DDevice8Impl,iface);
3373 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),
3374 MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
3376 if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
3377 if (IndexDataFormat == D3DFMT_INDEX16) {
3383 /* Note in the following, its not this type, but thats the purpose of streamIsUP */
3384 This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData;
3385 This->StateBlock->streamIsUP = TRUE;
3386 This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
3387 drawPrimitive(iface, PrimitiveType, PrimitiveCount, This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
3389 /*stream zero settings set to null at end */
3390 This->StateBlock->stream_source[0] = NULL;
3391 This->StateBlock->stream_stride[0] = 0;
3392 IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
3396 HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
3397 ICOM_THIS(IDirect3DDevice8Impl,iface);
3398 FIXME("(%p) : stub\n", This); return D3D_OK;
3400 HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
3401 ICOM_THIS(IDirect3DDevice8Impl,iface);
3402 IDirect3DVertexShaderImpl* object;
3403 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3407 TRACE_(d3d_shader)("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p, Usage=%lu\n", This, pDeclaration, pFunction, Usage);
3408 if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
3409 return D3DERR_INVALIDCALL;
3411 for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
3412 if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
3413 return D3DERR_OUTOFVIDEOMEMORY;
3416 /** Create the Vertex Shader */
3417 res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
3418 /** TODO: check FAILED(res) */
3420 /** Create and Bind the Vertex Shader Declaration */
3421 res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
3422 /** TODO: check FAILED(res) */
3424 VertexShaders[i] = object;
3425 VertexShaderDeclarations[i] = attached_decl;
3426 *pHandle = VS_HIGHESTFIXEDFXF + i;
3427 TRACE("Finished creating vertex shader %lx\n", *pHandle);
3431 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3432 ICOM_THIS(IDirect3DDevice8Impl,iface);
3434 This->UpdateStateBlock->VertexShader = Handle;
3435 This->UpdateStateBlock->Changed.vertexShader = TRUE;
3436 This->UpdateStateBlock->Set.vertexShader = TRUE;
3438 if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
3439 TRACE_(d3d_shader)("(%p) : Created shader, Handle=%lx\n", This, Handle);
3440 This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
3441 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3442 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3443 } else { /* use a fvf, so desactivate the vshader decl */
3444 TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
3445 This->UpdateStateBlock->vertexShaderDecl = NULL;
3446 This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
3447 This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
3449 /* Handle recording of state blocks */
3450 if (This->isRecordingState) {
3451 TRACE("Recording... not performing anything\n");
3455 * TODO: merge HAL shaders context switching from prototype
3459 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3460 ICOM_THIS(IDirect3DDevice8Impl,iface);
3461 TRACE_(d3d_shader)("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
3462 *pHandle = This->StateBlock->VertexShader;
3466 HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3467 ICOM_THIS(IDirect3DDevice8Impl,iface);
3468 IDirect3DVertexShaderImpl* object;
3469 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3471 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3472 return D3DERR_INVALIDCALL;
3476 * Delete Vertex Shader
3478 object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
3479 if (NULL == object) {
3480 return D3DERR_INVALIDCALL;
3482 TRACE_(d3d_shader)("(%p) : freing VertexShader %p\n", This, object);
3483 /* TODO: check validity of object */
3484 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3485 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3486 HeapFree(GetProcessHeap(), 0, (void *)object);
3487 VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3490 * Delete Vertex Shader Declaration
3492 attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
3493 if (NULL == attached_decl) {
3494 return D3DERR_INVALIDCALL;
3496 TRACE_(d3d_shader)("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
3497 /* TODO: check validity of object */
3498 HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
3499 HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
3500 VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3505 HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3506 ICOM_THIS(IDirect3DDevice8Impl,iface);
3508 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3509 ERR_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);
3510 return D3DERR_INVALIDCALL;
3512 if (NULL == pConstantData) {
3513 return D3DERR_INVALIDCALL;
3515 if (ConstantCount > 1) {
3516 FLOAT* f = (FLOAT*)pConstantData;
3518 TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
3519 for (i = 0; i < ConstantCount; ++i) {
3520 TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
3524 FLOAT* f = (FLOAT*) pConstantData;
3525 TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
3527 This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
3528 memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
3531 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3532 ICOM_THIS(IDirect3DDevice8Impl,iface);
3534 TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
3535 if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
3536 return D3DERR_INVALIDCALL;
3538 if (NULL == pConstantData) {
3539 return D3DERR_INVALIDCALL;
3541 memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
3544 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3545 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3546 IDirect3DVertexShaderDeclarationImpl* attached_decl;
3548 attached_decl = VERTEX_SHADER_DECL(Handle);
3549 if (NULL == attached_decl) {
3550 return D3DERR_INVALIDCALL;
3552 return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
3554 HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3555 /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
3556 IDirect3DVertexShaderImpl* object;
3558 object = VERTEX_SHADER(Handle);
3559 if (NULL == object) {
3560 return D3DERR_INVALIDCALL;
3562 return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
3565 HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
3566 ICOM_THIS(IDirect3DDevice8Impl,iface);
3567 IDirect3DIndexBuffer8 *oldIdxs;
3569 TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
3570 oldIdxs = This->StateBlock->pIndexData;
3572 This->UpdateStateBlock->Changed.Indices = TRUE;
3573 This->UpdateStateBlock->Set.Indices = TRUE;
3574 This->UpdateStateBlock->pIndexData = pIndexData;
3575 This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
3577 /* Handle recording of state blocks */
3578 if (This->isRecordingState) {
3579 TRACE("Recording... not performing anything\n");
3583 if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
3584 if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
3587 HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
3588 ICOM_THIS(IDirect3DDevice8Impl,iface);
3589 FIXME("(%p) : stub\n", This);
3591 *ppIndexData = This->StateBlock->pIndexData;
3592 /* up ref count on ppindexdata */
3593 if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
3594 *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
3598 HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
3599 ICOM_THIS(IDirect3DDevice8Impl,iface);
3600 IDirect3DPixelShaderImpl* object;
3604 TRACE_(d3d_shader)("(%p) : PixelShader not fully supported yet : Func=%p\n", This, pFunction);
3605 if (NULL == pFunction || NULL == pHandle) {
3606 return D3DERR_INVALIDCALL;
3608 for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
3609 if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
3610 return D3DERR_OUTOFVIDEOMEMORY;
3613 /** Create the Pixel Shader */
3614 res = IDirect3DDeviceImpl_CreatePixelShader(This, pFunction, &object);
3615 if (SUCCEEDED(res)) {
3616 PixelShaders[i] = object;
3617 *pHandle = VS_HIGHESTFIXEDFXF + i;
3620 *pHandle = 0xFFFFFFFF;
3623 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3624 ICOM_THIS(IDirect3DDevice8Impl,iface);
3626 This->UpdateStateBlock->PixelShader = Handle;
3627 This->UpdateStateBlock->Changed.pixelShader = TRUE;
3628 This->UpdateStateBlock->Set.pixelShader = TRUE;
3630 /* Handle recording of state blocks */
3631 if (This->isRecordingState) {
3632 TRACE_(d3d_shader)("Recording... not performing anything\n");
3636 /* FIXME: Quieten when not being used */
3638 FIXME_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
3640 TRACE_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
3645 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
3646 ICOM_THIS(IDirect3DDevice8Impl,iface);
3647 TRACE_(d3d_shader)("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
3648 *pHandle = This->StateBlock->PixelShader;
3652 HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
3653 ICOM_THIS(IDirect3DDevice8Impl,iface);
3654 IDirect3DPixelShaderImpl* object;
3656 if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
3657 return D3DERR_INVALIDCALL;
3659 object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
3660 TRACE_(d3d_shader)("(%p) : freeing PixelShader %p\n", This, object);
3661 /* TODO: check validity of object before free */
3662 if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
3663 HeapFree(GetProcessHeap(), 0, (void *)object->data);
3664 HeapFree(GetProcessHeap(), 0, (void *)object);
3665 PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
3670 HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
3671 ICOM_THIS(IDirect3DDevice8Impl,iface);
3673 if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
3674 ERR_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu] invalid\n", This, Register);
3675 return D3DERR_INVALIDCALL;
3677 if (NULL == pConstantData) {
3678 return D3DERR_INVALIDCALL;
3680 if (ConstantCount > 1) {
3681 FLOAT* f = (FLOAT*)pConstantData;
3683 TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
3684 for (i = 0; i < ConstantCount; ++i) {
3685 TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
3689 FLOAT* f = (FLOAT*) pConstantData;
3690 TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
3692 This->UpdateStateBlock->Changed.pixelShaderConstant = TRUE;
3693 memcpy(&This->UpdateStateBlock->pixelShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
3696 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
3697 ICOM_THIS(IDirect3DDevice8Impl,iface);
3699 TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
3700 if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
3701 return D3DERR_INVALIDCALL;
3703 if (NULL == pConstantData) {
3704 return D3DERR_INVALIDCALL;
3706 memcpy(pConstantData, &This->UpdateStateBlock->pixelShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
3709 HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
3710 IDirect3DPixelShaderImpl* object;
3712 object = PIXEL_SHADER(Handle);
3713 if (NULL == object) {
3714 return D3DERR_INVALIDCALL;
3716 return IDirect3DPixelShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
3718 HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
3719 ICOM_THIS(IDirect3DDevice8Impl,iface);
3720 FIXME("(%p) : stub\n", This); return D3D_OK;
3722 HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
3723 ICOM_THIS(IDirect3DDevice8Impl,iface);
3724 FIXME("(%p) : stub\n", This); return D3D_OK;
3726 HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
3727 ICOM_THIS(IDirect3DDevice8Impl,iface);
3728 FIXME("(%p) : stub\n", This); return D3D_OK;
3731 HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
3732 IDirect3DVertexBuffer8 *oldSrc;
3733 ICOM_THIS(IDirect3DDevice8Impl,iface);
3735 oldSrc = This->StateBlock->stream_source[StreamNumber];
3736 TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
3738 This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
3739 This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
3740 This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
3741 This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
3743 /* Handle recording of state blocks */
3744 if (This->isRecordingState) {
3745 TRACE("Recording... not performing anything\n");
3749 if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
3750 if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
3753 HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
3754 ICOM_THIS(IDirect3DDevice8Impl,iface);
3755 TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
3756 *pStream = This->StateBlock->stream_source[StreamNumber];
3757 *pStride = This->StateBlock->stream_stride[StreamNumber];
3758 IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
3763 ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
3765 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3766 IDirect3DDevice8Impl_QueryInterface,
3767 IDirect3DDevice8Impl_AddRef,
3768 IDirect3DDevice8Impl_Release,
3769 IDirect3DDevice8Impl_TestCooperativeLevel,
3770 IDirect3DDevice8Impl_GetAvailableTextureMem,
3771 IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
3772 IDirect3DDevice8Impl_GetDirect3D,
3773 IDirect3DDevice8Impl_GetDeviceCaps,
3774 IDirect3DDevice8Impl_GetDisplayMode,
3775 IDirect3DDevice8Impl_GetCreationParameters,
3776 IDirect3DDevice8Impl_SetCursorProperties,
3777 IDirect3DDevice8Impl_SetCursorPosition,
3778 IDirect3DDevice8Impl_ShowCursor,
3779 IDirect3DDevice8Impl_CreateAdditionalSwapChain,
3780 IDirect3DDevice8Impl_Reset,
3781 IDirect3DDevice8Impl_Present,
3782 IDirect3DDevice8Impl_GetBackBuffer,
3783 IDirect3DDevice8Impl_GetRasterStatus,
3784 IDirect3DDevice8Impl_SetGammaRamp,
3785 IDirect3DDevice8Impl_GetGammaRamp,
3786 IDirect3DDevice8Impl_CreateTexture,
3787 IDirect3DDevice8Impl_CreateVolumeTexture,
3788 IDirect3DDevice8Impl_CreateCubeTexture,
3789 IDirect3DDevice8Impl_CreateVertexBuffer,
3790 IDirect3DDevice8Impl_CreateIndexBuffer,
3791 IDirect3DDevice8Impl_CreateRenderTarget,
3792 IDirect3DDevice8Impl_CreateDepthStencilSurface,
3793 IDirect3DDevice8Impl_CreateImageSurface,
3794 IDirect3DDevice8Impl_CopyRects,
3795 IDirect3DDevice8Impl_UpdateTexture,
3796 IDirect3DDevice8Impl_GetFrontBuffer,
3797 IDirect3DDevice8Impl_SetRenderTarget,
3798 IDirect3DDevice8Impl_GetRenderTarget,
3799 IDirect3DDevice8Impl_GetDepthStencilSurface,
3800 IDirect3DDevice8Impl_BeginScene,
3801 IDirect3DDevice8Impl_EndScene,
3802 IDirect3DDevice8Impl_Clear,
3803 IDirect3DDevice8Impl_SetTransform,
3804 IDirect3DDevice8Impl_GetTransform,
3805 IDirect3DDevice8Impl_MultiplyTransform,
3806 IDirect3DDevice8Impl_SetViewport,
3807 IDirect3DDevice8Impl_GetViewport,
3808 IDirect3DDevice8Impl_SetMaterial,
3809 IDirect3DDevice8Impl_GetMaterial,
3810 IDirect3DDevice8Impl_SetLight,
3811 IDirect3DDevice8Impl_GetLight,
3812 IDirect3DDevice8Impl_LightEnable,
3813 IDirect3DDevice8Impl_GetLightEnable,
3814 IDirect3DDevice8Impl_SetClipPlane,
3815 IDirect3DDevice8Impl_GetClipPlane,
3816 IDirect3DDevice8Impl_SetRenderState,
3817 IDirect3DDevice8Impl_GetRenderState,
3818 IDirect3DDevice8Impl_BeginStateBlock,
3819 IDirect3DDevice8Impl_EndStateBlock,
3820 IDirect3DDevice8Impl_ApplyStateBlock,
3821 IDirect3DDevice8Impl_CaptureStateBlock,
3822 IDirect3DDevice8Impl_DeleteStateBlock,
3823 IDirect3DDevice8Impl_CreateStateBlock,
3824 IDirect3DDevice8Impl_SetClipStatus,
3825 IDirect3DDevice8Impl_GetClipStatus,
3826 IDirect3DDevice8Impl_GetTexture,
3827 IDirect3DDevice8Impl_SetTexture,
3828 IDirect3DDevice8Impl_GetTextureStageState,
3829 IDirect3DDevice8Impl_SetTextureStageState,
3830 IDirect3DDevice8Impl_ValidateDevice,
3831 IDirect3DDevice8Impl_GetInfo,
3832 IDirect3DDevice8Impl_SetPaletteEntries,
3833 IDirect3DDevice8Impl_GetPaletteEntries,
3834 IDirect3DDevice8Impl_SetCurrentTexturePalette,
3835 IDirect3DDevice8Impl_GetCurrentTexturePalette,
3836 IDirect3DDevice8Impl_DrawPrimitive,
3837 IDirect3DDevice8Impl_DrawIndexedPrimitive,
3838 IDirect3DDevice8Impl_DrawPrimitiveUP,
3839 IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
3840 IDirect3DDevice8Impl_ProcessVertices,
3841 IDirect3DDevice8Impl_CreateVertexShader,
3842 IDirect3DDevice8Impl_SetVertexShader,
3843 IDirect3DDevice8Impl_GetVertexShader,
3844 IDirect3DDevice8Impl_DeleteVertexShader,
3845 IDirect3DDevice8Impl_SetVertexShaderConstant,
3846 IDirect3DDevice8Impl_GetVertexShaderConstant,
3847 IDirect3DDevice8Impl_GetVertexShaderDeclaration,
3848 IDirect3DDevice8Impl_GetVertexShaderFunction,
3849 IDirect3DDevice8Impl_SetStreamSource,
3850 IDirect3DDevice8Impl_GetStreamSource,
3851 IDirect3DDevice8Impl_SetIndices,
3852 IDirect3DDevice8Impl_GetIndices,
3853 IDirect3DDevice8Impl_CreatePixelShader,
3854 IDirect3DDevice8Impl_SetPixelShader,
3855 IDirect3DDevice8Impl_GetPixelShader,
3856 IDirect3DDevice8Impl_DeletePixelShader,
3857 IDirect3DDevice8Impl_SetPixelShaderConstant,
3858 IDirect3DDevice8Impl_GetPixelShaderConstant,
3859 IDirect3DDevice8Impl_GetPixelShaderFunction,
3860 IDirect3DDevice8Impl_DrawRectPatch,
3861 IDirect3DDevice8Impl_DrawTriPatch,
3862 IDirect3DDevice8Impl_DeletePatch
3865 HRESULT WINAPI IDirect3DDevice8Impl_CleanRender(LPDIRECT3DDEVICE8 iface)
3867 #if defined(GL_VERSION_1_3) /* @see comments on ActiveRender */
3868 ICOM_THIS(IDirect3DDevice8Impl,iface);
3873 if (This->glCtx != This->render_ctx) {
3874 glXDestroyContext(This->display, This->render_ctx);
3875 This->render_ctx = This->glCtx;
3878 if (This->win != This->drawable) {
3879 glXDestroyPbuffer(This->display, This->drawable);
3880 This->drawable = This->win;
3889 HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface,
3890 IDirect3DSurface8* RenderSurface,
3891 IDirect3DSurface8* StencilSurface) {
3893 HRESULT ret = D3DERR_INVALIDCALL;
3895 * Currently only active for GLX >= 1.3
3896 * for others versions we'll have to use GLXPixmaps
3898 * normally we must test GLX_VERSION_1_3 but nvidia headers are not correct
3899 * as they implements GLX 1.3 but only define GLX_VERSION_1_2
3900 * so only check OpenGL version
3902 #if defined(GL_VERSION_1_3)
3903 GLXFBConfig* cfgs = NULL;
3907 D3DFORMAT BackBufferFormat = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Format;
3908 D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IDirect3DSurface8Impl*) StencilSurface)->myDesc.Format : 0;
3909 UINT Width = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Width;
3910 UINT Height = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Height;
3911 IDirect3DSurface8Impl* tmp;
3913 ICOM_THIS(IDirect3DDevice8Impl,iface);
3915 #define PUSH1(att) attribs[nAttribs++] = (att);
3916 #define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
3918 PUSH2(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_WINDOW | GLX_PBUFFER_BIT);
3919 PUSH2(GLX_X_RENDERABLE, TRUE);
3920 PUSH2(GLX_DOUBLEBUFFER, TRUE);
3922 switch (BackBufferFormat) {
3925 PUSH2(GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT);
3926 PUSH2(GLX_BUFFER_SIZE, 8);
3927 PUSH2(GLX_DOUBLEBUFFER, TRUE);
3931 PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
3932 PUSH2(GLX_RED_SIZE, 3);
3933 PUSH2(GLX_GREEN_SIZE, 3);
3934 PUSH2(GLX_BLUE_SIZE, 2);
3937 case D3DFMT_A1R5G5B5:
3938 PUSH2(GLX_ALPHA_SIZE, 1);
3939 case D3DFMT_X1R5G5B5:
3940 PUSH2(GLX_RED_SIZE, 5);
3941 PUSH2(GLX_GREEN_SIZE, 5);
3942 PUSH2(GLX_BLUE_SIZE, 5);
3946 PUSH2(GLX_RED_SIZE, 5);
3947 PUSH2(GLX_GREEN_SIZE, 6);
3948 PUSH2(GLX_BLUE_SIZE, 5);
3951 case D3DFMT_A4R4G4B4:
3952 PUSH2(GLX_ALPHA_SIZE, 4);
3953 case D3DFMT_X4R4G4B4:
3954 PUSH2(GLX_RED_SIZE, 4);
3955 PUSH2(GLX_GREEN_SIZE, 4);
3956 PUSH2(GLX_BLUE_SIZE, 4);
3959 case D3DFMT_A8R8G8B8:
3960 PUSH2(GLX_ALPHA_SIZE, 8);
3962 case D3DFMT_X8R8G8B8:
3963 PUSH2(GLX_RED_SIZE, 8);
3964 PUSH2(GLX_GREEN_SIZE, 8);
3965 PUSH2(GLX_BLUE_SIZE, 8);
3972 switch (StencilBufferFormat) {
3973 case D3DFMT_D16_LOCKABLE:
3975 PUSH2(GLX_DEPTH_SIZE, 16);
3979 PUSH2(GLX_DEPTH_SIZE, 15);
3983 PUSH2(GLX_DEPTH_SIZE, 24);
3986 case D3DFMT_D24X4S4:
3987 PUSH2(GLX_DEPTH_SIZE, 24);
3988 PUSH2(GLX_STENCIL_SIZE, 4);
3992 PUSH2(GLX_DEPTH_SIZE, 24);
3993 PUSH2(GLX_STENCIL_SIZE, 8);
3997 PUSH2(GLX_DEPTH_SIZE, 32);
4008 cfgs = glXChooseFBConfig(This->display, DefaultScreen(This->display), attribs, &nCfgs);
4012 for (i = 0; i < nCfgs; ++i) {
4013 TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat, debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat), i, cfgs[i]);
4017 if (NULL != This->renderTarget) {
4020 vcheckGLcall("glFlush");
4023 /** very very usefull debug code */
4024 glXSwapBuffers(This->display, This->drawable);
4025 printf("Hit Enter to get next frame ...\n");
4029 glGetIntegerv(GL_READ_BUFFER, &prev_read);
4030 vcheckGLcall("glIntegerv");
4031 glReadBuffer(GL_BACK);
4032 vcheckGLcall("glReadBuffer");
4035 long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel;
4037 if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */
4040 for (j = 0; j < This->renderTarget->myDesc.Height; ++j) {
4042 This->renderTarget->myDesc.Height - j - 1,
4043 This->renderTarget->myDesc.Width,
4045 D3DFmt2GLFmt(This, This->renderTarget->myDesc.Format),
4046 D3DFmt2GLType(This, This->renderTarget->myDesc.Format),
4047 This->renderTarget->allocatedMemory + j * pitch);
4048 vcheckGLcall("glReadPixels");
4051 glReadBuffer(prev_read);
4052 vcheckGLcall("glReadBuffer");
4055 if (BackBufferFormat != This->renderTarget->myDesc.Format &&
4056 StencilBufferFormat != This->stencilBufferTarget->myDesc.Format) {
4058 PUSH2(GLX_PBUFFER_WIDTH, Width);
4059 PUSH2(GLX_PBUFFER_HEIGHT, Height);
4061 This->drawable = glXCreatePbuffer(This->display, cfgs[0], attribs);
4063 This->render_ctx = glXCreateNewContext(This->display, cfgs[0], GLX_RGBA_TYPE, This->glCtx, TRUE);
4064 if (NULL == This->render_ctx) {
4065 ERR("cannot create glxContext\n");
4069 glXSwapBuffers(This->display, This->drawable);
4070 if (glXMakeContextCurrent(This->display, This->drawable, This->drawable, This->render_ctx) == False) {
4071 TRACE("Error in setting current context: context %p drawable %ld (default %ld)!\n", This->glCtx, This->drawable, This->win);
4073 checkGLcall("glXMakeContextCurrent");
4076 tmp = This->renderTarget;
4077 This->renderTarget = (IDirect3DSurface8Impl*) RenderSurface;
4078 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->renderTarget);
4079 IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
4081 tmp = This->stencilBufferTarget;
4082 This->stencilBufferTarget = (IDirect3DSurface8Impl*) StencilSurface;
4083 if (NULL != This->stencilBufferTarget) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->stencilBufferTarget);
4084 if (NULL != tmp) IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
4089 ERR("cannot get valides GLXFBConfig for (%u,%s)/(%u,%s)\n", BackBufferFormat, debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat));