2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the MESA implementation of all the D3D devices that
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
33 #include "wine/debug.h"
35 #include "mesa_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
42 /* They are non-static as they are used by Direct3D in the creation function */
43 const GUID IID_D3DDEVICE_OpenGL = {
47 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
50 #ifndef HAVE_GLEXT_PROTOTYPES
51 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
52 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
53 GLsizei width, GLenum format, GLenum type,
57 const float id_mat[16] = {
64 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
65 D3DPRIMITIVETYPE d3dptPrimitiveType,
66 DWORD d3dvtVertexType,
67 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
74 /* retrieve the X display to use on a given DC */
75 inline static Display *get_display( HDC hdc )
78 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
80 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
81 sizeof(display), (LPSTR)&display )) display = NULL;
87 /* retrieve the X drawable to use on a given DC */
88 inline static Drawable get_drawable( HDC hdc )
91 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
93 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
94 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
100 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
102 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
104 glXSwapBuffers((Display*)display,(Drawable)drawable);
110 /*******************************************************************************
111 * OpenGL static functions
113 static void set_context(IDirect3DDeviceImpl* This)
115 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
118 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
119 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
120 ERR("Error in setting current context (context %p drawable %ld)!\n",
121 glThis->gl_context, glThis->drawable);
126 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
128 pc->dwSize = sizeof(*pc);
129 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
130 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
131 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
132 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
133 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
134 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
135 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
136 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
137 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
138 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
139 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
140 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
141 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
142 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
143 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
144 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
145 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
146 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
147 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
148 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
149 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
150 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
151 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
152 pc->dwStippleWidth = 32;
153 pc->dwStippleHeight = 32;
156 static void fill_opengl_caps(D3DDEVICEDESC *d1)
158 /* GLint maxlight; */
160 d1->dwSize = sizeof(*d1);
161 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
162 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
163 d1->dcmColorModel = D3DCOLOR_RGB;
164 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
165 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
166 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
167 /* D3D 7 capabilities */
168 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
169 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
170 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
171 d1->bClipping = TRUE;
172 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
173 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
174 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
175 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
176 fill_opengl_primcaps(&(d1->dpcLineCaps));
177 fill_opengl_primcaps(&(d1->dpcTriCaps));
178 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
179 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
180 d1->dwMaxBufferSize = 0;
181 d1->dwMaxVertexCount = 65536;
182 d1->dwMinTextureWidth = 1;
183 d1->dwMinTextureHeight = 1;
184 d1->dwMaxTextureWidth = 1024;
185 d1->dwMaxTextureHeight = 1024;
186 d1->dwMinStippleWidth = 1;
187 d1->dwMinStippleHeight = 1;
188 d1->dwMaxStippleWidth = 32;
189 d1->dwMaxStippleHeight = 32;
190 d1->dwMaxTextureRepeat = 16;
191 d1->dwMaxTextureAspectRatio = 1024;
192 d1->dwMaxAnisotropy = 0;
193 d1->dvGuardBandLeft = 0.0;
194 d1->dvGuardBandRight = 0.0;
195 d1->dvGuardBandTop = 0.0;
196 d1->dvGuardBandBottom = 0.0;
197 d1->dvExtentsAdjust = 0.0;
198 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
199 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
200 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
201 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
202 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
203 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
206 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
210 /* Copy first D3D1/2/3 capabilities */
211 fill_opengl_caps(&d1);
213 /* And fill the D3D7 one with it */
214 d->dwDevCaps = d1.dwDevCaps;
215 d->dpcLineCaps = d1.dpcLineCaps;
216 d->dpcTriCaps = d1.dpcTriCaps;
217 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
218 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
219 d->dwMinTextureWidth = d1.dwMinTextureWidth;
220 d->dwMinTextureHeight = d1.dwMinTextureHeight;
221 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
222 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
223 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
224 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
225 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
226 d->dvGuardBandLeft = d1.dvGuardBandLeft;
227 d->dvGuardBandTop = d1.dvGuardBandTop;
228 d->dvGuardBandRight = d1.dvGuardBandRight;
229 d->dvGuardBandBottom = d1.dvGuardBandBottom;
230 d->dvExtentsAdjust = d1.dvExtentsAdjust;
231 d->dwStencilCaps = d1.dwStencilCaps;
232 d->dwFVFCaps = d1.dwFVFCaps;
233 d->dwTextureOpCaps = d1.dwTextureOpCaps;
234 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
235 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
236 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
237 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
238 d->deviceGUID = IID_IDirect3DTnLHalDevice;
239 d->wMaxUserClipPlanes = 1;
240 d->wMaxVertexBlendMatrices = 0;
241 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
242 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
249 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
250 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
252 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
253 const char *ext_string;
254 Mesa_DeviceCapabilities *devcap;
256 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
257 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
260 ext_string = glGetString(GL_EXTENSIONS);
261 /* Query for the ColorTable Extension */
262 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
263 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
264 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
266 TRACE("Color table extension not found.\n");
274 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
276 D3DDEVICEDESC dref, d1, d2;
279 fill_opengl_caps(&dref);
281 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
284 ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
285 if (ret_value != D3DENUMRET_OK)
288 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
291 ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
292 if (ret_value != D3DENUMRET_OK)
295 return D3DENUMRET_OK;
298 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
300 D3DDEVICEDESC7 ddesc;
302 fill_opengl_caps_7(&ddesc);
304 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
306 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
310 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
312 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
313 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
315 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
316 if (!--(This->ref)) {
318 /* Release texture associated with the device */
319 for (i = 0; i < MAX_TEXTURES; i++)
320 if (This->current_texture[i] != NULL)
321 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[i], IDirectDrawSurface7));
323 /* And warn the D3D object that this device is no longer active... */
324 This->d3d->removed_device(This->d3d, This);
326 HeapFree(GetProcessHeap(), 0, This->world_mat);
327 HeapFree(GetProcessHeap(), 0, This->view_mat);
328 HeapFree(GetProcessHeap(), 0, This->proj_mat);
331 glXDestroyContext(glThis->display, glThis->gl_context);
333 HeapFree(GetProcessHeap(), 0, This->clipping_planes);
335 HeapFree(GetProcessHeap(), 0, This);
342 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
343 LPD3DDEVICEDESC lpD3DHWDevDesc,
344 LPD3DDEVICEDESC lpD3DHELDevDesc)
346 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
350 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
352 fill_opengl_caps(&desc);
353 dwSize = lpD3DHWDevDesc->dwSize;
354 memset(lpD3DHWDevDesc, 0, dwSize);
355 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
357 dwSize = lpD3DHELDevDesc->dwSize;
358 memset(lpD3DHELDevDesc, 0, dwSize);
359 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
361 TRACE(" returning caps : (no dump function yet)\n");
366 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
367 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
371 LPDDPIXELFORMAT pformat;
373 /* Do the texture enumeration */
374 sdesc.dwSize = sizeof(DDSURFACEDESC);
375 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
376 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
377 pformat = &(sdesc.ddpfPixelFormat);
378 pformat->dwSize = sizeof(DDPIXELFORMAT);
379 pformat->dwFourCC = 0;
381 TRACE("Enumerating GL_RGBA unpacked (32)\n");
382 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
383 pformat->u1.dwRGBBitCount = 32;
384 pformat->u2.dwRBitMask = 0xFF000000;
385 pformat->u3.dwGBitMask = 0x00FF0000;
386 pformat->u4.dwBBitMask = 0x0000FF00;
387 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
388 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
389 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
391 TRACE("Enumerating GL_RGB unpacked (24)\n");
392 pformat->dwFlags = DDPF_RGB;
393 pformat->u1.dwRGBBitCount = 24;
394 pformat->u2.dwRBitMask = 0x00FF0000;
395 pformat->u3.dwGBitMask = 0x0000FF00;
396 pformat->u4.dwBBitMask = 0x000000FF;
397 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
398 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
399 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
401 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
402 pformat->dwFlags = DDPF_RGB;
403 pformat->u1.dwRGBBitCount = 16;
404 pformat->u2.dwRBitMask = 0x0000F800;
405 pformat->u3.dwGBitMask = 0x000007E0;
406 pformat->u4.dwBBitMask = 0x0000001F;
407 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
408 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
409 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
411 /* Note : even if this is an 'emulated' texture format, it needs to be first
412 as some dumb applications seem to rely on that. */
413 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n");
414 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
415 pformat->u1.dwRGBBitCount = 16;
416 pformat->u2.dwRBitMask = 0x00007C00;
417 pformat->u3.dwGBitMask = 0x000003E0;
418 pformat->u4.dwBBitMask = 0x0000001F;
419 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
420 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
421 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
423 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
424 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
425 pformat->u1.dwRGBBitCount = 16;
426 pformat->u2.dwRBitMask = 0x00000F00;
427 pformat->u3.dwGBitMask = 0x000000F0;
428 pformat->u4.dwBBitMask = 0x0000000F;
429 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
430 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
431 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
434 /* This is a compromise : some games choose the first 16 bit texture format with alpha they
435 find enumerated, others the last one. And both want to have the ARGB one.
437 So basically, forget our OpenGL roots and do not even enumerate our RGBA ones.
439 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
440 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
441 pformat->u1.dwRGBBitCount = 16;
442 pformat->u2.dwRBitMask = 0x0000F000;
443 pformat->u3.dwGBitMask = 0x00000F00;
444 pformat->u4.dwBBitMask = 0x000000F0;
445 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
446 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
447 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
449 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
450 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
451 pformat->u1.dwRGBBitCount = 16;
452 pformat->u2.dwRBitMask = 0x0000F800;
453 pformat->u3.dwGBitMask = 0x000007C0;
454 pformat->u4.dwBBitMask = 0x0000003E;
455 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
456 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
457 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
460 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
461 pformat->dwFlags = DDPF_RGB;
462 pformat->u1.dwRGBBitCount = 8;
463 pformat->u2.dwRBitMask = 0x000000E0;
464 pformat->u3.dwGBitMask = 0x0000001C;
465 pformat->u4.dwBBitMask = 0x00000003;
466 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
467 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
468 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
470 TRACE("Enumerating Paletted (8)\n");
471 pformat->dwFlags = DDPF_PALETTEINDEXED8;
472 pformat->u1.dwRGBBitCount = 8;
473 pformat->u2.dwRBitMask = 0x00000000;
474 pformat->u3.dwGBitMask = 0x00000000;
475 pformat->u4.dwBBitMask = 0x00000000;
476 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
477 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
478 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
480 TRACE("End of enumeration\n");
486 d3ddevice_find(IDirect3DImpl *d3d,
487 LPD3DFINDDEVICESEARCH lpD3DDFS,
488 LPD3DFINDDEVICERESULT lplpD3DDevice)
492 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
493 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
494 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
495 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
497 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
498 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
499 if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
500 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0) &&
501 (IsEqualGUID(&IID_IDirect3DRefDevice, &(lpD3DDFS->guid)) == 0)) {
502 TRACE(" no match for this GUID.\n");
503 return DDERR_INVALIDPARAMS;
507 /* Now return our own GUID */
508 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
509 fill_opengl_caps(&desc);
510 lplpD3DDevice->ddHwDesc = desc;
511 lplpD3DDevice->ddSwDesc = desc;
513 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
519 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
520 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
523 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
524 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
525 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
529 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
530 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
533 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
534 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
535 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
539 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
540 D3DRENDERSTATETYPE dwRenderStateType,
543 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
544 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
546 /* Call the render state functions */
547 store_render_state(This, dwRenderStateType, dwRenderState, &This->state_block);
548 set_render_state(This, dwRenderStateType, &This->state_block);
554 GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
555 D3DRENDERSTATETYPE dwRenderStateType,
556 LPDWORD lpdwRenderState)
558 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
559 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState);
561 /* Call the render state functions */
562 get_render_state(This, dwRenderStateType, lpdwRenderState, &This->state_block);
564 TRACE(" - asked for rendering state : %s, returning value %08lx.\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
570 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
571 D3DLIGHTSTATETYPE dwLightStateType,
574 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
576 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
578 if (!dwLightStateType && (dwLightStateType > D3DLIGHTSTATE_COLORVERTEX))
579 TRACE("Unexpected Light State Type\n");
580 return DDERR_INVALIDPARAMS;
582 if (dwLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) {
583 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
590 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
592 } else if (dwLightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) {
593 switch (dwLightState) {
595 ERR("DDCOLOR_MONO should not happend!\n");
598 /* We are already in this mode */
601 ERR("Unknown color model!\n");
605 D3DRENDERSTATETYPE rs;
606 switch (dwLightStateType) {
608 case D3DLIGHTSTATE_AMBIENT: /* 2 */
609 rs = D3DRENDERSTATE_AMBIENT;
611 case D3DLIGHTSTATE_FOGMODE: /* 4 */
612 rs = D3DRENDERSTATE_FOGVERTEXMODE;
614 case D3DLIGHTSTATE_FOGSTART: /* 5 */
615 rs = D3DRENDERSTATE_FOGSTART;
617 case D3DLIGHTSTATE_FOGEND: /* 6 */
618 rs = D3DRENDERSTATE_FOGEND;
620 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
621 rs = D3DRENDERSTATE_FOGDENSITY;
623 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
624 rs = D3DRENDERSTATE_COLORVERTEX;
630 IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
637 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
640 case D3DPT_POINTLIST:
641 TRACE("Start POINTS\n");
646 TRACE("Start LINES\n");
650 case D3DPT_LINESTRIP:
651 TRACE("Start LINE_STRIP\n");
652 glBegin(GL_LINE_STRIP);
655 case D3DPT_TRIANGLELIST:
656 TRACE("Start TRIANGLES\n");
657 glBegin(GL_TRIANGLES);
660 case D3DPT_TRIANGLESTRIP:
661 TRACE("Start TRIANGLE_STRIP\n");
662 glBegin(GL_TRIANGLE_STRIP);
665 case D3DPT_TRIANGLEFAN:
666 TRACE("Start TRIANGLE_FAN\n");
667 glBegin(GL_TRIANGLE_FAN);
671 TRACE("Unhandled primitive\n");
676 /* This function calculate the Z coordinate from Zproj */
677 static float ZfromZproj(IDirect3DDeviceImpl *This, D3DVALUE Zproj)
680 /* Assume that X = Y = 0 and W = 1 */
681 a = This->proj_mat->_33;
682 b = This->proj_mat->_34;
683 c = This->proj_mat->_43;
684 d = This->proj_mat->_44;
685 /* We have in homogenous coordinates Z' = a * Z + c and W' = b * Z + d
686 * So in non homogenous coordinates we have Zproj = (a * Z + c) / (b * Z + d)
687 * And finally Z = (d * Zproj - c) / (a - b * Zproj)
689 return (d*Zproj - c) / (a - b*Zproj);
692 static void build_fog_table(BYTE *fog_table, DWORD fog_color) {
695 TRACE(" rebuilding fog table (%06lx)...\n", fog_color & 0x00FFFFFF);
697 for (i = 0; i < 3; i++) {
698 BYTE fog_color_component = (fog_color >> (8 * i)) & 0xFF;
700 for (elt = 0; elt < 0x10000; elt++) {
701 /* We apply the fog transformation and cache the result */
702 DWORD fog_intensity = elt & 0xFF;
703 DWORD vertex_color = (elt >> 8) & 0xFF;
704 fog_table[(i * 0x10000) + elt] = ((fog_intensity * vertex_color) + ((0xFF - fog_intensity) * fog_color_component)) / 0xFF;
709 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
710 BOOLEAN vertex_transformed,
711 BOOLEAN vertex_lit) {
712 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
714 /* Puts GL in the correct lighting / transformation mode */
715 if ((vertex_transformed == FALSE) &&
716 (glThis->transform_state != GL_TRANSFORM_NORMAL)) {
717 /* Need to put the correct transformation again if we go from Transformed
718 vertices to non-transformed ones.
720 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
721 This->world_mat, This->view_mat, This->proj_mat);
722 glThis->transform_state = GL_TRANSFORM_NORMAL;
724 } else if ((vertex_transformed == TRUE) &&
725 (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
726 /* Set our orthographic projection */
727 glThis->transform_state = GL_TRANSFORM_ORTHO;
728 d3ddevice_set_ortho(This);
731 /* TODO: optimize this to not always reset all the fog stuff on all DrawPrimitive call
732 if no fogging state change occured */
733 if (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE) {
734 if (vertex_transformed == TRUE) {
736 /* Now check if our fog_table still corresponds to the current vertex color.
737 Element '0x..00' is always the fog color as it corresponds to maximum fog intensity */
738 if ((glThis->fog_table[0 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >> 0) & 0xFF)) ||
739 (glThis->fog_table[1 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >> 8) & 0xFF)) ||
740 (glThis->fog_table[2 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >> 16) & 0xFF))) {
741 /* We need to rebuild our fog table.... */
742 build_fog_table(glThis->fog_table, This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1]);
745 if (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1] != D3DFOG_NONE) {
746 switch (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1]) {
747 case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); break;
748 case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); break;
749 case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); break;
751 if (vertex_lit == FALSE) {
752 glFogf(GL_FOG_START, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]);
753 glFogf(GL_FOG_END, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]);
755 /* Special case of 'pixel fog' */
756 glFogf(GL_FOG_START, ZfromZproj(This, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]));
757 glFogf(GL_FOG_END, ZfromZproj(This, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]));
768 /* Handle the 'no-normal' case */
769 if ((vertex_lit == FALSE) && (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE))
770 glEnable(GL_LIGHTING);
772 glDisable(GL_LIGHTING);
774 /* Handle the code for pre-vertex material properties */
775 if (vertex_transformed == FALSE) {
776 if ((This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) &&
777 (This->state_block.render_state[D3DRENDERSTATE_COLORVERTEX - 1] == TRUE)) {
778 if ((This->state_block.render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
779 (This->state_block.render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
780 (This->state_block.render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
781 (This->state_block.render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] != D3DMCS_MATERIAL)) {
782 glEnable(GL_COLOR_MATERIAL);
789 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
790 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
792 D3DDRAWPRIMITIVESTRIDEDDATA strided;
796 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
797 strided.position.dwStride = sizeof(D3DVERTEX);
798 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
799 strided.normal.dwStride = sizeof(D3DVERTEX);
800 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
801 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
802 draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
805 case D3DVT_LVERTEX: {
806 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
807 strided.position.dwStride = sizeof(D3DLVERTEX);
808 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
809 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
810 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
811 strided.specular.dwStride = sizeof(D3DLVERTEX);
812 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
813 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
814 draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
817 case D3DVT_TLVERTEX: {
818 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
819 strided.position.dwStride = sizeof(D3DTLVERTEX);
820 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
821 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
822 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
823 strided.specular.dwStride = sizeof(D3DTLVERTEX);
824 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
825 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
826 draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
830 FIXME("Unhandled vertex type\n");
836 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
837 D3DPRIMITIVETYPE d3dptPrimitiveType,
838 D3DVERTEXTYPE d3dvtVertexType,
843 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
845 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
846 if (TRACE_ON(ddraw)) {
847 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
850 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
856 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
857 D3DPRIMITIVETYPE d3dptPrimitiveType,
858 D3DVERTEXTYPE d3dvtVertexType,
865 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
866 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
867 if (TRACE_ON(ddraw)) {
868 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
871 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
877 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
878 LPD3DEXECUTEBUFFERDESC lpDesc,
879 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
882 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
883 IDirect3DExecuteBufferImpl *ret;
886 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
888 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
889 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
891 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
896 /* These are the various handler used in the generic path */
897 inline static void handle_xyz(D3DVALUE *coords) {
900 inline static void handle_xyzrhw(D3DVALUE *coords) {
901 if (coords[3] < 1e-8)
904 GLfloat w = 1.0 / coords[3];
906 glVertex4f(coords[0] * w,
912 inline static void handle_normal(D3DVALUE *coords) {
916 inline static void handle_diffuse_base(STATEBLOCK *sb, DWORD *color) {
917 if ((sb->render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] == TRUE) ||
918 (sb->render_state[D3DRENDERSTATE_ALPHABLENDENABLE - 1] == TRUE)) {
919 glColor4ub((*color >> 16) & 0xFF,
920 (*color >> 8) & 0xFF,
921 (*color >> 0) & 0xFF,
922 (*color >> 24) & 0xFF);
924 glColor3ub((*color >> 16) & 0xFF,
925 (*color >> 8) & 0xFF,
926 (*color >> 0) & 0xFF);
930 inline static void handle_specular_base(STATEBLOCK *sb, DWORD *color) {
931 glColor4ub((*color >> 16) & 0xFF,
932 (*color >> 8) & 0xFF,
933 (*color >> 0) & 0xFF,
934 (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
937 inline static void handle_diffuse(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
938 if ((lighted == FALSE) &&
939 (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) &&
940 (sb->render_state[D3DRENDERSTATE_COLORVERTEX - 1] == TRUE)) {
941 if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
942 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
943 handle_diffuse_base(sb, color);
945 if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
946 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
947 handle_diffuse_base(sb, color);
949 if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR1) &&
950 (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
951 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
952 handle_diffuse_base(sb, color);
954 if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
955 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
956 handle_diffuse_base(sb, color);
959 handle_diffuse_base(sb, color);
963 inline static void handle_specular(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
964 if ((lighted == FALSE) &&
965 (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) &&
966 (sb->render_state[D3DRENDERSTATE_COLORVERTEX - 1] == TRUE)) {
967 if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
968 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
969 handle_specular_base(sb, color);
971 if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
972 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
973 handle_specular_base(sb, color);
975 if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR2) &&
976 (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
977 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
978 handle_specular_base(sb, color);
980 if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
981 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
982 handle_specular_base(sb, color);
985 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
988 inline static void handle_diffuse_and_specular(STATEBLOCK *sb, BYTE *fog_table, DWORD *color_d, DWORD *color_s, BOOLEAN lighted) {
989 if (lighted == TRUE) {
990 DWORD color = *color_d;
991 if (sb->render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE) {
992 /* Special case where the specular value is used to do fogging */
993 BYTE fog_intensity = *color_s >> 24; /* The alpha value of the specular component is the fog 'intensity' for this vertex */
994 color &= 0xFF000000; /* Only keep the alpha component */
995 color |= fog_table[((*color_d >> 0) & 0xFF) << 8 | fog_intensity] << 0;
996 color |= fog_table[((*color_d >> 8) & 0xFF) << 8 | fog_intensity] << 8;
997 color |= fog_table[((*color_d >> 16) & 0xFF) << 8 | fog_intensity] << 16;
999 if (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE) {
1000 /* Standard specular value in transformed mode. TODO */
1002 handle_diffuse_base(sb, &color);
1004 if (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) {
1005 handle_diffuse(sb, color_d, FALSE);
1006 handle_specular(sb, color_s, FALSE);
1008 /* In that case, only put the diffuse color... */
1009 handle_diffuse_base(sb, color_d);
1014 inline static void handle_texture(D3DVALUE *coords) {
1015 glTexCoord2fv(coords);
1017 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
1018 /* For the moment, draw only the first texture.. */
1019 if (tex_index == 0) glTexCoord2fv(coords);
1022 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
1023 D3DPRIMITIVETYPE d3dptPrimitiveType,
1024 DWORD d3dvtVertexType,
1025 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1026 DWORD dwStartVertex,
1027 DWORD dwVertexCount,
1032 BOOLEAN vertex_lighted = (d3dvtVertexType & D3DFVF_NORMAL) == 0;
1033 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
1035 if (TRACE_ON(ddraw)) {
1036 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
1040 draw_primitive_handle_GL_state(This,
1041 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
1043 draw_primitive_start_GL(d3dptPrimitiveType);
1045 /* Some fast paths first before the generic case.... */
1046 if (d3dvtVertexType == D3DFVF_VERTEX) {
1049 for (index = 0; index < dwIndexCount; index++) {
1050 int i = (dwIndices == NULL) ? index : dwIndices[index];
1052 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1053 D3DVALUE *tex_coord =
1054 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1055 D3DVALUE *position =
1056 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1058 handle_normal(normal);
1059 handle_texture(tex_coord);
1060 handle_xyz(position);
1062 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
1063 position[0], position[1], position[2],
1064 normal[0], normal[1], normal[2],
1065 tex_coord[0], tex_coord[1]);
1067 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
1070 for (index = 0; index < dwIndexCount; index++) {
1071 int i = (dwIndices == NULL) ? index : dwIndices[index];
1073 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1075 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1076 D3DVALUE *tex_coord =
1077 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1078 D3DVALUE *position =
1079 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1081 handle_diffuse_and_specular(&(This->state_block), glThis->fog_table, color_d, color_s, TRUE);
1082 handle_texture(tex_coord);
1083 handle_xyzrhw(position);
1085 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1086 position[0], position[1], position[2], position[3],
1087 (*color_d >> 16) & 0xFF,
1088 (*color_d >> 8) & 0xFF,
1089 (*color_d >> 0) & 0xFF,
1090 (*color_d >> 24) & 0xFF,
1091 (*color_s >> 16) & 0xFF,
1092 (*color_s >> 8) & 0xFF,
1093 (*color_s >> 0) & 0xFF,
1094 (*color_s >> 24) & 0xFF,
1095 tex_coord[0], tex_coord[1]);
1097 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1098 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1099 /* This is the 'slow path' but that should support all possible vertex formats out there...
1100 Note that people should write a fast path for all vertex formats out there...
1103 for (index = 0; index < dwIndexCount; index++) {
1104 int i = (dwIndices == NULL) ? index : dwIndices[index];
1106 if (d3dvtVertexType & D3DFVF_NORMAL) {
1108 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1109 handle_normal(normal);
1111 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1113 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1115 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1116 handle_diffuse_and_specular(&(This->state_block), glThis->fog_table, color_d, color_s, vertex_lighted);
1118 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1120 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1121 handle_specular(&(This->state_block), color_s, vertex_lighted);
1122 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1124 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1125 handle_diffuse(&(This->state_block), color_d, vertex_lighted);
1129 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1130 /* Special case for single texture... */
1131 D3DVALUE *tex_coord =
1132 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1133 handle_texture(tex_coord);
1136 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1137 D3DVALUE *tex_coord =
1138 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1139 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1140 handle_textures(tex_coord, tex_index);
1143 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1144 D3DVALUE *position =
1145 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1146 handle_xyz(position);
1147 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1148 D3DVALUE *position =
1149 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1150 handle_xyzrhw(position);
1153 if (TRACE_ON(ddraw)) {
1156 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1157 D3DVALUE *position =
1158 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1159 TRACE(" %f %f %f", position[0], position[1], position[2]);
1160 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1161 D3DVALUE *position =
1162 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1163 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1165 if (d3dvtVertexType & D3DFVF_NORMAL) {
1167 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1168 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1170 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1172 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1173 DPRINTF(" / %02lx %02lx %02lx %02lx",
1174 (*color_d >> 16) & 0xFF,
1175 (*color_d >> 8) & 0xFF,
1176 (*color_d >> 0) & 0xFF,
1177 (*color_d >> 24) & 0xFF);
1179 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1181 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1182 DPRINTF(" / %02lx %02lx %02lx %02lx",
1183 (*color_s >> 16) & 0xFF,
1184 (*color_s >> 8) & 0xFF,
1185 (*color_s >> 0) & 0xFF,
1186 (*color_s >> 24) & 0xFF);
1188 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1189 D3DVALUE *tex_coord =
1190 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1191 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1192 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1198 ERR(" matrix weighting not handled yet....\n");
1203 /* Whatever the case, disable the color material stuff */
1204 glDisable(GL_COLOR_MATERIAL);
1211 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1212 D3DPRIMITIVETYPE d3dptPrimitiveType,
1213 DWORD d3dvtVertexType,
1215 DWORD dwVertexCount,
1218 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1219 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1221 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1222 if (TRACE_ON(ddraw)) {
1223 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1226 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1227 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1233 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1234 D3DPRIMITIVETYPE d3dptPrimitiveType,
1235 DWORD d3dvtVertexType,
1237 DWORD dwVertexCount,
1242 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1243 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1245 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1246 if (TRACE_ON(ddraw)) {
1247 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1250 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1251 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1257 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1258 D3DPRIMITIVETYPE d3dptPrimitiveType,
1260 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1261 DWORD dwVertexCount,
1264 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1266 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1267 if (TRACE_ON(ddraw)) {
1268 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1270 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1276 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1277 D3DPRIMITIVETYPE d3dptPrimitiveType,
1279 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1280 DWORD dwVertexCount,
1285 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1287 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1288 if (TRACE_ON(ddraw)) {
1289 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1292 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1298 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1299 D3DPRIMITIVETYPE d3dptPrimitiveType,
1300 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1301 DWORD dwStartVertex,
1302 DWORD dwNumVertices,
1305 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1306 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1307 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1309 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1310 if (TRACE_ON(ddraw)) {
1311 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1314 if (vb_impl->processed == TRUE) {
1315 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1316 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1318 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1319 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1320 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1322 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1323 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1326 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1327 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1334 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1335 D3DPRIMITIVETYPE d3dptPrimitiveType,
1336 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1337 DWORD dwStartVertex,
1338 DWORD dwNumVertices,
1343 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1344 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1345 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1347 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1348 if (TRACE_ON(ddraw)) {
1349 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1352 if (vb_impl->processed == TRUE) {
1353 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1354 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1356 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1357 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1358 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1360 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1361 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1364 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1365 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1372 convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwState)
1378 gl_state = GL_NEAREST;
1381 gl_state = GL_LINEAR;
1384 gl_state = GL_LINEAR;
1391 convert_mag_filter_to_GL(D3DTEXTUREMAGFILTER dwState)
1397 gl_state = GL_NEAREST;
1400 gl_state = GL_LINEAR;
1403 gl_state = GL_LINEAR;
1410 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1412 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1415 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1417 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1419 if (dwStage > 0) return DD_OK; /* We nothing in this case for now */
1421 if (TRACE_ON(ddraw)) {
1422 TRACE(" Stage type is : ");
1423 switch (d3dTexStageStateType) {
1424 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1425 GEN_CASE(D3DTSS_COLOROP);
1426 GEN_CASE(D3DTSS_COLORARG1);
1427 GEN_CASE(D3DTSS_COLORARG2);
1428 GEN_CASE(D3DTSS_ALPHAOP);
1429 GEN_CASE(D3DTSS_ALPHAARG1);
1430 GEN_CASE(D3DTSS_ALPHAARG2);
1431 GEN_CASE(D3DTSS_BUMPENVMAT00);
1432 GEN_CASE(D3DTSS_BUMPENVMAT01);
1433 GEN_CASE(D3DTSS_BUMPENVMAT10);
1434 GEN_CASE(D3DTSS_BUMPENVMAT11);
1435 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1436 GEN_CASE(D3DTSS_ADDRESS);
1437 GEN_CASE(D3DTSS_ADDRESSU);
1438 GEN_CASE(D3DTSS_ADDRESSV);
1439 GEN_CASE(D3DTSS_BORDERCOLOR);
1440 GEN_CASE(D3DTSS_MAGFILTER);
1441 GEN_CASE(D3DTSS_MINFILTER);
1442 GEN_CASE(D3DTSS_MIPFILTER);
1443 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1444 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1445 GEN_CASE(D3DTSS_MAXANISOTROPY);
1446 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1447 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1448 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1450 default: DPRINTF("UNKNOWN !!!");
1455 switch (d3dTexStageStateType) {
1456 case D3DTSS_MINFILTER:
1457 if (TRACE_ON(ddraw)) {
1458 switch ((D3DTEXTUREMINFILTER) dwState) {
1459 case D3DTFN_POINT: DPRINTF("D3DTFN_POINT\n"); break;
1460 case D3DTFN_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
1461 default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
1464 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert_min_filter_to_GL(dwState));
1467 case D3DTSS_MAGFILTER:
1468 if (TRACE_ON(ddraw)) {
1469 switch ((D3DTEXTUREMAGFILTER) dwState) {
1470 case D3DTFG_POINT: DPRINTF("D3DTFN_POINT\n"); break;
1471 case D3DTFG_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
1472 default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
1475 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert_mag_filter_to_GL(dwState));
1478 case D3DTSS_ADDRESS:
1479 case D3DTSS_ADDRESSU:
1480 case D3DTSS_ADDRESSV: {
1481 GLenum arg = GL_REPEAT; /* Default value */
1482 switch ((D3DTEXTUREADDRESS) dwState) {
1483 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1484 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1485 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1486 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1488 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1489 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1490 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1491 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1492 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1493 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1497 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1500 This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState;
1501 /* Some special cases when one state modifies more than one... */
1502 if (d3dTexStageStateType == D3DTSS_ADDRESS) {
1503 This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState;
1504 This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState;
1511 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1513 LPDIRECTDRAWSURFACE7 lpTexture2)
1515 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1517 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1519 if (dwStage > 0) return DD_OK;
1521 if (This->current_texture[dwStage] != NULL) {
1522 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7));
1526 if (lpTexture2 == NULL) {
1527 This->current_texture[dwStage] = NULL;
1529 TRACE(" disabling 2D texturing.\n");
1530 glBindTexture(GL_TEXTURE_2D, 0);
1531 glDisable(GL_TEXTURE_2D);
1533 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1535 This->current_texture[dwStage] = tex_impl;
1536 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1538 glEnable(GL_TEXTURE_2D);
1539 gltex_upload_texture(tex_impl);
1541 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1542 convert_mag_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MAGFILTER - 1]));
1543 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1544 convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1]));
1552 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1553 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1555 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1556 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1558 fill_opengl_caps_7(lpD3DHELDevDesc);
1560 TRACE(" returning caps : no dump function yet.\n");
1566 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1567 LPD3DMATERIAL7 lpMat)
1569 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1570 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1572 if (TRACE_ON(ddraw)) {
1573 TRACE(" material is : \n");
1574 dump_D3DMATERIAL7(lpMat);
1577 This->current_material = *lpMat;
1579 glMaterialfv(GL_FRONT_AND_BACK,
1581 (float *) &(This->current_material.u.diffuse));
1582 glMaterialfv(GL_FRONT_AND_BACK,
1584 (float *) &(This->current_material.u1.ambient));
1585 glMaterialfv(GL_FRONT_AND_BACK,
1587 (float *) &(This->current_material.u2.specular));
1588 glMaterialfv(GL_FRONT_AND_BACK,
1590 (float *) &(This->current_material.u3.emissive));
1591 glMaterialf(GL_FRONT_AND_BACK,
1593 This->current_material.u4.power); /* Not sure about this... */
1600 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1602 LPD3DLIGHT7 lpLight)
1604 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1605 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1607 if (TRACE_ON(ddraw)) {
1608 TRACE(" setting light : \n");
1609 dump_D3DLIGHT7(lpLight);
1612 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1613 This->set_lights |= 0x00000001 << dwLightIndex;
1614 This->light_parameters[dwLightIndex] = *lpLight;
1616 switch (lpLight->dltType) {
1617 case D3DLIGHT_DIRECTIONAL: {
1619 float cut_off = 180.0;
1621 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1622 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1623 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1624 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1626 direction[0] = lpLight->dvDirection.u1.x;
1627 direction[1] = lpLight->dvDirection.u2.y;
1628 direction[2] = lpLight->dvDirection.u3.z;
1630 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1633 case D3DLIGHT_POINT: {
1635 float cut_off = 180.0;
1637 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1638 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1639 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1640 position[0] = lpLight->dvPosition.u1.x;
1641 position[1] = lpLight->dvPosition.u2.y;
1642 position[2] = lpLight->dvPosition.u3.z;
1644 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1645 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1646 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1647 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1648 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1651 case D3DLIGHT_SPOT: {
1654 float cut_off = 90.0 * (lpLight->dvPhi / M_PI);
1656 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1657 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1658 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1660 direction[0] = lpLight->dvDirection.u1.x;
1661 direction[1] = lpLight->dvDirection.u2.y;
1662 direction[2] = lpLight->dvDirection.u3.z;
1664 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_DIRECTION, (float *) direction);
1665 position[0] = lpLight->dvPosition.u1.x;
1666 position[1] = lpLight->dvPosition.u2.y;
1667 position[2] = lpLight->dvPosition.u3.z;
1669 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1670 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1671 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1672 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1673 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1674 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_EXPONENT, &(lpLight->dvFalloff));
1675 if ((lpLight->dvTheta != 0.0) || (lpLight->dvTheta != lpLight->dvPhi)) {
1676 WARN("dvTheta not fully supported yet !\n");
1680 default: WARN(" light type not handled yet...\n");
1687 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1691 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1692 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1694 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1697 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1698 /* Set the default parameters.. */
1699 TRACE(" setting default light parameters...\n");
1700 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1702 glEnable(GL_LIGHT0 + dwLightIndex);
1704 glDisable(GL_LIGHT0 + dwLightIndex);
1711 GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, CONST D3DVALUE* pPlaneEquation)
1713 ICOM_THIS(IDirect3DDeviceImpl,iface);
1716 TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
1718 if (dwIndex>=This->max_clipping_planes) {
1719 return DDERR_INVALIDPARAMS;
1722 TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] );
1724 memcpy( This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4]));
1725 plane[0] = pPlaneEquation[0];
1726 plane[1] = pPlaneEquation[1];
1727 plane[2] = pPlaneEquation[2];
1728 plane[3] = pPlaneEquation[3];
1730 /* XXX: is here also code needed to handle the transformation of the world? */
1731 glClipPlane( GL_CLIP_PLANE0+dwIndex, (const GLdouble*)(&plane) );
1736 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1737 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1739 # define XCAST(fun) (void*)
1742 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1744 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1745 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1746 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1747 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1748 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1749 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1750 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1751 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1752 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1753 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1754 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1755 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1756 XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1757 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1758 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1759 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1760 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1761 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1762 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1763 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1764 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1765 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1766 XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1767 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1768 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1769 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1770 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1771 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1772 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1773 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1774 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1775 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1776 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1777 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1778 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1779 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1780 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1781 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1782 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1783 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1784 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1785 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1786 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1787 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1788 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1789 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1790 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1791 XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane,
1792 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1793 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1796 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1801 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1802 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1804 # define XCAST(fun) (void*)
1807 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1809 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1810 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1811 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1812 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1813 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1814 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1815 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1816 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1817 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1818 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1819 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1820 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1821 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1822 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1823 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1824 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1825 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1826 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1827 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1828 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1829 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1830 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1831 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1832 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1833 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1834 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1835 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1836 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1837 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1838 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1839 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1840 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1841 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1842 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1843 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1844 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1845 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1846 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1847 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1848 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1849 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1850 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1851 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1854 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1859 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1860 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1862 # define XCAST(fun) (void*)
1865 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1867 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1868 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1869 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1870 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1871 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1872 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
1873 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1874 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1875 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1876 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1877 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1878 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1879 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1880 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1881 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1882 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1883 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1884 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1885 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1886 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1887 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1888 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1889 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1890 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1891 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1892 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1893 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1894 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1895 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1896 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1897 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1898 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1899 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1900 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1903 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1908 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1909 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1911 # define XCAST(fun) (void*)
1914 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1916 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1917 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1918 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1919 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1920 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1921 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1922 XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
1923 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1924 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1925 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1926 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1927 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1928 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1929 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1930 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1931 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1932 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1933 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1934 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1935 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1936 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1937 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1938 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1941 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1945 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1954 GLfloat old_z_clear_value;
1955 GLbitfield bitfield = 0;
1956 GLint old_stencil_clear_value;
1957 GLfloat old_color_clear_value[4];
1959 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1960 if (TRACE_ON(ddraw)) {
1963 TRACE(" rectangles : \n");
1964 for (i = 0; i < dwCount; i++) {
1965 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1971 WARN(" Warning, this function only for now clears the whole screen...\n");
1974 /* Clears the screen */
1976 if (dwFlags & D3DCLEAR_ZBUFFER) {
1977 bitfield |= GL_DEPTH_BUFFER_BIT;
1978 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1979 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1980 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1982 TRACE(" depth value : %f\n", dvZ);
1984 if (dwFlags & D3DCLEAR_STENCIL) {
1985 bitfield |= GL_STENCIL_BUFFER_BIT;
1986 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1987 glClearStencil(dwStencil);
1988 TRACE(" stencil value : %ld\n", dwStencil);
1990 if (dwFlags & D3DCLEAR_TARGET) {
1991 bitfield |= GL_COLOR_BUFFER_BIT;
1992 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1993 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1994 ((dwColor >> 8) & 0xFF) / 255.0,
1995 ((dwColor >> 0) & 0xFF) / 255.0,
1996 ((dwColor >> 24) & 0xFF) / 255.0);
1997 TRACE(" color value (ARGB) : %08lx\n", dwColor);
2002 if (dwFlags & D3DCLEAR_ZBUFFER) {
2004 glClearDepth(old_z_clear_value);
2006 if (dwFlags & D3DCLEAR_STENCIL) {
2007 bitfield |= GL_STENCIL_BUFFER_BIT;
2008 glClearStencil(old_stencil_clear_value);
2010 if (dwFlags & D3DCLEAR_TARGET) {
2011 bitfield |= GL_COLOR_BUFFER_BIT;
2012 glClearColor(old_color_clear_value[0],
2013 old_color_clear_value[1],
2014 old_color_clear_value[2],
2015 old_color_clear_value[3]);
2024 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
2025 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
2026 DWORD dwFlags, LPDDBLTFX lpbltfx)
2028 if (dwFlags & DDBLT_COLORFILL) {
2029 /* This is easy to handle for the D3D Device... */
2030 DWORD color = lpbltfx->u5.dwFillColor;
2031 TRACE(" executing D3D Device override.\n");
2032 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
2035 return DDERR_INVALIDPARAMS;
2039 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
2040 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
2041 LPRECT rsrc, DWORD trans)
2043 return DDERR_INVALIDPARAMS;
2047 d3ddevice_set_ortho(IDirect3DDeviceImpl *This)
2049 GLfloat height, width;
2050 GLfloat trans_mat[16];
2052 width = This->surface->surface_desc.dwWidth;
2053 height = This->surface->surface_desc.dwHeight;
2055 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
2056 to OpenGL screen coordinates (ie the upper left corner is not the same).
2057 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
2058 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
2059 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
2060 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
2061 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
2062 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
2064 glMatrixMode(GL_MODELVIEW);
2066 glMatrixMode(GL_PROJECTION);
2067 glLoadMatrixf(trans_mat);
2071 d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
2072 D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
2074 if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
2075 glMatrixMode(GL_MODELVIEW);
2076 glLoadMatrixf((float *) view_mat);
2077 glMultMatrixf((float *) world_mat);
2079 if ((matrices & PROJMAT_CHANGED) != 0) {
2080 glMatrixMode(GL_PROJECTION);
2081 glLoadMatrixf((float *) proj_mat);
2086 d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
2088 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
2089 if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
2090 /* This will force an update of the transform state at the next drawing. */
2091 glThis->transform_state = GL_TRANSFORM_NONE;
2095 /* TODO for both these functions :
2096 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
2097 by other OpenGL code in D3D
2098 - handle the case where no 'Begin / EndScene' was done between two locks
2099 - handle the rectangles in the unlock too
2100 - handle pitch correctly...
2102 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
2104 /* First, check if we need to do anything */
2105 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
2112 glGetIntegerv(GL_READ_BUFFER, &prev_read);
2115 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
2116 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2117 /* Application wants to lock the front buffer */
2118 glReadBuffer(GL_FRONT);
2119 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2120 /* Application wants to lock the back buffer */
2121 glReadBuffer(GL_BACK);
2123 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
2126 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2127 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2129 WARN(" unsupported pixel format.\n");
2133 if (pRect == NULL) {
2136 loc_rect.bottom = This->surface_desc.dwHeight;
2137 loc_rect.right = This->surface_desc.dwWidth;
2141 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
2142 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
2143 + loc_rect.top * This->surface_desc.u1.lPitch
2144 + loc_rect.left * GET_BPP(This->surface_desc)));
2145 glReadBuffer(prev_read);
2150 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
2152 /* First, check if we need to do anything */
2153 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
2159 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
2161 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
2162 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2163 /* Application wants to lock the front buffer */
2164 glDrawBuffer(GL_FRONT);
2165 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2166 /* Application wants to lock the back buffer */
2167 glDrawBuffer(GL_BACK);
2169 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
2172 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2173 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2175 WARN(" unsupported pixel format.\n");
2179 glRasterPos2f(0.0, 0.0);
2180 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
2181 GL_RGB, buffer_type, This->surface_desc.lpSurface);
2182 glDrawBuffer(prev_draw);
2189 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
2191 IDirect3DDeviceImpl *object;
2192 IDirect3DDeviceGLImpl *gl_object;
2193 IDirectDrawSurfaceImpl *surf;
2197 XVisualInfo template;
2198 GLenum buffer = GL_FRONT;
2200 GLint max_clipping_planes = 0;
2202 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
2203 if (object == NULL) return DDERR_OUTOFMEMORY;
2205 gl_object = (IDirect3DDeviceGLImpl *) object;
2209 object->surface = surface;
2210 object->set_context = set_context;
2211 object->clear = d3ddevice_clear;
2212 object->set_matrices = d3ddevice_set_matrices;
2213 object->matrices_updated = d3ddevice_matrices_updated;
2215 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
2217 device_context = GetDC(surface->ddraw_owner->window);
2218 gl_object->display = get_display(device_context);
2219 gl_object->drawable = get_drawable(device_context);
2220 ReleaseDC(surface->ddraw_owner->window,device_context);
2223 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2224 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2226 HeapFree(GetProcessHeap(), 0, object);
2227 ERR("No visual found !\n");
2229 return DDERR_INVALIDPARAMS;
2231 TRACE(" visual found\n");
2234 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2237 if (gl_object->gl_context == NULL) {
2238 HeapFree(GetProcessHeap(), 0, object);
2239 ERR("Error in context creation !\n");
2241 return DDERR_INVALIDPARAMS;
2243 TRACE(" context created (%p)\n", gl_object->gl_context);
2246 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2247 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2248 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2249 surf->aux_ctx = (LPVOID) gl_object->display;
2250 surf->aux_data = (LPVOID) gl_object->drawable;
2251 surf->aux_flip = opengl_flip;
2256 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2258 TRACE(" no double buffering : drawing on the front buffer\n");
2262 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2263 for (; surf != NULL; surf = surf->next_attached) {
2264 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2265 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2266 /* Override the Lock / Unlock function for all these surfaces */
2267 surf->lock_update = d3ddevice_lock_update;
2268 surf->unlock_update = d3ddevice_unlock_update;
2269 /* And install also the blt / bltfast overrides */
2270 surf->aux_blt = d3ddevice_blt;
2271 surf->aux_bltfast = d3ddevice_bltfast;
2273 surf->d3ddevice = object;
2276 /* Set the various light parameters */
2277 for (light = 0; light < MAX_LIGHTS; light++) {
2278 /* Only set the fields that are not zero-created */
2279 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2280 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2281 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2282 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2283 object->light_parameters[light].dvDirection.u3.z = 1.0;
2286 /* Allocate memory for the matrices */
2287 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2288 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2289 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2290 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2291 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2292 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2294 /* allocate the clipping planes */
2295 glGetIntegerv(GL_MAX_CLIP_PLANES,&max_clipping_planes);
2296 if (max_clipping_planes>32) {
2297 object->max_clipping_planes=32;
2299 object->max_clipping_planes = max_clipping_planes;
2301 TRACE(" capable of %d clipping planes\n", (int)object->max_clipping_planes );
2302 object->clipping_planes = (d3d7clippingplane*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane));
2304 /* Initialisation */
2305 TRACE(" setting current context\n");
2307 object->set_context(object);
2309 TRACE(" current context set\n");
2311 glHint(GL_FOG_HINT,GL_NICEST);
2312 glClearColor(0.0, 0.0, 0.0, 0.0);
2313 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2314 glDrawBuffer(buffer);
2315 glReadBuffer(buffer);
2316 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2319 /* fill_device_capabilities(d3d->ddraw); */
2321 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2322 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2323 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2324 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2328 TRACE(" creating implementation at %p.\n", *obj);
2330 /* And finally warn D3D that this device is now present */
2331 object->d3d->added_device(object->d3d, object);
2333 /* FIXME: Should handle other versions than just 7 */
2334 InitDefaultStateBlock(&object->state_block, 7);
2335 /* Apply default render state values */
2336 apply_render_state(object, &object->state_block);
2337 /* FIXME: do something similar for ligh_state and texture_stage_state */
2339 /* And fill the fog table with the default fog value */
2340 build_fog_table(gl_object->fog_table, object->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1]);