Reenable device's default render states initialization.
[wine/multimedia.git] / dlls / ddraw / d3ddevice / mesa.c
blob3c78ffeacaa34c458c1b70c1b8359547234096e1
1 /* Direct3D Device
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the MESA implementation of all the D3D devices that
5 * Wine supports.
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
22 #include "config.h"
24 #include <string.h>
26 #include "windef.h"
27 #include "winerror.h"
28 #include "objbase.h"
29 #include "ddraw.h"
30 #include "d3d.h"
31 #include "wine/debug.h"
33 #include "mesa_private.h"
34 #include "main.h"
36 #include "x11drv.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
40 /* They are non-static as they are used by Direct3D in the creation function */
41 const GUID IID_D3DDEVICE_OpenGL = {
42 0x31416d44,
43 0x86ae,
44 0x11d2,
45 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
48 #ifndef HAVE_GLEXT_PROTOTYPES
49 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
50 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
51 GLsizei width, GLenum format, GLenum type,
52 const GLvoid *table);
53 #endif
55 const float id_mat[16] = {
56 1.0, 0.0, 0.0, 0.0,
57 0.0, 1.0, 0.0, 0.0,
58 0.0, 0.0, 1.0, 0.0,
59 0.0, 0.0, 0.0, 1.0
62 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
63 D3DPRIMITIVETYPE d3dptPrimitiveType,
64 DWORD d3dvtVertexType,
65 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
66 DWORD dwStartVertex,
67 DWORD dwVertexCount,
68 LPWORD dwIndices,
69 DWORD dwIndexCount,
70 DWORD dwFlags) ;
72 /* retrieve the X display to use on a given DC */
73 inline static Display *get_display( HDC hdc )
75 Display *display;
76 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
78 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
79 sizeof(display), (LPSTR)&display )) display = NULL;
81 return display;
85 /* retrieve the X drawable to use on a given DC */
86 inline static Drawable get_drawable( HDC hdc )
88 Drawable drawable;
89 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
91 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
92 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
94 return drawable;
98 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
100 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
101 ENTER_GL();
102 glXSwapBuffers((Display*)display,(Drawable)drawable);
103 LEAVE_GL();
104 return TRUE;
108 /*******************************************************************************
109 * OpenGL static functions
111 static void set_context(IDirect3DDeviceImpl* This)
113 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
115 ENTER_GL();
116 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
117 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
118 ERR("Error in setting current context (context %p drawable %ld)!\n",
119 glThis->gl_context, glThis->drawable);
121 LEAVE_GL();
124 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
126 pc->dwSize = sizeof(*pc);
127 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
128 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
129 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
130 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
131 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
132 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
133 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
134 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
135 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
136 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
137 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
138 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
139 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
140 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
141 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
142 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
143 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
144 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
145 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
146 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
147 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
148 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
149 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
150 pc->dwStippleWidth = 32;
151 pc->dwStippleHeight = 32;
154 static void fill_opengl_caps(D3DDEVICEDESC *d1)
156 /* GLint maxlight; */
158 d1->dwSize = sizeof(*d1);
159 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
160 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
161 d1->dcmColorModel = D3DCOLOR_RGB;
162 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
163 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
164 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
165 /* D3D 7 capabilities */
166 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
167 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
168 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
169 d1->bClipping = TRUE;
170 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
171 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
172 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
173 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
174 fill_opengl_primcaps(&(d1->dpcLineCaps));
175 fill_opengl_primcaps(&(d1->dpcTriCaps));
176 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
177 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
178 d1->dwMaxBufferSize = 0;
179 d1->dwMaxVertexCount = 65536;
180 d1->dwMinTextureWidth = 1;
181 d1->dwMinTextureHeight = 1;
182 d1->dwMaxTextureWidth = 1024;
183 d1->dwMaxTextureHeight = 1024;
184 d1->dwMinStippleWidth = 1;
185 d1->dwMinStippleHeight = 1;
186 d1->dwMaxStippleWidth = 32;
187 d1->dwMaxStippleHeight = 32;
188 d1->dwMaxTextureRepeat = 16;
189 d1->dwMaxTextureAspectRatio = 1024;
190 d1->dwMaxAnisotropy = 0;
191 d1->dvGuardBandLeft = 0.0;
192 d1->dvGuardBandRight = 0.0;
193 d1->dvGuardBandTop = 0.0;
194 d1->dvGuardBandBottom = 0.0;
195 d1->dvExtentsAdjust = 0.0;
196 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
197 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
198 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
199 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
200 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
201 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
204 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
206 D3DDEVICEDESC d1;
208 /* Copy first D3D1/2/3 capabilities */
209 fill_opengl_caps(&d1);
211 /* And fill the D3D7 one with it */
212 d->dwDevCaps = d1.dwDevCaps;
213 d->dpcLineCaps = d1.dpcLineCaps;
214 d->dpcTriCaps = d1.dpcTriCaps;
215 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
216 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
217 d->dwMinTextureWidth = d1.dwMinTextureWidth;
218 d->dwMinTextureHeight = d1.dwMinTextureHeight;
219 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
220 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
221 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
222 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
223 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
224 d->dvGuardBandLeft = d1.dvGuardBandLeft;
225 d->dvGuardBandTop = d1.dvGuardBandTop;
226 d->dvGuardBandRight = d1.dvGuardBandRight;
227 d->dvGuardBandBottom = d1.dvGuardBandBottom;
228 d->dvExtentsAdjust = d1.dvExtentsAdjust;
229 d->dwStencilCaps = d1.dwStencilCaps;
230 d->dwFVFCaps = d1.dwFVFCaps;
231 d->dwTextureOpCaps = d1.dwTextureOpCaps;
232 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
233 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
234 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
235 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
236 d->deviceGUID = IID_IDirect3DTnLHalDevice;
237 d->wMaxUserClipPlanes = 1;
238 d->wMaxVertexBlendMatrices = 0;
239 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
240 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
241 d->dwReserved1 = 0;
242 d->dwReserved2 = 0;
243 d->dwReserved3 = 0;
244 d->dwReserved4 = 0;
247 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
248 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
250 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
251 const char *ext_string;
252 Mesa_DeviceCapabilities *devcap;
254 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
255 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
257 ENTER_GL();
258 ext_string = glGetString(GL_EXTENSIONS);
259 /* Query for the ColorTable Extension */
260 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
261 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
262 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
263 } else {
264 TRACE("Color table extension not found.\n");
266 LEAVE_GL();
268 #endif
272 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
274 D3DDEVICEDESC dref, d1, d2;
275 HRESULT ret_value;
277 fill_opengl_caps(&dref);
279 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
280 d1 = dref;
281 d2 = dref;
282 ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
283 if (ret_value != D3DENUMRET_OK)
284 return ret_value;
286 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
287 d1 = dref;
288 d2 = dref;
289 ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
290 if (ret_value != D3DENUMRET_OK)
291 return ret_value;
293 return D3DENUMRET_OK;
296 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
298 D3DDEVICEDESC7 ddesc;
300 fill_opengl_caps_7(&ddesc);
302 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
304 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
307 ULONG WINAPI
308 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
310 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
311 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
313 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
314 if (!--(This->ref)) {
315 /* Release texture associated with the device */
316 if (This->current_texture[0] != NULL)
317 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
319 /* And warn the D3D object that this device is no longer active... */
320 This->d3d->removed_device(This->d3d, This);
322 HeapFree(GetProcessHeap(), 0, This->world_mat);
323 HeapFree(GetProcessHeap(), 0, This->view_mat);
324 HeapFree(GetProcessHeap(), 0, This->proj_mat);
326 ENTER_GL();
327 glXDestroyContext(glThis->display, glThis->gl_context);
328 LEAVE_GL();
330 HeapFree(GetProcessHeap(), 0, This);
331 return 0;
333 return This->ref;
336 HRESULT WINAPI
337 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
338 LPD3DDEVICEDESC lpD3DHWDevDesc,
339 LPD3DDEVICEDESC lpD3DHELDevDesc)
341 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
342 D3DDEVICEDESC desc;
343 DWORD dwSize;
345 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
347 fill_opengl_caps(&desc);
348 dwSize = lpD3DHWDevDesc->dwSize;
349 memset(lpD3DHWDevDesc, 0, dwSize);
350 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
352 dwSize = lpD3DHELDevDesc->dwSize;
353 memset(lpD3DHELDevDesc, 0, dwSize);
354 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
356 TRACE(" returning caps : (no dump function yet)\n");
358 return DD_OK;
361 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
362 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
363 LPVOID context)
365 DDSURFACEDESC sdesc;
366 LPDDPIXELFORMAT pformat;
368 /* Do the texture enumeration */
369 sdesc.dwSize = sizeof(DDSURFACEDESC);
370 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
371 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
372 pformat = &(sdesc.ddpfPixelFormat);
373 pformat->dwSize = sizeof(DDPIXELFORMAT);
374 pformat->dwFourCC = 0;
376 TRACE("Enumerating GL_RGBA unpacked (32)\n");
377 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
378 pformat->u1.dwRGBBitCount = 32;
379 pformat->u2.dwRBitMask = 0xFF000000;
380 pformat->u3.dwGBitMask = 0x00FF0000;
381 pformat->u4.dwBBitMask = 0x0000FF00;
382 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
383 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
384 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
386 TRACE("Enumerating GL_RGB unpacked (24)\n");
387 pformat->dwFlags = DDPF_RGB;
388 pformat->u1.dwRGBBitCount = 24;
389 pformat->u2.dwRBitMask = 0x00FF0000;
390 pformat->u3.dwGBitMask = 0x0000FF00;
391 pformat->u4.dwBBitMask = 0x000000FF;
392 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
393 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
394 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
396 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
397 pformat->dwFlags = DDPF_RGB;
398 pformat->u1.dwRGBBitCount = 16;
399 pformat->u2.dwRBitMask = 0x0000F800;
400 pformat->u3.dwGBitMask = 0x000007E0;
401 pformat->u4.dwBBitMask = 0x0000001F;
402 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
403 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
404 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
406 /* Note : even if this is an 'emulated' texture format, it needs to be first
407 as some dumb applications seem to rely on that. */
408 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n");
409 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
410 pformat->u1.dwRGBBitCount = 16;
411 pformat->u2.dwRBitMask = 0x00007C00;
412 pformat->u3.dwGBitMask = 0x000003E0;
413 pformat->u4.dwBBitMask = 0x0000001F;
414 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
415 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
416 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
418 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
419 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
420 pformat->u1.dwRGBBitCount = 16;
421 pformat->u2.dwRBitMask = 0x0000F800;
422 pformat->u3.dwGBitMask = 0x000007C0;
423 pformat->u4.dwBBitMask = 0x0000003E;
424 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
425 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
426 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
428 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
429 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
430 pformat->u1.dwRGBBitCount = 16;
431 pformat->u2.dwRBitMask = 0x00000F00;
432 pformat->u3.dwGBitMask = 0x000000F0;
433 pformat->u4.dwBBitMask = 0x0000000F;
434 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
435 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
436 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
438 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
439 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
440 pformat->u1.dwRGBBitCount = 16;
441 pformat->u2.dwRBitMask = 0x0000F000;
442 pformat->u3.dwGBitMask = 0x00000F00;
443 pformat->u4.dwBBitMask = 0x000000F0;
444 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
445 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
446 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
448 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
449 pformat->dwFlags = DDPF_RGB;
450 pformat->u1.dwRGBBitCount = 8;
451 pformat->u2.dwRBitMask = 0x000000E0;
452 pformat->u3.dwGBitMask = 0x0000001C;
453 pformat->u4.dwBBitMask = 0x00000003;
454 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
455 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
456 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
458 TRACE("Enumerating Paletted (8)\n");
459 pformat->dwFlags = DDPF_PALETTEINDEXED8;
460 pformat->u1.dwRGBBitCount = 8;
461 pformat->u2.dwRBitMask = 0x00000000;
462 pformat->u3.dwGBitMask = 0x00000000;
463 pformat->u4.dwBBitMask = 0x00000000;
464 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
465 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
466 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
468 TRACE("End of enumeration\n");
469 return DD_OK;
473 HRESULT
474 d3ddevice_find(IDirect3DImpl *d3d,
475 LPD3DFINDDEVICESEARCH lpD3DDFS,
476 LPD3DFINDDEVICERESULT lplpD3DDevice)
478 D3DDEVICEDESC desc;
480 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
481 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
482 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
483 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
485 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
486 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
487 if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
488 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0) &&
489 (IsEqualGUID(&IID_IDirect3DRefDevice, &(lpD3DDFS->guid)) == 0)) {
490 TRACE(" no match for this GUID.\n");
491 return DDERR_INVALIDPARAMS;
495 /* Now return our own GUID */
496 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
497 fill_opengl_caps(&desc);
498 lplpD3DDevice->ddHwDesc = desc;
499 lplpD3DDevice->ddSwDesc = desc;
501 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
503 return D3D_OK;
506 HRESULT WINAPI
507 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
508 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
509 LPVOID lpArg)
511 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
512 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
513 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
516 HRESULT WINAPI
517 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
518 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
519 LPVOID lpArg)
521 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
522 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
523 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
526 HRESULT WINAPI
527 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
528 D3DRENDERSTATETYPE dwRenderStateType,
529 DWORD dwRenderState)
531 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
532 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
533 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
535 /* Call the render state functions */
536 set_render_state(glThis, dwRenderStateType, dwRenderState);
537 store_render_state(dwRenderStateType, dwRenderState, &glThis->parent.state_block);
539 return DD_OK;
542 HRESULT WINAPI
543 GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
544 D3DRENDERSTATETYPE dwRenderStateType,
545 LPDWORD lpdwRenderState)
547 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
548 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
549 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState);
551 /* Call the render state functions */
552 get_render_state(dwRenderStateType, lpdwRenderState, &glThis->parent.state_block);
554 return DD_OK;
557 HRESULT WINAPI
558 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
559 D3DLIGHTSTATETYPE dwLightStateType,
560 DWORD dwLightState)
562 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
563 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
565 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
567 switch (dwLightStateType) {
568 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
569 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
571 if (mat != NULL) {
572 ENTER_GL();
573 mat->activate(mat);
574 LEAVE_GL();
575 } else {
576 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
578 } break;
580 case D3DLIGHTSTATE_AMBIENT: /* 2 */
581 /* Call the render_state function... */
582 set_render_state(glThis, D3DRENDERSTATE_AMBIENT, dwLightState);
583 break;
585 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
586 UNSUP(COLORMODEL);
587 UNSUP(FOGMODE);
588 UNSUP(FOGSTART);
589 UNSUP(FOGEND);
590 UNSUP(FOGDENSITY);
591 UNSUP(COLORVERTEX);
592 #undef UNSUP
594 default:
595 TRACE("Unexpected Light State Type\n");
596 return DDERR_INVALIDPARAMS;
599 This->state_block.light_state[dwLightStateType] = dwLightState;
601 return DD_OK;
604 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
606 switch (d3dpt) {
607 case D3DPT_POINTLIST:
608 TRACE("Start POINTS\n");
609 glBegin(GL_POINTS);
610 break;
612 case D3DPT_LINELIST:
613 TRACE("Start LINES\n");
614 glBegin(GL_LINES);
615 break;
617 case D3DPT_LINESTRIP:
618 TRACE("Start LINE_STRIP\n");
619 glBegin(GL_LINE_STRIP);
620 break;
622 case D3DPT_TRIANGLELIST:
623 TRACE("Start TRIANGLES\n");
624 glBegin(GL_TRIANGLES);
625 break;
627 case D3DPT_TRIANGLESTRIP:
628 TRACE("Start TRIANGLE_STRIP\n");
629 glBegin(GL_TRIANGLE_STRIP);
630 break;
632 case D3DPT_TRIANGLEFAN:
633 TRACE("Start TRIANGLE_FAN\n");
634 glBegin(GL_TRIANGLE_FAN);
635 break;
637 default:
638 TRACE("Unhandled primitive\n");
639 break;
643 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
644 BOOLEAN vertex_transformed,
645 BOOLEAN vertex_lit) {
646 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
648 /* Puts GL in the correct lighting / transformation mode */
649 if ((vertex_transformed == FALSE) &&
650 (glThis->transform_state != GL_TRANSFORM_NORMAL)) {
651 /* Need to put the correct transformation again if we go from Transformed
652 vertices to non-transformed ones.
654 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
655 This->world_mat, This->view_mat, This->proj_mat);
656 glThis->transform_state = GL_TRANSFORM_NORMAL;
658 if (glThis->render_state.fog_on == TRUE)
659 glEnable(GL_FOG);
660 } else if ((vertex_transformed == TRUE) &&
661 (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
662 GLfloat height, width;
663 GLfloat trans_mat[16];
665 glThis->transform_state = GL_TRANSFORM_ORTHO;
667 width = glThis->parent.surface->surface_desc.dwWidth;
668 height = glThis->parent.surface->surface_desc.dwHeight;
670 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
671 to OpenGL screen coordinates (ie the upper left corner is not the same).
672 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
673 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
674 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
675 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
676 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
677 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
679 glMatrixMode(GL_MODELVIEW);
680 glLoadIdentity();
681 glMatrixMode(GL_PROJECTION);
682 glLoadMatrixf(trans_mat);
684 /* Remove also fogging... */
685 glDisable(GL_FOG);
688 /* Handle the 'no-normal' case */
689 if (vertex_lit == FALSE)
690 glDisable(GL_LIGHTING);
691 else if (glThis->render_state.lighting_enable == TRUE)
692 glEnable(GL_LIGHTING);
694 /* Handle the code for pre-vertex material properties */
695 if (vertex_transformed == FALSE) {
696 if (glThis->render_state.lighting_enable == TRUE) {
697 if ((glThis->render_state.color_diffuse != D3DMCS_MATERIAL) ||
698 (glThis->render_state.color_specular != D3DMCS_MATERIAL) ||
699 (glThis->render_state.color_ambient != D3DMCS_MATERIAL) ||
700 (glThis->render_state.color_emissive != D3DMCS_MATERIAL)) {
701 glEnable(GL_COLOR_MATERIAL);
708 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
709 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
711 D3DDRAWPRIMITIVESTRIDEDDATA strided;
713 switch (d3dvt) {
714 case D3DVT_VERTEX: {
715 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
716 strided.position.dwStride = sizeof(D3DVERTEX);
717 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
718 strided.normal.dwStride = sizeof(D3DVERTEX);
719 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
720 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
721 draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
722 } break;
724 case D3DVT_LVERTEX: {
725 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
726 strided.position.dwStride = sizeof(D3DLVERTEX);
727 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
728 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
729 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
730 strided.specular.dwStride = sizeof(D3DLVERTEX);
731 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
732 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
733 draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
734 } break;
736 case D3DVT_TLVERTEX: {
737 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
738 strided.position.dwStride = sizeof(D3DTLVERTEX);
739 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
740 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
741 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
742 strided.specular.dwStride = sizeof(D3DTLVERTEX);
743 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
744 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
745 draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
746 } break;
748 default:
749 FIXME("Unhandled vertex type\n");
750 break;
754 HRESULT WINAPI
755 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
756 D3DPRIMITIVETYPE d3dptPrimitiveType,
757 D3DVERTEXTYPE d3dvtVertexType,
758 LPVOID lpvVertices,
759 DWORD dwVertexCount,
760 DWORD dwFlags)
762 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
764 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
765 if (TRACE_ON(ddraw)) {
766 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
769 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
771 return DD_OK;
774 HRESULT WINAPI
775 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
776 D3DPRIMITIVETYPE d3dptPrimitiveType,
777 D3DVERTEXTYPE d3dvtVertexType,
778 LPVOID lpvVertices,
779 DWORD dwVertexCount,
780 LPWORD dwIndices,
781 DWORD dwIndexCount,
782 DWORD dwFlags)
784 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
785 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
786 if (TRACE_ON(ddraw)) {
787 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
790 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
792 return DD_OK;
795 HRESULT WINAPI
796 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
797 LPD3DEXECUTEBUFFERDESC lpDesc,
798 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
799 IUnknown* pUnkOuter)
801 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
802 IDirect3DExecuteBufferImpl *ret;
803 HRESULT ret_value;
805 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
807 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
808 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
810 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
812 return ret_value;
815 /* These are the various handler used in the generic path */
816 inline static void handle_xyz(D3DVALUE *coords) {
817 glVertex3fv(coords);
819 inline static void handle_xyzrhw(D3DVALUE *coords) {
820 if (coords[3] < 1e-8)
821 glVertex3fv(coords);
822 else {
823 GLfloat w = 1.0 / coords[3];
825 glVertex4f(coords[0] * w,
826 coords[1] * w,
827 coords[2] * w,
831 inline static void handle_normal(D3DVALUE *coords) {
832 glNormal3fv(coords);
835 inline static void handle_diffuse_base(RenderState *rs, DWORD *color) {
836 if (rs->alpha_blend_enable == TRUE) {
837 glColor4ub((*color >> 16) & 0xFF,
838 (*color >> 8) & 0xFF,
839 (*color >> 0) & 0xFF,
840 (*color >> 24) & 0xFF);
841 } else {
842 glColor3ub((*color >> 16) & 0xFF,
843 (*color >> 8) & 0xFF,
844 (*color >> 0) & 0xFF);
848 inline static void handle_specular_base(RenderState *rs, DWORD *color) {
849 glColor4ub((*color >> 16) & 0xFF,
850 (*color >> 8) & 0xFF,
851 (*color >> 0) & 0xFF,
852 (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
855 inline static void handle_diffuse(RenderState *rs, DWORD *color) {
856 if (rs->lighting_enable == TRUE) {
857 if (rs->color_diffuse == D3DMCS_COLOR1) {
858 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
859 handle_diffuse_base(rs, color);
861 if (rs->color_ambient == D3DMCS_COLOR1) {
862 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
863 handle_diffuse_base(rs, color);
865 if ((rs->color_specular == D3DMCS_COLOR1) && (rs->specular_enable == TRUE)) {
866 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
867 handle_diffuse_base(rs, color);
869 if (rs->color_emissive == D3DMCS_COLOR1) {
870 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
871 handle_diffuse_base(rs, color);
873 } else {
874 handle_diffuse_base(rs, color);
878 inline static void handle_specular(RenderState *rs, DWORD *color) {
879 if (rs->lighting_enable == TRUE) {
880 if (rs->color_diffuse == D3DMCS_COLOR2) {
881 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
882 handle_specular(rs, color);
884 if (rs->color_ambient == D3DMCS_COLOR2) {
885 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
886 handle_specular(rs, color);
888 if ((rs->color_specular == D3DMCS_COLOR2) && (rs->specular_enable == TRUE)) {
889 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
890 handle_specular(rs, color);
892 if (rs->color_emissive == D3DMCS_COLOR2) {
893 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
894 handle_specular(rs, color);
897 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
900 inline static void handle_diffuse_and_specular(RenderState *rs, DWORD *color_d, DWORD *color_s, BOOLEAN transformed) {
901 if (transformed == TRUE) {
902 if (rs->fog_on == TRUE) {
903 /* Special case where the specular value is used to do fogging. TODO */
905 if (rs->specular_enable == TRUE) {
906 /* Standard specular value in transformed mode. TODO */
908 handle_diffuse_base(rs, color_d);
909 } else {
910 if (rs->lighting_enable == TRUE) {
911 handle_diffuse(rs, color_d);
912 handle_specular(rs, color_s);
913 } else {
914 /* In that case, only put the diffuse color... */
915 handle_diffuse_base(rs, color_d);
920 inline static void handle_texture(D3DVALUE *coords) {
921 glTexCoord2fv(coords);
923 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
924 /* For the moment, draw only the first texture.. */
925 if (tex_index == 0) glTexCoord2fv(coords);
928 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
929 D3DPRIMITIVETYPE d3dptPrimitiveType,
930 DWORD d3dvtVertexType,
931 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
932 DWORD dwStartVertex,
933 DWORD dwVertexCount,
934 LPWORD dwIndices,
935 DWORD dwIndexCount,
936 DWORD dwFlags)
938 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
939 if (TRACE_ON(ddraw)) {
940 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
943 ENTER_GL();
944 draw_primitive_handle_GL_state(This,
945 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
946 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
947 draw_primitive_start_GL(d3dptPrimitiveType);
949 /* Some fast paths first before the generic case.... */
950 if (d3dvtVertexType == D3DFVF_VERTEX) {
951 int index;
953 for (index = 0; index < dwIndexCount; index++) {
954 int i = (dwIndices == NULL) ? index : dwIndices[index];
955 D3DVALUE *normal =
956 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
957 D3DVALUE *tex_coord =
958 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
959 D3DVALUE *position =
960 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
962 handle_normal(normal);
963 handle_texture(tex_coord);
964 handle_xyz(position);
966 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
967 position[0], position[1], position[2],
968 normal[0], normal[1], normal[2],
969 tex_coord[0], tex_coord[1]);
971 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
972 int index;
974 for (index = 0; index < dwIndexCount; index++) {
975 int i = (dwIndices == NULL) ? index : dwIndices[index];
976 DWORD *color_d =
977 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
978 DWORD *color_s =
979 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
980 D3DVALUE *tex_coord =
981 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
982 D3DVALUE *position =
983 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
985 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, TRUE);
986 handle_texture(tex_coord);
987 handle_xyzrhw(position);
989 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
990 position[0], position[1], position[2], position[3],
991 (*color_d >> 16) & 0xFF,
992 (*color_d >> 8) & 0xFF,
993 (*color_d >> 0) & 0xFF,
994 (*color_d >> 24) & 0xFF,
995 (*color_s >> 16) & 0xFF,
996 (*color_s >> 8) & 0xFF,
997 (*color_s >> 0) & 0xFF,
998 (*color_s >> 24) & 0xFF,
999 tex_coord[0], tex_coord[1]);
1001 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1002 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1003 /* This is the 'slow path' but that should support all possible vertex formats out there...
1004 Note that people should write a fast path for all vertex formats out there...
1006 int index;
1007 for (index = 0; index < dwIndexCount; index++) {
1008 int i = (dwIndices == NULL) ? index : dwIndices[index];
1010 if (d3dvtVertexType & D3DFVF_NORMAL) {
1011 D3DVALUE *normal =
1012 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1013 handle_normal(normal);
1015 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1016 DWORD *color_d =
1017 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1018 DWORD *color_s =
1019 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1020 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, (d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW);
1021 } else {
1022 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1023 DWORD *color_s =
1024 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1025 handle_specular(&(glThis->render_state), color_s);
1026 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1027 DWORD *color_d =
1028 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1029 handle_diffuse(&(glThis->render_state), color_d);
1033 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1034 /* Special case for single texture... */
1035 D3DVALUE *tex_coord =
1036 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1037 handle_texture(tex_coord);
1038 } else {
1039 int tex_index;
1040 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1041 D3DVALUE *tex_coord =
1042 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1043 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1044 handle_textures(tex_coord, tex_index);
1047 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1048 D3DVALUE *position =
1049 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1050 handle_xyz(position);
1051 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1052 D3DVALUE *position =
1053 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1054 handle_xyzrhw(position);
1057 if (TRACE_ON(ddraw)) {
1058 int tex_index;
1060 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1061 D3DVALUE *position =
1062 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1063 TRACE(" %f %f %f", position[0], position[1], position[2]);
1064 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1065 D3DVALUE *position =
1066 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1067 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1069 if (d3dvtVertexType & D3DFVF_NORMAL) {
1070 D3DVALUE *normal =
1071 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1072 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1074 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1075 DWORD *color_d =
1076 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1077 DPRINTF(" / %02lx %02lx %02lx %02lx",
1078 (*color_d >> 16) & 0xFF,
1079 (*color_d >> 8) & 0xFF,
1080 (*color_d >> 0) & 0xFF,
1081 (*color_d >> 24) & 0xFF);
1083 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1084 DWORD *color_s =
1085 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1086 DPRINTF(" / %02lx %02lx %02lx %02lx",
1087 (*color_s >> 16) & 0xFF,
1088 (*color_s >> 8) & 0xFF,
1089 (*color_s >> 0) & 0xFF,
1090 (*color_s >> 24) & 0xFF);
1092 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1093 D3DVALUE *tex_coord =
1094 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1095 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1096 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1098 DPRINTF("\n");
1101 } else {
1102 ERR(" matrix weighting not handled yet....\n");
1105 glEnd();
1107 /* Whatever the case, disable the color material stuff */
1108 glDisable(GL_COLOR_MATERIAL);
1110 LEAVE_GL();
1111 TRACE("End\n");
1114 HRESULT WINAPI
1115 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1116 D3DPRIMITIVETYPE d3dptPrimitiveType,
1117 DWORD d3dvtVertexType,
1118 LPVOID lpvVertices,
1119 DWORD dwVertexCount,
1120 DWORD dwFlags)
1122 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1123 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1125 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1126 if (TRACE_ON(ddraw)) {
1127 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1130 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1131 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1133 return DD_OK;
1136 HRESULT WINAPI
1137 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1138 D3DPRIMITIVETYPE d3dptPrimitiveType,
1139 DWORD d3dvtVertexType,
1140 LPVOID lpvVertices,
1141 DWORD dwVertexCount,
1142 LPWORD dwIndices,
1143 DWORD dwIndexCount,
1144 DWORD dwFlags)
1146 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1147 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1149 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1150 if (TRACE_ON(ddraw)) {
1151 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1154 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1155 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1157 return DD_OK;
1160 HRESULT WINAPI
1161 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1162 D3DPRIMITIVETYPE d3dptPrimitiveType,
1163 DWORD dwVertexType,
1164 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1165 DWORD dwVertexCount,
1166 DWORD dwFlags)
1168 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1170 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1171 if (TRACE_ON(ddraw)) {
1172 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1174 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1176 return DD_OK;
1179 HRESULT WINAPI
1180 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1181 D3DPRIMITIVETYPE d3dptPrimitiveType,
1182 DWORD dwVertexType,
1183 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1184 DWORD dwVertexCount,
1185 LPWORD lpIndex,
1186 DWORD dwIndexCount,
1187 DWORD dwFlags)
1189 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1191 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1192 if (TRACE_ON(ddraw)) {
1193 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1196 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1198 return DD_OK;
1201 HRESULT WINAPI
1202 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1203 D3DPRIMITIVETYPE d3dptPrimitiveType,
1204 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1205 DWORD dwStartVertex,
1206 DWORD dwNumVertices,
1207 DWORD dwFlags)
1209 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1210 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1211 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1213 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1214 if (TRACE_ON(ddraw)) {
1215 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1218 if (vb_impl->processed == TRUE) {
1219 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1220 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1222 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1223 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1224 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1226 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1227 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1229 } else {
1230 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1231 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1234 return DD_OK;
1237 HRESULT WINAPI
1238 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1239 D3DPRIMITIVETYPE d3dptPrimitiveType,
1240 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1241 DWORD dwStartVertex,
1242 DWORD dwNumVertices,
1243 LPWORD lpwIndices,
1244 DWORD dwIndexCount,
1245 DWORD dwFlags)
1247 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1248 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1249 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1251 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1252 if (TRACE_ON(ddraw)) {
1253 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1256 if (vb_impl->processed == TRUE) {
1257 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1258 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1260 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1261 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1262 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1264 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1265 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1267 } else {
1268 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1269 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1272 return DD_OK;
1275 HRESULT WINAPI
1276 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1277 DWORD dwStage,
1278 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1279 DWORD dwState)
1281 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1282 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1283 GLenum gl_state;
1285 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1287 if (TRACE_ON(ddraw)) {
1288 TRACE(" Stage type is : ");
1289 switch (d3dTexStageStateType) {
1290 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1291 GEN_CASE(D3DTSS_COLOROP);
1292 GEN_CASE(D3DTSS_COLORARG1);
1293 GEN_CASE(D3DTSS_COLORARG2);
1294 GEN_CASE(D3DTSS_ALPHAOP);
1295 GEN_CASE(D3DTSS_ALPHAARG1);
1296 GEN_CASE(D3DTSS_ALPHAARG2);
1297 GEN_CASE(D3DTSS_BUMPENVMAT00);
1298 GEN_CASE(D3DTSS_BUMPENVMAT01);
1299 GEN_CASE(D3DTSS_BUMPENVMAT10);
1300 GEN_CASE(D3DTSS_BUMPENVMAT11);
1301 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1302 GEN_CASE(D3DTSS_ADDRESS);
1303 GEN_CASE(D3DTSS_ADDRESSU);
1304 GEN_CASE(D3DTSS_ADDRESSV);
1305 GEN_CASE(D3DTSS_BORDERCOLOR);
1306 GEN_CASE(D3DTSS_MAGFILTER);
1307 GEN_CASE(D3DTSS_MINFILTER);
1308 GEN_CASE(D3DTSS_MIPFILTER);
1309 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1310 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1311 GEN_CASE(D3DTSS_MAXANISOTROPY);
1312 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1313 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1314 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1315 #undef GEN_CASE
1316 default: DPRINTF("UNKNOWN !!!");
1318 DPRINTF(" => ");
1321 switch (d3dTexStageStateType) {
1322 case D3DTSS_MINFILTER:
1323 switch ((D3DTEXTUREMINFILTER) dwState) {
1324 case D3DTFN_POINT:
1325 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1326 gl_state = GL_NEAREST;
1327 break;
1328 case D3DTFN_LINEAR:
1329 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1330 gl_state = GL_LINEAR;
1331 break;
1332 default:
1333 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1334 gl_state = GL_LINEAR;
1335 break;
1337 glThis->render_state.min = gl_state;
1338 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1339 break;
1341 case D3DTSS_MAGFILTER:
1342 switch ((D3DTEXTUREMAGFILTER) dwState) {
1343 case D3DTFG_POINT:
1344 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1345 gl_state = GL_NEAREST;
1346 break;
1347 case D3DTFG_LINEAR:
1348 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1349 gl_state = GL_LINEAR;
1350 break;
1351 default:
1352 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1353 gl_state = GL_LINEAR;
1354 break;
1356 glThis->render_state.mag = gl_state;
1357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1358 break;
1360 case D3DTSS_ADDRESS:
1361 case D3DTSS_ADDRESSU:
1362 case D3DTSS_ADDRESSV: {
1363 GLenum arg = GL_REPEAT; /* Default value */
1364 switch ((D3DTEXTUREADDRESS) dwState) {
1365 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1366 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1367 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1368 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1370 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1371 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1373 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1374 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1376 } break;
1378 default:
1379 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1382 This->state_block.texture_stage_state[dwStage][d3dTexStageStateType-1] = dwState;
1384 return DD_OK;
1387 HRESULT WINAPI
1388 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1389 DWORD dwStage,
1390 LPDIRECTDRAWSURFACE7 lpTexture2)
1392 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1393 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1395 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1397 if (This->current_texture[dwStage] != NULL) {
1398 /* Seems that this is not right... Need to test in real Windows
1399 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1402 ENTER_GL();
1403 if (lpTexture2 == NULL) {
1404 TRACE(" disabling 2D texturing.\n");
1405 glBindTexture(GL_TEXTURE_2D, 0);
1406 glDisable(GL_TEXTURE_2D);
1407 } else {
1408 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1409 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
1411 This->current_texture[dwStage] = tex_impl;
1412 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1414 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1416 glEnable(GL_TEXTURE_2D);
1417 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1418 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glThis->render_state.mag);
1419 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glThis->render_state.min);
1421 LEAVE_GL();
1423 return DD_OK;
1426 HRESULT WINAPI
1427 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1428 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1430 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1431 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1433 fill_opengl_caps_7(lpD3DHELDevDesc);
1435 TRACE(" returning caps : no dump function yet.\n");
1437 return DD_OK;
1440 HRESULT WINAPI
1441 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1442 LPD3DMATERIAL7 lpMat)
1444 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1445 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1447 if (TRACE_ON(ddraw)) {
1448 TRACE(" material is : \n");
1449 dump_D3DMATERIAL7(lpMat);
1452 This->current_material = *lpMat;
1454 glMaterialfv(GL_FRONT_AND_BACK,
1455 GL_DIFFUSE,
1456 (float *) &(This->current_material.u.diffuse));
1457 glMaterialfv(GL_FRONT_AND_BACK,
1458 GL_AMBIENT,
1459 (float *) &(This->current_material.u1.ambient));
1460 glMaterialfv(GL_FRONT_AND_BACK,
1461 GL_SPECULAR,
1462 (float *) &(This->current_material.u2.specular));
1463 glMaterialfv(GL_FRONT_AND_BACK,
1464 GL_EMISSION,
1465 (float *) &(This->current_material.u3.emissive));
1466 glMaterialf(GL_FRONT_AND_BACK,
1467 GL_SHININESS,
1468 This->current_material.u4.power); /* Not sure about this... */
1470 return DD_OK;
1474 HRESULT WINAPI
1475 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1476 DWORD dwLightIndex,
1477 LPD3DLIGHT7 lpLight)
1479 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1480 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1482 if (TRACE_ON(ddraw)) {
1483 TRACE(" setting light : \n");
1484 dump_D3DLIGHT7(lpLight);
1487 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1488 This->set_lights |= 0x00000001 << dwLightIndex;
1489 This->light_parameters[dwLightIndex] = *lpLight;
1491 switch (lpLight->dltType) {
1492 case D3DLIGHT_DIRECTIONAL: {
1493 float direction[4];
1494 float cut_off = 180.0;
1496 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1497 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1498 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1499 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1501 direction[0] = lpLight->dvDirection.u1.x;
1502 direction[1] = lpLight->dvDirection.u2.y;
1503 direction[2] = lpLight->dvDirection.u3.z;
1504 direction[3] = 0.0;
1505 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1506 } break;
1508 case D3DLIGHT_POINT: {
1509 float position[4];
1510 float cut_off = 180.0;
1512 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1513 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1514 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1515 position[0] = lpLight->dvPosition.u1.x;
1516 position[1] = lpLight->dvPosition.u2.y;
1517 position[2] = lpLight->dvPosition.u3.z;
1518 position[3] = 1.0;
1519 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1520 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1521 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1522 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1523 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1524 } break;
1526 case D3DLIGHT_SPOT: {
1527 float direction[4];
1528 float position[4];
1529 float cut_off = 90.0 * (lpLight->dvPhi / M_PI);
1531 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1532 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1533 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1535 direction[0] = lpLight->dvDirection.u1.x;
1536 direction[1] = lpLight->dvDirection.u2.y;
1537 direction[2] = lpLight->dvDirection.u3.z;
1538 direction[3] = 0.0;
1539 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_DIRECTION, (float *) direction);
1540 position[0] = lpLight->dvPosition.u1.x;
1541 position[1] = lpLight->dvPosition.u2.y;
1542 position[2] = lpLight->dvPosition.u3.z;
1543 position[3] = 1.0;
1544 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1545 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1546 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1547 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1548 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1549 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_EXPONENT, &(lpLight->dvFalloff));
1550 if ((lpLight->dvTheta != 0.0) || (lpLight->dvTheta != lpLight->dvPhi)) {
1551 WARN("dvTheta not fully supported yet !\n");
1553 } break;
1555 default: WARN(" light type not handled yet...\n");
1558 return DD_OK;
1561 HRESULT WINAPI
1562 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1563 DWORD dwLightIndex,
1564 BOOL bEnable)
1566 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1567 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1569 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1571 if (bEnable) {
1572 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1573 /* Set the default parameters.. */
1574 TRACE(" setting default light parameters...\n");
1575 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1577 glEnable(GL_LIGHT0 + dwLightIndex);
1578 } else {
1579 glDisable(GL_LIGHT0 + dwLightIndex);
1582 return DD_OK;
1585 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1586 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1587 #else
1588 # define XCAST(fun) (void*)
1589 #endif
1591 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1593 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1594 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1595 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1596 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1597 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1598 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1599 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1600 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1601 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1602 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1603 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1604 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1605 XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1606 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1607 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1608 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1609 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1610 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1611 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1612 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1613 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1614 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1615 XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1616 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1617 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1618 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1619 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1620 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1621 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1622 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1623 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1624 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1625 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1626 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1627 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1628 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1629 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1630 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1631 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1632 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1633 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1634 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1635 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1636 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1637 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1638 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1639 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1640 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1641 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1642 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1645 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1646 #undef XCAST
1647 #endif
1650 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1651 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1652 #else
1653 # define XCAST(fun) (void*)
1654 #endif
1656 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1658 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1659 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1660 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1661 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1662 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1663 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1664 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1665 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1666 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1667 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1668 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1669 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1670 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1671 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1672 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1673 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1674 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1675 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1676 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1677 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1678 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1679 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1680 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1681 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1682 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1683 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1684 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1685 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1686 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1687 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1688 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1689 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1690 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1691 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1692 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1693 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1694 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1695 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1696 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1697 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1698 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1699 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1700 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1703 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1704 #undef XCAST
1705 #endif
1708 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1709 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1710 #else
1711 # define XCAST(fun) (void*)
1712 #endif
1714 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1716 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1717 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1718 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1719 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1720 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1721 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
1722 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1723 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1724 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1725 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1726 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1727 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1728 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1729 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1730 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1731 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1732 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1733 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1734 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1735 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1736 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1737 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1738 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1739 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1740 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1741 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1742 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1743 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1744 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1745 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1746 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1747 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1748 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1749 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1752 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1753 #undef XCAST
1754 #endif
1757 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1758 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1759 #else
1760 # define XCAST(fun) (void*)
1761 #endif
1763 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1765 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1766 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1767 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1768 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1769 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1770 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1771 XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
1772 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1773 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1774 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1775 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1776 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1777 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1778 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1779 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1780 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1781 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1782 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1783 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1784 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1785 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1786 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1787 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1790 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1791 #undef XCAST
1792 #endif
1794 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1795 DWORD dwCount,
1796 LPD3DRECT lpRects,
1797 DWORD dwFlags,
1798 DWORD dwColor,
1799 D3DVALUE dvZ,
1800 DWORD dwStencil)
1802 GLboolean ztest;
1803 GLfloat old_z_clear_value;
1804 GLbitfield bitfield = 0;
1805 GLint old_stencil_clear_value;
1806 GLfloat old_color_clear_value[4];
1808 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1809 if (TRACE_ON(ddraw)) {
1810 if (dwCount > 0) {
1811 int i;
1812 TRACE(" rectangles : \n");
1813 for (i = 0; i < dwCount; i++) {
1814 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1819 if (dwCount > 1) {
1820 WARN(" Warning, this function only for now clears the whole screen...\n");
1823 /* Clears the screen */
1824 ENTER_GL();
1825 if (dwFlags & D3DCLEAR_ZBUFFER) {
1826 bitfield |= GL_DEPTH_BUFFER_BIT;
1827 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1828 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1829 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1830 glClearDepth(dvZ);
1831 TRACE(" depth value : %f\n", dvZ);
1833 if (dwFlags & D3DCLEAR_STENCIL) {
1834 bitfield |= GL_STENCIL_BUFFER_BIT;
1835 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1836 glClearStencil(dwStencil);
1837 TRACE(" stencil value : %ld\n", dwStencil);
1839 if (dwFlags & D3DCLEAR_TARGET) {
1840 bitfield |= GL_COLOR_BUFFER_BIT;
1841 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1842 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1843 ((dwColor >> 8) & 0xFF) / 255.0,
1844 ((dwColor >> 0) & 0xFF) / 255.0,
1845 ((dwColor >> 24) & 0xFF) / 255.0);
1846 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1849 glClear(bitfield);
1851 if (dwFlags & D3DCLEAR_ZBUFFER) {
1852 glDepthMask(ztest);
1853 glClearDepth(old_z_clear_value);
1855 if (dwFlags & D3DCLEAR_STENCIL) {
1856 bitfield |= GL_STENCIL_BUFFER_BIT;
1857 glClearStencil(old_stencil_clear_value);
1859 if (dwFlags & D3DCLEAR_TARGET) {
1860 bitfield |= GL_COLOR_BUFFER_BIT;
1861 glClearColor(old_color_clear_value[0],
1862 old_color_clear_value[1],
1863 old_color_clear_value[2],
1864 old_color_clear_value[3]);
1867 LEAVE_GL();
1869 return DD_OK;
1872 HRESULT
1873 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1874 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1875 DWORD dwFlags, LPDDBLTFX lpbltfx)
1877 if (dwFlags & DDBLT_COLORFILL) {
1878 /* This is easy to handle for the D3D Device... */
1879 DWORD color = lpbltfx->u5.dwFillColor;
1880 TRACE(" executing D3D Device override.\n");
1881 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1882 return DD_OK;
1884 return DDERR_INVALIDPARAMS;
1887 HRESULT
1888 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1889 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1890 LPRECT rsrc, DWORD trans)
1892 return DDERR_INVALIDPARAMS;
1895 void
1896 d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
1897 D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
1899 if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
1900 glMatrixMode(GL_MODELVIEW);
1901 glLoadMatrixf((float *) view_mat);
1902 glMultMatrixf((float *) world_mat);
1904 if ((matrices & PROJMAT_CHANGED) != 0) {
1905 glMatrixMode(GL_PROJECTION);
1906 glLoadMatrixf((float *) proj_mat);
1910 void
1911 d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
1913 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1914 if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
1915 /* This will force an update of the transform state at the next drawing. */
1916 glThis->transform_state = GL_TRANSFORM_NONE;
1920 /* TODO for both these functions :
1921 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1922 by other OpenGL code in D3D
1923 - handle the case where no 'Begin / EndScene' was done between two locks
1924 - handle the rectangles in the unlock too
1925 - handle pitch correctly...
1927 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1929 /* First, check if we need to do anything */
1930 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1931 GLenum buffer_type;
1932 GLenum prev_read;
1933 RECT loc_rect;
1935 ENTER_GL();
1937 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1938 glFlush();
1940 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1941 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1942 /* Application wants to lock the front buffer */
1943 glReadBuffer(GL_FRONT);
1944 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1945 /* Application wants to lock the back buffer */
1946 glReadBuffer(GL_BACK);
1947 } else {
1948 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1951 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1952 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1953 } else {
1954 WARN(" unsupported pixel format.\n");
1955 LEAVE_GL();
1956 return;
1958 if (pRect == NULL) {
1959 loc_rect.top = 0;
1960 loc_rect.left = 0;
1961 loc_rect.bottom = This->surface_desc.dwHeight;
1962 loc_rect.right = This->surface_desc.dwWidth;
1963 } else {
1964 loc_rect = *pRect;
1966 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1967 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1968 + loc_rect.top * This->surface_desc.u1.lPitch
1969 + loc_rect.left * GET_BPP(This->surface_desc)));
1970 glReadBuffer(prev_read);
1971 LEAVE_GL();
1975 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1977 /* First, check if we need to do anything */
1978 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1979 GLenum buffer_type;
1980 GLenum prev_draw;
1982 ENTER_GL();
1984 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1986 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1987 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1988 /* Application wants to lock the front buffer */
1989 glDrawBuffer(GL_FRONT);
1990 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1991 /* Application wants to lock the back buffer */
1992 glDrawBuffer(GL_BACK);
1993 } else {
1994 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
1997 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1998 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1999 } else {
2000 WARN(" unsupported pixel format.\n");
2001 LEAVE_GL();
2002 return;
2004 glRasterPos2f(0.0, 0.0);
2005 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
2006 GL_RGB, buffer_type, This->surface_desc.lpSurface);
2007 glDrawBuffer(prev_draw);
2009 LEAVE_GL();
2013 HRESULT
2014 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
2016 IDirect3DDeviceImpl *object;
2017 IDirect3DDeviceGLImpl *gl_object;
2018 IDirectDrawSurfaceImpl *surf;
2019 HDC device_context;
2020 XVisualInfo *vis;
2021 int num;
2022 XVisualInfo template;
2023 GLenum buffer = GL_FRONT;
2024 int light;
2026 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
2027 if (object == NULL) return DDERR_OUTOFMEMORY;
2029 gl_object = (IDirect3DDeviceGLImpl *) object;
2031 object->ref = 1;
2032 object->d3d = d3d;
2033 object->surface = surface;
2034 object->set_context = set_context;
2035 object->clear = d3ddevice_clear;
2036 object->set_matrices = d3ddevice_set_matrices;
2037 object->matrices_updated = d3ddevice_matrices_updated;
2039 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
2041 device_context = GetDC(surface->ddraw_owner->window);
2042 gl_object->display = get_display(device_context);
2043 gl_object->drawable = get_drawable(device_context);
2044 ReleaseDC(surface->ddraw_owner->window,device_context);
2046 ENTER_GL();
2047 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2048 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2049 if (vis == NULL) {
2050 HeapFree(GetProcessHeap(), 0, object);
2051 ERR("No visual found !\n");
2052 LEAVE_GL();
2053 return DDERR_INVALIDPARAMS;
2054 } else {
2055 TRACE(" visual found\n");
2058 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2059 NULL, GL_TRUE);
2061 if (gl_object->gl_context == NULL) {
2062 HeapFree(GetProcessHeap(), 0, object);
2063 ERR("Error in context creation !\n");
2064 LEAVE_GL();
2065 return DDERR_INVALIDPARAMS;
2066 } else {
2067 TRACE(" context created (%p)\n", gl_object->gl_context);
2070 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2071 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2072 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2073 surf->aux_ctx = (LPVOID) gl_object->display;
2074 surf->aux_data = (LPVOID) gl_object->drawable;
2075 surf->aux_flip = opengl_flip;
2076 buffer = GL_BACK;
2077 break;
2080 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2081 if (surf == NULL) {
2082 TRACE(" no double buffering : drawing on the front buffer\n");
2083 buffer = GL_FRONT;
2086 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2087 for (; surf != NULL; surf = surf->next_attached) {
2088 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2089 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2090 /* Override the Lock / Unlock function for all these surfaces */
2091 surf->lock_update = d3ddevice_lock_update;
2092 surf->unlock_update = d3ddevice_unlock_update;
2093 /* And install also the blt / bltfast overrides */
2094 surf->aux_blt = d3ddevice_blt;
2095 surf->aux_bltfast = d3ddevice_bltfast;
2097 surf->d3ddevice = object;
2100 /* FIXME: Should handle other versions than just 7 */
2101 InitDefaultStateBlock(&object->state_block,7);
2103 /* FIXME: These 4 statements are kept for compatibility but should be removed as soon
2104 as they are correctly handled */
2105 gl_object->render_state.fog_on = FALSE;
2106 gl_object->render_state.stencil_enable = FALSE;
2107 gl_object->render_state.lighting_enable = FALSE;
2108 gl_object->render_state.specular_enable = FALSE;
2110 /* Set the various light parameters */
2111 for (light = 0; light < MAX_LIGHTS; light++) {
2112 /* Only set the fields that are not zero-created */
2113 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2114 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2115 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2116 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2117 object->light_parameters[light].dvDirection.u3.z = 1.0;
2120 /* Allocate memory for the matrices */
2121 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2122 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2123 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2124 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2125 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2126 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2128 /* Initialisation */
2129 TRACE(" setting current context\n");
2130 LEAVE_GL();
2131 object->set_context(object);
2132 ENTER_GL();
2133 TRACE(" current context set\n");
2135 /* Apply default render state values */
2136 apply_render_state(gl_object, &object->state_block);
2137 /* FIXME: do something similar for ligh_state and texture_stage_state */
2139 glClearColor(0.0, 0.0, 0.0, 0.0);
2140 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2141 glDrawBuffer(buffer);
2142 glReadBuffer(buffer);
2143 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2144 LEAVE_GL();
2146 /* fill_device_capabilities(d3d->ddraw); */
2148 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2149 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2150 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2151 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2153 *obj = object;
2155 TRACE(" creating implementation at %p.\n", *obj);
2157 /* And finally warn D3D that this device is now present */
2158 object->d3d->added_device(object->d3d, object);
2160 return DD_OK;