- Clean up all the D3D COM handling (but the underlaying code is still
[wine/testsucceed.git] / dlls / ddraw / d3ddevice / mesa.c
blob0395cd35f3d0f4a5ebf2f1ff8cc3b1e354b82e23
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 "wine/obj_base.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 const GUID IID_D3DDEVICE2_OpenGL = {
49 0x31416d44,
50 0x86ae,
51 0x11d2,
52 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfb }
55 const GUID IID_D3DDEVICE3_OpenGL = {
56 0x31416d44,
57 0x86ae,
58 0x11d2,
59 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfc }
62 const GUID IID_D3DDEVICE7_OpenGL = {
63 0x31416d44,
64 0x86ae,
65 0x11d2,
66 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfd }
69 const GUID IID_D3DDEVICE_Default = {
70 0x00000000,
71 0x0000,
72 0x0000,
73 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
76 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
77 on Mesa's home page) or version 3.1b.
79 Version 3.1b2 should correct this bug */
80 #undef HAVE_BUGGY_MESAGL
82 #ifndef HAVE_GLEXT_PROTOTYPES
83 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
84 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
85 GLsizei width, GLenum format, GLenum type,
86 const GLvoid *table);
87 #endif
89 static const float id_mat[16] = {
90 1.0, 0.0, 0.0, 0.0,
91 0.0, 1.0, 0.0, 0.0,
92 0.0, 0.0, 1.0, 0.0,
93 0.0, 0.0, 0.0, 1.0
96 /* retrieve the X display to use on a given DC */
97 inline static Display *get_display( HDC hdc )
99 Display *display;
100 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
102 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
103 sizeof(display), (LPSTR)&display )) display = NULL;
105 return display;
109 /* retrieve the X drawable to use on a given DC */
110 inline static Drawable get_drawable( HDC hdc )
112 Drawable drawable;
113 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
115 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
116 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
118 return drawable;
122 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
124 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
125 ENTER_GL();
126 glXSwapBuffers((Display*)display,(Drawable)drawable);
127 LEAVE_GL();
128 return TRUE;
132 /*******************************************************************************
133 * OpenGL static functions
135 static void set_context(IDirect3DDeviceImpl* This) {
136 #if 0
137 D3DDPRIVATE(This);
139 ENTER_GL();
140 TRACE("glxMakeCurrent %p, %ld, %p\n",odev->gdi_display,odev->drawable, odev->ctx);
141 if (glXMakeCurrent(odev->gdi_display,odev->drawable, odev->ctx) == False) {
142 ERR("Error in setting current context (context %p drawable %ld)!\n",
143 odev->ctx, odev->drawable);
145 LEAVE_GL();
146 #else
147 ERR("This function should not be called in the current state of the code...\n");
148 #endif
151 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
153 pc->dwSize = sizeof(*pc);
154 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
155 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
156 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
157 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
158 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
159 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
160 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
161 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
162 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
163 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
164 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
165 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
166 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
167 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
168 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
169 pc->dwStippleWidth = 32;
170 pc->dwStippleHeight = 32;
173 static void fill_opengl_caps(D3DDEVICEDESC *d1)
175 /* GLint maxlight; */
177 d1->dwSize = sizeof(*d1);
178 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
179 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
180 d1->dcmColorModel = D3DCOLOR_RGB;
181 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
182 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
183 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
184 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
185 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
186 d1->bClipping = TRUE;
187 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
188 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
189 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
190 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
191 fill_opengl_primcaps(&(d1->dpcLineCaps));
192 fill_opengl_primcaps(&(d1->dpcTriCaps));
193 d1->dwDeviceRenderBitDepth = DDBD_16;
194 d1->dwDeviceZBufferBitDepth = DDBD_16;
195 d1->dwMaxBufferSize = 0;
196 d1->dwMaxVertexCount = 65536;
197 d1->dwMinTextureWidth = 1;
198 d1->dwMinTextureHeight = 1;
199 d1->dwMaxTextureWidth = 1024;
200 d1->dwMaxTextureHeight = 1024;
201 d1->dwMinStippleWidth = 1;
202 d1->dwMinStippleHeight = 1;
203 d1->dwMaxStippleWidth = 32;
204 d1->dwMaxStippleHeight = 32;
207 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
209 #if 0 /* TODO : fix this... */
210 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
211 const char *ext_string;
212 Mesa_DeviceCapabilities *devcap;
214 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
215 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
217 ENTER_GL();
218 ext_string = glGetString(GL_EXTENSIONS);
219 /* Query for the ColorTable Extension */
220 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
221 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
222 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
223 } else {
224 TRACE("Color table extension not found.\n");
226 LEAVE_GL();
227 #endif
232 HRESULT d3device_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD interface_version)
234 D3DDEVICEDESC d1, d2;
235 char buf[256];
236 const void *iid = NULL;
238 switch (interface_version) {
239 case 1: iid = &IID_D3DDEVICE_OpenGL; break;
240 case 2: iid = &IID_D3DDEVICE2_OpenGL; break;
241 case 3: iid = &IID_D3DDEVICE3_OpenGL; break;
242 case 7: iid = &IID_D3DDEVICE7_OpenGL; break;
244 strcpy(buf, "WINE Direct3DX using OpenGL");
245 buf[13] = '0' + interface_version;
247 fill_opengl_caps(&d1);
248 d2 = d1;
250 TRACE(" enumerating OpenGL D3DDevice%ld interface (IID %s).\n", interface_version, debugstr_guid(iid));
251 return cb((LPGUID) iid, buf, "direct3d", &d1, &d2, context);
254 ULONG WINAPI
255 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
257 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
258 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
260 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
261 if (!--(This->ref)) {
262 /* Release texture associated with the device */
263 if (This->current_texture != NULL)
264 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture, IDirect3DTexture2));
266 ENTER_GL();
267 glXDestroyContext(glThis->display, glThis->gl_context);
268 LEAVE_GL();
270 HeapFree(GetProcessHeap(), 0, This);
271 return 0;
273 return This->ref;
276 HRESULT WINAPI
277 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
278 LPD3DDEVICEDESC lpD3DHWDevDesc,
279 LPD3DDEVICEDESC lpD3DHELDevDesc)
281 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
282 D3DDEVICEDESC desc;
283 DWORD dwSize;
285 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
287 fill_opengl_caps(&desc);
288 dwSize = lpD3DHWDevDesc->dwSize;
289 memset(lpD3DHWDevDesc, 0, dwSize);
290 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
292 dwSize = lpD3DHELDevDesc->dwSize;
293 memset(lpD3DHELDevDesc, 0, dwSize);
294 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
296 TRACE(" returning caps : TODO\n");
298 return DD_OK;
301 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
302 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
303 LPVOID context)
305 DDSURFACEDESC sdesc;
306 LPDDPIXELFORMAT pformat;
308 /* Do the texture enumeration */
309 sdesc.dwSize = sizeof(DDSURFACEDESC);
310 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
311 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
312 pformat = &(sdesc.ddpfPixelFormat);
313 pformat->dwSize = sizeof(DDPIXELFORMAT);
314 pformat->dwFourCC = 0;
316 TRACE("Enumerating GL_RGBA unpacked (32)\n");
317 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
318 pformat->u1.dwRGBBitCount = 32;
319 pformat->u2.dwRBitMask = 0xFF000000;
320 pformat->u3.dwGBitMask = 0x00FF0000;
321 pformat->u4.dwBBitMask = 0x0000FF00;
322 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
323 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
324 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
326 TRACE("Enumerating GL_RGB unpacked (24)\n");
327 pformat->dwFlags = DDPF_RGB;
328 pformat->u1.dwRGBBitCount = 24;
329 pformat->u2.dwRBitMask = 0x00FF0000;
330 pformat->u3.dwGBitMask = 0x0000FF00;
331 pformat->u4.dwBBitMask = 0x000000FF;
332 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
333 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
334 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
336 #ifndef HAVE_BUGGY_MESAGL
337 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
338 so that future version will work great. */
339 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
340 pformat->dwFlags = DDPF_RGB;
341 pformat->u1.dwRGBBitCount = 16;
342 pformat->u2.dwRBitMask = 0x0000F800;
343 pformat->u3.dwGBitMask = 0x000007E0;
344 pformat->u4.dwBBitMask = 0x0000001F;
345 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
346 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
347 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
349 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
350 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
351 pformat->u1.dwRGBBitCount = 16;
352 pformat->u2.dwRBitMask = 0x0000F800;
353 pformat->u3.dwGBitMask = 0x000007C0;
354 pformat->u4.dwBBitMask = 0x0000003E;
355 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
356 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
357 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
359 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
360 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
361 pformat->u1.dwRGBBitCount = 16;
362 pformat->u2.dwRBitMask = 0x0000F000;
363 pformat->u3.dwGBitMask = 0x00000F00;
364 pformat->u4.dwBBitMask = 0x000000F0;
365 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
366 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
367 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
369 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
370 pformat->dwFlags = DDPF_RGB;
371 pformat->u1.dwRGBBitCount = 8;
372 pformat->u2.dwRBitMask = 0x000000E0;
373 pformat->u3.dwGBitMask = 0x0000001C;
374 pformat->u4.dwBBitMask = 0x00000003;
375 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
376 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
377 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
378 #endif
380 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
381 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
382 pformat->u1.dwRGBBitCount = 16;
383 pformat->u2.dwRBitMask = 0x00007C00;
384 pformat->u3.dwGBitMask = 0x000003E0;
385 pformat->u4.dwBBitMask = 0x0000001F;
386 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
387 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
388 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
390 TRACE("Enumerating Paletted (8)\n");
391 pformat->dwFlags = DDPF_PALETTEINDEXED8;
392 pformat->u1.dwRGBBitCount = 8;
393 pformat->u2.dwRBitMask = 0x00000000;
394 pformat->u3.dwGBitMask = 0x00000000;
395 pformat->u4.dwBBitMask = 0x00000000;
396 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
397 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
398 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
400 TRACE("End of enumeration\n");
401 return DD_OK;
404 HRESULT WINAPI
405 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
406 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
407 LPVOID lpArg)
409 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
410 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
411 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
414 HRESULT WINAPI
415 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
416 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
417 LPVOID lpArg)
419 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
420 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
421 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
424 HRESULT WINAPI
425 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
426 D3DRENDERSTATETYPE dwRenderStateType,
427 DWORD dwRenderState)
429 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
430 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
431 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
433 /* Call the render state functions */
434 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
436 return DD_OK;
439 HRESULT WINAPI
440 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
441 D3DLIGHTSTATETYPE dwLightStateType,
442 DWORD dwLightState)
444 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
445 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
447 switch (dwLightStateType) {
448 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
449 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
451 if (mat != NULL) {
452 ENTER_GL();
453 mat->activate(mat);
454 LEAVE_GL();
455 } else {
456 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
458 } break;
460 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
461 float light[4];
463 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
464 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
465 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
466 light[3] = 1.0;
467 ENTER_GL();
468 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
469 LEAVE_GL();
470 } break;
472 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
473 UNSUP(COLORMODEL);
474 UNSUP(FOGMODE);
475 UNSUP(FOGSTART);
476 UNSUP(FOGEND);
477 UNSUP(FOGDENSITY);
478 #undef UNSUP
480 default:
481 TRACE("Unexpected Light State Type\n");
482 return DDERR_INVALIDPARAMS;
485 return DD_OK;
488 HRESULT WINAPI
489 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
490 D3DTRANSFORMSTATETYPE dtstTransformStateType,
491 LPD3DMATRIX lpD3DMatrix)
493 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
494 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
496 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
498 ENTER_GL();
500 /* Using a trial and failure approach, I found that the order of
501 Direct3D transformations that works best is :
503 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
505 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
506 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
508 If anyone has a good explanation of the three different matrices in
509 the SDK online documentation, feel free to point it to me. For example,
510 which matrices transform lights ? In OpenGL only the PROJECTION matrix
511 transform the lights, not the MODELVIEW. Using the matrix names, I
512 supposed that PROJECTION and VIEW (all 'camera' related names) do
513 transform lights, but WORLD do not. It may be wrong though... */
515 /* After reading through both OpenGL and Direct3D documentations, I
516 thought that D3D matrices were written in 'line major mode' transposed
517 from OpenGL's 'column major mode'. But I found out that a simple memcpy
518 works fine to transfer one matrix format to the other (it did not work
519 when transposing)....
521 So :
522 1) are the documentations wrong
523 2) does the matrix work even if they are not read correctly
524 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
525 loading using glLoadMatrix ?
527 Anyway, I always use 'conv_mat' to transfer the matrices from one format
528 to the other so that if I ever find out that I need to transpose them, I
529 will able to do it quickly, only by changing the macro conv_mat. */
531 switch (dtstTransformStateType) {
532 case D3DTRANSFORMSTATE_WORLD: {
533 conv_mat(lpD3DMatrix, glThis->world_mat);
534 glMatrixMode(GL_MODELVIEW);
535 glLoadMatrixf((float *) glThis->world_mat);
536 } break;
538 case D3DTRANSFORMSTATE_VIEW: {
539 conv_mat(lpD3DMatrix, glThis->view_mat);
540 glMatrixMode(GL_PROJECTION);
541 glLoadMatrixf((float *) glThis->proj_mat);
542 glMultMatrixf((float *) glThis->view_mat);
543 } break;
545 case D3DTRANSFORMSTATE_PROJECTION: {
546 conv_mat(lpD3DMatrix, glThis->proj_mat);
547 glMatrixMode(GL_PROJECTION);
548 glLoadMatrixf((float *) glThis->proj_mat);
549 glMultMatrixf((float *) glThis->view_mat);
550 } break;
552 default:
553 ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType);
554 break;
556 LEAVE_GL();
558 return DD_OK;
561 inline static void draw_primitive(IDirect3DDeviceGLImpl *glThis, DWORD maxvert, WORD *index,
562 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
564 DWORD vx_index;
566 /* Puts GL in the correct lighting mode */
567 if (glThis->vertex_type != d3dvt) {
568 if (glThis->vertex_type == D3DVT_TLVERTEX) {
569 /* Need to put the correct transformation again */
570 glMatrixMode(GL_MODELVIEW);
571 glLoadMatrixf((float *) glThis->world_mat);
572 glMatrixMode(GL_PROJECTION);
573 glLoadMatrixf((float *) glThis->proj_mat);
574 glMultMatrixf((float *) glThis->view_mat);
577 switch (d3dvt) {
578 case D3DVT_VERTEX:
579 TRACE("Standard Vertex\n");
580 glEnable(GL_LIGHTING);
581 break;
583 case D3DVT_LVERTEX:
584 TRACE("Lighted Vertex\n");
585 glDisable(GL_LIGHTING);
586 break;
588 case D3DVT_TLVERTEX: {
589 GLdouble height, width, minZ, maxZ;
591 TRACE("Transformed - Lighted Vertex\n");
592 /* First, disable lighting */
593 glDisable(GL_LIGHTING);
595 /* Then do not put any transformation matrixes */
596 glMatrixMode(GL_MODELVIEW);
597 glLoadIdentity();
598 glMatrixMode(GL_PROJECTION);
599 glLoadIdentity();
601 if (glThis->parent.current_viewport == NULL) {
602 ERR("No current viewport !\n");
603 /* Using standard values */
604 height = 640.0;
605 width = 480.0;
606 minZ = -10.0;
607 maxZ = 10.0;
608 } else {
609 if (glThis->parent.current_viewport->use_vp2 == 1) {
610 height = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwHeight;
611 width = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwWidth;
612 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMinZ;
613 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMaxZ;
614 } else {
615 height = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwHeight;
616 width = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwWidth;
617 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMinZ;
618 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMaxZ;
622 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
623 } break;
625 default:
626 ERR("Unhandled vertex type\n");
627 break;
630 glThis->vertex_type = d3dvt;
633 switch (d3dpt) {
634 case D3DPT_POINTLIST:
635 TRACE("Start POINTS\n");
636 glBegin(GL_POINTS);
637 break;
639 case D3DPT_LINELIST:
640 TRACE("Start LINES\n");
641 glBegin(GL_LINES);
642 break;
644 case D3DPT_LINESTRIP:
645 TRACE("Start LINE_STRIP\n");
646 glBegin(GL_LINE_STRIP);
647 break;
649 case D3DPT_TRIANGLELIST:
650 TRACE("Start TRIANGLES\n");
651 glBegin(GL_TRIANGLES);
652 break;
654 case D3DPT_TRIANGLESTRIP:
655 TRACE("Start TRIANGLE_STRIP\n");
656 glBegin(GL_TRIANGLE_STRIP);
657 break;
659 case D3DPT_TRIANGLEFAN:
660 TRACE("Start TRIANGLE_FAN\n");
661 glBegin(GL_TRIANGLE_FAN);
662 break;
664 default:
665 TRACE("Unhandled primitive\n");
666 break;
669 /* Draw the primitives */
670 for (vx_index = 0; vx_index < maxvert; vx_index++) {
671 switch (d3dvt) {
672 case D3DVT_VERTEX: {
673 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
675 glNormal3f(vx->u4.nx, vx->u5.ny, vx->u6.nz);
676 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
677 TRACE(" V: %f %f %f\n", vx->u1.x, vx->u2.y, vx->u3.z);
678 } break;
680 case D3DVT_LVERTEX: {
681 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
682 DWORD col = vx->u4.color;
684 glColor3f(((col >> 16) & 0xFF) / 255.0,
685 ((col >> 8) & 0xFF) / 255.0,
686 ((col >> 0) & 0xFF) / 255.0);
687 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
688 TRACE(" LV: %f %f %f (%02lx %02lx %02lx)\n",
689 vx->u1.x, vx->u2.y, vx->u3.z,
690 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF));
691 } break;
693 case D3DVT_TLVERTEX: {
694 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
695 DWORD col = vx->u5.color;
697 glColor3f(((col >> 16) & 0xFF) / 255.0,
698 ((col >> 8) & 0xFF) / 255.0,
699 ((col >> 0) & 0xFF) / 255.0);
700 glTexCoord2f(vx->u7.tu, vx->u8.tv);
701 if (vx->u4.rhw < 0.01)
702 glVertex3f(vx->u1.sx,
703 vx->u2.sy,
704 vx->u3.sz);
705 else
706 glVertex4f(vx->u1.sx / vx->u4.rhw,
707 vx->u2.sy / vx->u4.rhw,
708 vx->u3.sz / vx->u4.rhw,
709 1.0 / vx->u4.rhw);
710 TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",
711 vx->u1.sx, vx->u2.sy, vx->u3.sz,
712 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF),
713 vx->u7.tu, vx->u8.tv, vx->u4.rhw);
714 } break;
716 default:
717 FIXME("Unhandled vertex type\n");
718 break;
722 glEnd();
723 TRACE("End\n");
726 HRESULT WINAPI
727 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
728 D3DPRIMITIVETYPE d3dptPrimitiveType,
729 D3DVERTEXTYPE d3dvtVertexType,
730 LPVOID lpvVertices,
731 DWORD dwVertexCount,
732 DWORD dwFlags)
734 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
735 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
737 ENTER_GL();
738 draw_primitive((IDirect3DDeviceGLImpl *) This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
739 LEAVE_GL();
741 return DD_OK;
744 HRESULT WINAPI
745 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
746 D3DPRIMITIVETYPE d3dptPrimitiveType,
747 D3DVERTEXTYPE d3dvtVertexType,
748 LPVOID lpvVertices,
749 DWORD dwVertexCount,
750 LPWORD dwIndices,
751 DWORD dwIndexCount,
752 DWORD dwFlags)
754 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
755 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
757 ENTER_GL();
758 draw_primitive((IDirect3DDeviceGLImpl *) This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
759 LEAVE_GL();
761 return DD_OK;
764 HRESULT WINAPI
765 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
766 LPD3DEXECUTEBUFFERDESC lpDesc,
767 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
768 IUnknown* pUnkOuter)
770 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
771 IDirect3DExecuteBufferImpl *ret;
772 HRESULT ret_value;
774 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
776 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
777 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
779 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
781 return ret_value;
784 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
785 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
786 #else
787 # define XCAST(fun) (void*)
788 #endif
790 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
792 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
793 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
794 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
795 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
796 XCAST(GetCaps) Main_IDirect3DDeviceImpl_7_GetCaps,
797 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
798 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
799 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
800 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
801 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
802 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
803 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
804 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
805 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
806 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
807 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
808 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
809 XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
810 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
811 XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
812 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
813 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
814 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
815 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
816 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
817 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
818 XCAST(DrawPrimitive) Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
819 XCAST(DrawIndexedPrimitive) Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
820 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
821 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
822 XCAST(DrawPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
823 XCAST(DrawIndexedPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
824 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB,
825 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
826 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
827 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
828 XCAST(SetTexture) Main_IDirect3DDeviceImpl_7_SetTexture,
829 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
830 XCAST(SetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
831 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
832 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
833 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
834 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
835 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
836 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
837 XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
838 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
839 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
840 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
841 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
844 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
845 #undef XCAST
846 #endif
849 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
850 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
851 #else
852 # define XCAST(fun) (void*)
853 #endif
855 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
857 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
858 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
859 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
860 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
861 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
862 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
863 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
864 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
865 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
866 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
867 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
868 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
869 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
870 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
871 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
872 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
873 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
874 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
875 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
876 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
877 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
878 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
879 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
880 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
881 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
882 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
883 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
884 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
885 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
886 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
887 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
888 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
889 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
890 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
891 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
892 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
893 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
894 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
895 XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
896 XCAST(SetTexture) Main_IDirect3DDeviceImpl_3_SetTexture,
897 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
898 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
899 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
902 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
903 #undef XCAST
904 #endif
907 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
908 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
909 #else
910 # define XCAST(fun) (void*)
911 #endif
913 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
915 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
916 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
917 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
918 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
919 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
920 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
921 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
922 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
923 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
924 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
925 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
926 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
927 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
928 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
929 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
930 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
931 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
932 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
933 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
934 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
935 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
936 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
937 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
938 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
939 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
940 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
941 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
942 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
943 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
944 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
945 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
946 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
947 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
948 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
951 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
952 #undef XCAST
953 #endif
956 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
957 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
958 #else
959 # define XCAST(fun) (void*)
960 #endif
962 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
964 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
965 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
966 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
967 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
968 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
969 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
970 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
971 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
972 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
973 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
974 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
975 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
976 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
977 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
978 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
979 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
980 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
981 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
982 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
983 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
984 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
985 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
986 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
989 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
990 #undef XCAST
991 #endif
996 HRESULT
997 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
999 IDirect3DDeviceImpl *object;
1000 IDirect3DDeviceGLImpl *gl_object;
1001 IDirectDrawSurfaceImpl *surf;
1002 HDC device_context;
1003 XVisualInfo *vis;
1004 int num;
1005 XVisualInfo template;
1007 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1008 if (object == NULL) return DDERR_OUTOFMEMORY;
1010 gl_object = (IDirect3DDeviceGLImpl *) object;
1012 object->ref = 1;
1013 object->d3d = d3d;
1014 object->surface = surface;
1015 object->viewport_list = NULL;
1016 object->current_viewport = NULL;
1017 object->current_texture = NULL;
1018 object->set_context = set_context;
1020 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1022 device_context = GetDC(surface->ddraw_owner->window);
1023 gl_object->display = get_display(device_context);
1024 gl_object->drawable = get_drawable(device_context);
1025 ReleaseDC(surface->ddraw_owner->window,device_context);
1027 ENTER_GL();
1028 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1029 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
1030 if (vis == NULL) {
1031 HeapFree(GetProcessHeap(), 0, object);
1032 ERR("No visual found !\n");
1033 LEAVE_GL();
1034 return DDERR_INVALIDPARAMS;
1035 } else {
1036 TRACE(" visual found\n");
1039 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
1040 NULL, GL_TRUE);
1042 if (gl_object->gl_context == NULL) {
1043 HeapFree(GetProcessHeap(), 0, object);
1044 ERR("Error in context creation !\n");
1045 LEAVE_GL();
1046 return DDERR_INVALIDPARAMS;
1047 } else {
1048 TRACE(" context created (%p)\n", gl_object->gl_context);
1051 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
1052 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
1053 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
1054 surface->surface_owner->aux_ctx = (LPVOID) gl_object->display;
1055 surface->surface_owner->aux_data = (LPVOID) gl_object->drawable;
1056 surface->surface_owner->aux_flip = opengl_flip;
1057 break;
1061 gl_object->render_state.src = GL_ONE;
1062 gl_object->render_state.dst = GL_ZERO;
1063 gl_object->render_state.mag = GL_NEAREST;
1064 gl_object->render_state.min = GL_NEAREST;
1065 gl_object->vertex_type = 0;
1067 /* Allocate memory for the matrices */
1068 gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1069 gl_object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1070 gl_object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1072 memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float));
1073 memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float));
1074 memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float));
1076 /* Initialisation */
1077 TRACE(" setting current context\n");
1078 LEAVE_GL();
1079 object->set_context(object);
1080 ENTER_GL();
1081 TRACE(" current context set\n");
1082 glClearColor(0.0, 0.0, 0.0, 0.0);
1083 glColor3f(1.0, 1.0, 1.0);
1084 LEAVE_GL();
1086 fill_device_capabilities(d3d->ddraw);
1088 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
1089 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
1090 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
1091 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
1093 *obj = object;
1095 TRACE(" creating implementation at %p.\n", *obj);
1097 return DD_OK;