- start of support for device locking / unlocking via glReadPixels /
[wine/wine-kai.git] / dlls / ddraw / d3ddevice / mesa.c
blob2b5abedd3f1a81880f1230b3cee8c47e7bea093e
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 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
70 on Mesa's home page) or version 3.1b.
72 Version 3.1b2 should correct this bug */
73 #undef HAVE_BUGGY_MESAGL
75 #ifndef HAVE_GLEXT_PROTOTYPES
76 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
77 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
78 GLsizei width, GLenum format, GLenum type,
79 const GLvoid *table);
80 #endif
82 static const float id_mat[16] = {
83 1.0, 0.0, 0.0, 0.0,
84 0.0, 1.0, 0.0, 0.0,
85 0.0, 0.0, 1.0, 0.0,
86 0.0, 0.0, 0.0, 1.0
89 /* retrieve the X display to use on a given DC */
90 inline static Display *get_display( HDC hdc )
92 Display *display;
93 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
95 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
96 sizeof(display), (LPSTR)&display )) display = NULL;
98 return display;
102 /* retrieve the X drawable to use on a given DC */
103 inline static Drawable get_drawable( HDC hdc )
105 Drawable drawable;
106 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
108 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
109 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
111 return drawable;
115 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
117 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
118 ENTER_GL();
119 glXSwapBuffers((Display*)display,(Drawable)drawable);
120 LEAVE_GL();
121 return TRUE;
125 /*******************************************************************************
126 * OpenGL static functions
128 static void set_context(IDirect3DDeviceImpl* This)
130 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
132 ENTER_GL();
133 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
134 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
135 ERR("Error in setting current context (context %p drawable %ld)!\n",
136 glThis->gl_context, glThis->drawable);
138 LEAVE_GL();
141 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
143 pc->dwSize = sizeof(*pc);
144 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
145 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
146 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
147 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
148 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
149 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
150 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
151 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
152 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
153 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
154 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
155 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
156 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
157 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
158 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
159 pc->dwStippleWidth = 32;
160 pc->dwStippleHeight = 32;
163 static void fill_opengl_caps(D3DDEVICEDESC *d1)
165 /* GLint maxlight; */
167 d1->dwSize = sizeof(*d1);
168 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
169 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
170 d1->dcmColorModel = D3DCOLOR_RGB;
171 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
172 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
173 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
174 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
175 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
176 d1->bClipping = TRUE;
177 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
178 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
179 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
180 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
181 fill_opengl_primcaps(&(d1->dpcLineCaps));
182 fill_opengl_primcaps(&(d1->dpcTriCaps));
183 d1->dwDeviceRenderBitDepth = DDBD_16;
184 d1->dwDeviceZBufferBitDepth = DDBD_16;
185 d1->dwMaxBufferSize = 0;
186 d1->dwMaxVertexCount = 65536;
187 d1->dwMinTextureWidth = 1;
188 d1->dwMinTextureHeight = 1;
189 d1->dwMaxTextureWidth = 1024;
190 d1->dwMaxTextureHeight = 1024;
191 d1->dwMinStippleWidth = 1;
192 d1->dwMinStippleHeight = 1;
193 d1->dwMaxStippleWidth = 32;
194 d1->dwMaxStippleHeight = 32;
195 d1->dwMaxTextureRepeat = 16;
196 d1->dwMaxTextureAspectRatio = 1024;
197 d1->dwMaxAnisotropy = 0;
198 d1->dvGuardBandLeft = 0.0;
199 d1->dvGuardBandRight = 0.0;
200 d1->dvGuardBandTop = 0.0;
201 d1->dvGuardBandBottom = 0.0;
202 d1->dvExtentsAdjust = 0.0;
203 d1->dwStencilCaps = 0; /* TODO add proper caps according to what OpenGL can do */
204 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
205 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
206 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
207 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
210 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
211 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
213 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
214 const char *ext_string;
215 Mesa_DeviceCapabilities *devcap;
217 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
218 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
220 ENTER_GL();
221 ext_string = glGetString(GL_EXTENSIONS);
222 /* Query for the ColorTable Extension */
223 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
224 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
225 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
226 } else {
227 TRACE("Color table extension not found.\n");
229 LEAVE_GL();
231 #endif
235 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD interface_version)
237 D3DDEVICEDESC d1, d2;
238 char buf[256];
239 const void *iid = NULL;
241 switch (interface_version) {
242 case 1: iid = &IID_D3DDEVICE_OpenGL; break;
243 case 2: iid = &IID_D3DDEVICE2_OpenGL; break;
244 case 3: iid = &IID_D3DDEVICE3_OpenGL; break;
245 case 7: iid = &IID_D3DDEVICE7_OpenGL; break;
247 strcpy(buf, "WINE Direct3DX using OpenGL");
248 buf[13] = '0' + interface_version;
250 fill_opengl_caps(&d1);
251 d2 = d1;
253 TRACE(" enumerating OpenGL D3DDevice%ld interface (IID %s).\n", interface_version, debugstr_guid(iid));
254 return cb((LPGUID) iid, buf, "direct3d", &d1, &d2, context);
257 ULONG WINAPI
258 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
260 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
261 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
263 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
264 if (!--(This->ref)) {
265 /* Release texture associated with the device */
266 if (This->current_texture != NULL)
267 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture, IDirect3DTexture2));
269 ENTER_GL();
270 glXDestroyContext(glThis->display, glThis->gl_context);
271 LEAVE_GL();
273 HeapFree(GetProcessHeap(), 0, This);
274 return 0;
276 return This->ref;
279 HRESULT WINAPI
280 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
281 LPD3DDEVICEDESC lpD3DHWDevDesc,
282 LPD3DDEVICEDESC lpD3DHELDevDesc)
284 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
285 D3DDEVICEDESC desc;
286 DWORD dwSize;
288 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
290 fill_opengl_caps(&desc);
291 dwSize = lpD3DHWDevDesc->dwSize;
292 memset(lpD3DHWDevDesc, 0, dwSize);
293 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
295 dwSize = lpD3DHELDevDesc->dwSize;
296 memset(lpD3DHELDevDesc, 0, dwSize);
297 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
299 TRACE(" returning caps : (no dump function yet)\n");
301 return DD_OK;
304 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
305 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
306 LPVOID context)
308 DDSURFACEDESC sdesc;
309 LPDDPIXELFORMAT pformat;
311 /* Do the texture enumeration */
312 sdesc.dwSize = sizeof(DDSURFACEDESC);
313 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
314 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
315 pformat = &(sdesc.ddpfPixelFormat);
316 pformat->dwSize = sizeof(DDPIXELFORMAT);
317 pformat->dwFourCC = 0;
319 TRACE("Enumerating GL_RGBA unpacked (32)\n");
320 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
321 pformat->u1.dwRGBBitCount = 32;
322 pformat->u2.dwRBitMask = 0xFF000000;
323 pformat->u3.dwGBitMask = 0x00FF0000;
324 pformat->u4.dwBBitMask = 0x0000FF00;
325 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
326 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
327 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
329 TRACE("Enumerating GL_RGB unpacked (24)\n");
330 pformat->dwFlags = DDPF_RGB;
331 pformat->u1.dwRGBBitCount = 24;
332 pformat->u2.dwRBitMask = 0x00FF0000;
333 pformat->u3.dwGBitMask = 0x0000FF00;
334 pformat->u4.dwBBitMask = 0x000000FF;
335 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
336 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
337 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
339 #ifndef HAVE_BUGGY_MESAGL
340 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
341 so that future version will work great. */
342 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
343 pformat->dwFlags = DDPF_RGB;
344 pformat->u1.dwRGBBitCount = 16;
345 pformat->u2.dwRBitMask = 0x0000F800;
346 pformat->u3.dwGBitMask = 0x000007E0;
347 pformat->u4.dwBBitMask = 0x0000001F;
348 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
349 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
350 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
352 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
353 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
354 pformat->u1.dwRGBBitCount = 16;
355 pformat->u2.dwRBitMask = 0x0000F800;
356 pformat->u3.dwGBitMask = 0x000007C0;
357 pformat->u4.dwBBitMask = 0x0000003E;
358 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
359 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
360 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
362 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
363 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
364 pformat->u1.dwRGBBitCount = 16;
365 pformat->u2.dwRBitMask = 0x0000F000;
366 pformat->u3.dwGBitMask = 0x00000F00;
367 pformat->u4.dwBBitMask = 0x000000F0;
368 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
369 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
370 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
372 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
373 pformat->dwFlags = DDPF_RGB;
374 pformat->u1.dwRGBBitCount = 8;
375 pformat->u2.dwRBitMask = 0x000000E0;
376 pformat->u3.dwGBitMask = 0x0000001C;
377 pformat->u4.dwBBitMask = 0x00000003;
378 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
379 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
380 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
381 #endif
383 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
384 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
385 pformat->u1.dwRGBBitCount = 16;
386 pformat->u2.dwRBitMask = 0x00007C00;
387 pformat->u3.dwGBitMask = 0x000003E0;
388 pformat->u4.dwBBitMask = 0x0000001F;
389 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
390 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
391 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
393 TRACE("Enumerating Paletted (8)\n");
394 pformat->dwFlags = DDPF_PALETTEINDEXED8;
395 pformat->u1.dwRGBBitCount = 8;
396 pformat->u2.dwRBitMask = 0x00000000;
397 pformat->u3.dwGBitMask = 0x00000000;
398 pformat->u4.dwBBitMask = 0x00000000;
399 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
400 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
401 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
403 TRACE("End of enumeration\n");
404 return DD_OK;
408 HRESULT
409 d3ddevice_find(IDirect3DImpl *d3d,
410 LPD3DFINDDEVICESEARCH lpD3DDFS,
411 LPD3DFINDDEVICERESULT lplpD3DDevice,
412 DWORD interface_version)
414 DWORD dwSize;
415 D3DDEVICEDESC desc;
417 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
418 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
419 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
420 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
422 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
423 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
424 if ((IsEqualGUID( &IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
425 (IsEqualGUID( &IID_D3DDEVICE2_OpenGL, &(lpD3DDFS->guid)) == 0) &&
426 (IsEqualGUID( &IID_D3DDEVICE3_OpenGL, &(lpD3DDFS->guid)) == 0) &&
427 (IsEqualGUID( &IID_D3DDEVICE7_OpenGL, &(lpD3DDFS->guid)) == 0) &&
428 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0)) {
429 TRACE(" no match for this GUID.\n");
430 return DDERR_INVALIDPARAMS;
434 /* Now return our own GUIDs according to Direct3D version */
435 if (interface_version == 1) {
436 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
437 } else if (interface_version == 2) {
438 lplpD3DDevice->guid = IID_D3DDEVICE2_OpenGL;
439 } else if (interface_version == 3) {
440 lplpD3DDevice->guid = IID_D3DDEVICE3_OpenGL;
442 fill_opengl_caps(&desc);
443 dwSize = lplpD3DDevice->ddHwDesc.dwSize;
444 memset(&(lplpD3DDevice->ddHwDesc), 0, dwSize);
445 memcpy(&(lplpD3DDevice->ddHwDesc), &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
446 dwSize = lplpD3DDevice->ddSwDesc.dwSize;
447 memset(&(lplpD3DDevice->ddSwDesc), 0, dwSize);
448 memcpy(&(lplpD3DDevice->ddSwDesc), &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
450 return D3D_OK;
453 HRESULT WINAPI
454 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
455 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
456 LPVOID lpArg)
458 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
459 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
460 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
463 HRESULT WINAPI
464 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
465 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
466 LPVOID lpArg)
468 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
469 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
470 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
473 HRESULT WINAPI
474 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
475 D3DRENDERSTATETYPE dwRenderStateType,
476 DWORD dwRenderState)
478 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
479 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
480 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
482 /* Call the render state functions */
483 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
485 return DD_OK;
488 HRESULT WINAPI
489 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
490 D3DLIGHTSTATETYPE dwLightStateType,
491 DWORD dwLightState)
493 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
494 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
496 switch (dwLightStateType) {
497 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
498 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
500 if (mat != NULL) {
501 ENTER_GL();
502 mat->activate(mat);
503 LEAVE_GL();
504 } else {
505 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
507 } break;
509 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
510 float light[4];
512 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
513 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
514 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
515 light[3] = 1.0;
516 ENTER_GL();
517 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
518 LEAVE_GL();
519 } break;
521 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
522 UNSUP(COLORMODEL);
523 UNSUP(FOGMODE);
524 UNSUP(FOGSTART);
525 UNSUP(FOGEND);
526 UNSUP(FOGDENSITY);
527 #undef UNSUP
529 default:
530 TRACE("Unexpected Light State Type\n");
531 return DDERR_INVALIDPARAMS;
534 return DD_OK;
537 HRESULT WINAPI
538 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
539 D3DTRANSFORMSTATETYPE dtstTransformStateType,
540 LPD3DMATRIX lpD3DMatrix)
542 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
543 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
545 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
547 ENTER_GL();
549 /* Using a trial and failure approach, I found that the order of
550 Direct3D transformations that works best is :
552 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
554 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
555 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
557 If anyone has a good explanation of the three different matrices in
558 the SDK online documentation, feel free to point it to me. For example,
559 which matrices transform lights ? In OpenGL only the PROJECTION matrix
560 transform the lights, not the MODELVIEW. Using the matrix names, I
561 supposed that PROJECTION and VIEW (all 'camera' related names) do
562 transform lights, but WORLD do not. It may be wrong though... */
564 /* After reading through both OpenGL and Direct3D documentations, I
565 thought that D3D matrices were written in 'line major mode' transposed
566 from OpenGL's 'column major mode'. But I found out that a simple memcpy
567 works fine to transfer one matrix format to the other (it did not work
568 when transposing)....
570 So :
571 1) are the documentations wrong
572 2) does the matrix work even if they are not read correctly
573 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
574 loading using glLoadMatrix ?
576 Anyway, I always use 'conv_mat' to transfer the matrices from one format
577 to the other so that if I ever find out that I need to transpose them, I
578 will able to do it quickly, only by changing the macro conv_mat. */
580 switch (dtstTransformStateType) {
581 case D3DTRANSFORMSTATE_WORLD: {
582 conv_mat(lpD3DMatrix, glThis->world_mat);
583 glMatrixMode(GL_MODELVIEW);
584 glLoadMatrixf((float *) glThis->world_mat);
585 } break;
587 case D3DTRANSFORMSTATE_VIEW: {
588 conv_mat(lpD3DMatrix, glThis->view_mat);
589 glMatrixMode(GL_PROJECTION);
590 glLoadMatrixf((float *) glThis->proj_mat);
591 glMultMatrixf((float *) glThis->view_mat);
592 } break;
594 case D3DTRANSFORMSTATE_PROJECTION: {
595 conv_mat(lpD3DMatrix, glThis->proj_mat);
596 glMatrixMode(GL_PROJECTION);
597 glLoadMatrixf((float *) glThis->proj_mat);
598 glMultMatrixf((float *) glThis->view_mat);
599 } break;
601 default:
602 ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType);
603 break;
605 LEAVE_GL();
607 return DD_OK;
610 inline static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
612 switch (d3dpt) {
613 case D3DPT_POINTLIST:
614 TRACE("Start POINTS\n");
615 glBegin(GL_POINTS);
616 break;
618 case D3DPT_LINELIST:
619 TRACE("Start LINES\n");
620 glBegin(GL_LINES);
621 break;
623 case D3DPT_LINESTRIP:
624 TRACE("Start LINE_STRIP\n");
625 glBegin(GL_LINE_STRIP);
626 break;
628 case D3DPT_TRIANGLELIST:
629 TRACE("Start TRIANGLES\n");
630 glBegin(GL_TRIANGLES);
631 break;
633 case D3DPT_TRIANGLESTRIP:
634 TRACE("Start TRIANGLE_STRIP\n");
635 glBegin(GL_TRIANGLE_STRIP);
636 break;
638 case D3DPT_TRIANGLEFAN:
639 TRACE("Start TRIANGLE_FAN\n");
640 glBegin(GL_TRIANGLE_FAN);
641 break;
643 default:
644 TRACE("Unhandled primitive\n");
645 break;
649 inline static void draw_primitive(IDirect3DDeviceGLImpl *glThis, DWORD maxvert, WORD *index,
650 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
652 DWORD vx_index;
654 /* Puts GL in the correct lighting mode */
655 if (glThis->vertex_type != d3dvt) {
656 if ((glThis->vertex_type == D3DVT_TLVERTEX) &&
657 (d3dvt != D3DVT_TLVERTEX)) {
658 /* Need to put the correct transformation again if we go from Transformed / Lighted
659 vertices to non-transfromed ones.
661 glMatrixMode(GL_MODELVIEW);
662 glLoadMatrixf((float *) glThis->world_mat);
663 glMatrixMode(GL_PROJECTION);
664 glLoadMatrixf((float *) glThis->proj_mat);
665 glMultMatrixf((float *) glThis->view_mat);
668 switch (d3dvt) {
669 case D3DVT_VERTEX:
670 TRACE("Standard Vertex\n");
671 glEnable(GL_LIGHTING);
672 break;
674 case D3DVT_LVERTEX:
675 TRACE("Lighted Vertex\n");
676 glDisable(GL_LIGHTING);
677 break;
679 case D3DVT_TLVERTEX: {
680 GLdouble height, width, minZ, maxZ;
682 TRACE("Transformed - Lighted Vertex\n");
683 if (glThis->vertex_type != D3DVT_TLVERTEX) {
684 /* First, disable lighting */
685 glDisable(GL_LIGHTING);
687 /* Then do not put any transformation matrixes */
688 glMatrixMode(GL_MODELVIEW);
689 glLoadIdentity();
690 glMatrixMode(GL_PROJECTION);
691 glLoadIdentity();
694 if (glThis->parent.current_viewport == NULL) {
695 ERR("No current viewport !\n");
696 /* Using standard values */
697 height = 640.0;
698 width = 480.0;
699 minZ = -10.0;
700 maxZ = 10.0;
701 } else {
702 if (glThis->parent.current_viewport->use_vp2 == 1) {
703 height = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwHeight;
704 width = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwWidth;
705 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMinZ;
706 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMaxZ;
707 } else {
708 height = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwHeight;
709 width = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwWidth;
710 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMinZ;
711 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMaxZ;
715 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
716 } break;
718 default:
719 ERR("Unhandled vertex type\n");
720 break;
723 glThis->vertex_type = d3dvt;
726 draw_primitive_start_GL(d3dpt);
728 /* Draw the primitives */
729 for (vx_index = 0; vx_index < maxvert; vx_index++) {
730 switch (d3dvt) {
731 case D3DVT_VERTEX: {
732 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
734 glNormal3f(vx->u4.nx, vx->u5.ny, vx->u6.nz);
735 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
736 TRACE(" V: %f %f %f\n", vx->u1.x, vx->u2.y, vx->u3.z);
737 } break;
739 case D3DVT_LVERTEX: {
740 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
741 DWORD col = vx->u4.color;
743 glColor3f(((col >> 16) & 0xFF) / 255.0,
744 ((col >> 8) & 0xFF) / 255.0,
745 ((col >> 0) & 0xFF) / 255.0);
746 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
747 TRACE(" LV: %f %f %f (%02lx %02lx %02lx)\n",
748 vx->u1.x, vx->u2.y, vx->u3.z,
749 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF));
750 } break;
752 case D3DVT_TLVERTEX: {
753 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
754 DWORD col = vx->u5.color;
756 glColor4ub((col >> 24) & 0xFF,
757 (col >> 16) & 0xFF,
758 (col >> 8) & 0xFF,
759 (col >> 0) & 0xFF);
760 glTexCoord2f(vx->u7.tu, vx->u8.tv);
761 if (vx->u4.rhw < 0.01)
762 glVertex3f(vx->u1.sx,
763 vx->u2.sy,
764 vx->u3.sz);
765 else
766 glVertex4f(vx->u1.sx / vx->u4.rhw,
767 vx->u2.sy / vx->u4.rhw,
768 vx->u3.sz / vx->u4.rhw,
769 1.0 / vx->u4.rhw);
770 TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",
771 vx->u1.sx, vx->u2.sy, vx->u3.sz,
772 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF),
773 vx->u7.tu, vx->u8.tv, vx->u4.rhw);
774 } break;
776 default:
777 FIXME("Unhandled vertex type\n");
778 break;
782 glEnd();
783 TRACE("End\n");
786 HRESULT WINAPI
787 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
788 D3DPRIMITIVETYPE d3dptPrimitiveType,
789 D3DVERTEXTYPE d3dvtVertexType,
790 LPVOID lpvVertices,
791 DWORD dwVertexCount,
792 DWORD dwFlags)
794 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
795 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
797 ENTER_GL();
798 draw_primitive((IDirect3DDeviceGLImpl *) This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
799 LEAVE_GL();
801 return DD_OK;
804 HRESULT WINAPI
805 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
806 D3DPRIMITIVETYPE d3dptPrimitiveType,
807 D3DVERTEXTYPE d3dvtVertexType,
808 LPVOID lpvVertices,
809 DWORD dwVertexCount,
810 LPWORD dwIndices,
811 DWORD dwIndexCount,
812 DWORD dwFlags)
814 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
815 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
817 ENTER_GL();
818 draw_primitive((IDirect3DDeviceGLImpl *) This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
819 LEAVE_GL();
821 return DD_OK;
824 HRESULT WINAPI
825 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
826 LPD3DEXECUTEBUFFERDESC lpDesc,
827 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
828 IUnknown* pUnkOuter)
830 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
831 IDirect3DExecuteBufferImpl *ret;
832 HRESULT ret_value;
834 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
836 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
837 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
839 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
841 return ret_value;
844 static void dump_flexible_vertex(DWORD d3dvtVertexType)
846 static const flag_info flags[] = {
847 FE(D3DFVF_NORMAL),
848 FE(D3DFVF_RESERVED1),
849 FE(D3DFVF_DIFFUSE),
850 FE(D3DFVF_SPECULAR)
852 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
853 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
854 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
855 GEN_CASE(D3DFVF_XYZ);
856 GEN_CASE(D3DFVF_XYZRHW);
857 GEN_CASE(D3DFVF_XYZB1);
858 GEN_CASE(D3DFVF_XYZB2);
859 GEN_CASE(D3DFVF_XYZB3);
860 GEN_CASE(D3DFVF_XYZB4);
861 GEN_CASE(D3DFVF_XYZB5);
863 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
864 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
865 GEN_CASE(D3DFVF_TEX0);
866 GEN_CASE(D3DFVF_TEX1);
867 GEN_CASE(D3DFVF_TEX2);
868 GEN_CASE(D3DFVF_TEX3);
869 GEN_CASE(D3DFVF_TEX4);
870 GEN_CASE(D3DFVF_TEX5);
871 GEN_CASE(D3DFVF_TEX6);
872 GEN_CASE(D3DFVF_TEX7);
873 GEN_CASE(D3DFVF_TEX8);
875 #undef GEN_CASE
876 DPRINTF("\n");
879 /* Some types used by the fast paths... */
880 typedef struct {
881 float x, y, z;
882 float nx, ny, nz;
883 DWORD dwDiffuseRGBA;
884 float tu1, tv1;
885 } D3DFVF_VERTEX_1;
887 static void draw_primitive_7(IDirect3DDeviceImpl *This,
888 D3DPRIMITIVETYPE d3dptPrimitiveType,
889 DWORD d3dvtVertexType,
890 LPVOID lpvVertices,
891 DWORD dwVertexCount,
892 LPWORD dwIndices,
893 DWORD dwIndexCount,
894 DWORD dwFlags)
896 if (TRACE_ON(ddraw)) {
897 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
900 ENTER_GL();
901 draw_primitive_start_GL(d3dptPrimitiveType);
903 /* Some fast paths first before the generic case.... */
904 if (d3dvtVertexType == D3DFVF_VERTEX) {
905 D3DFVF_VERTEX_1 *vertices = (D3DFVF_VERTEX_1 *) lpvVertices;
906 int index;
908 for (index = 0; index < dwIndexCount; index++) {
909 int i = (dwIndices == NULL) ? index : dwIndices[index];
911 glNormal3f(vertices[i].nx, vertices[i].ny, vertices[i].nz);
912 glTexCoord2f(vertices[i].tu1, vertices[i].tv1);
913 glColor4ub((vertices[i].dwDiffuseRGBA >> 24) & 0xFF,
914 (vertices[i].dwDiffuseRGBA >> 16) & 0xFF,
915 (vertices[i].dwDiffuseRGBA >> 8) & 0xFF,
916 (vertices[i].dwDiffuseRGBA >> 0) & 0xFF);
917 glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
918 TRACE(" %f %f %f / %f %f %f (%02lx %02lx %02lx %02lx) (%f %f)\n",
919 vertices[i].x, vertices[i].y, vertices[i].z,
920 vertices[i].nx, vertices[i].ny, vertices[i].nz,
921 (vertices[i].dwDiffuseRGBA >> 24) & 0xFF,
922 (vertices[i].dwDiffuseRGBA >> 16) & 0xFF,
923 (vertices[i].dwDiffuseRGBA >> 8) & 0xFF,
924 (vertices[i].dwDiffuseRGBA >> 0) & 0xFF,
925 vertices[i].tu1, vertices[i].tv1);
929 glEnd();
930 LEAVE_GL();
931 TRACE("End\n");
935 HRESULT WINAPI
936 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
937 D3DPRIMITIVETYPE d3dptPrimitiveType,
938 DWORD d3dvtVertexType,
939 LPVOID lpvVertices,
940 DWORD dwVertexCount,
941 DWORD dwFlags)
943 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
944 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
946 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, NULL, dwVertexCount, dwFlags);
948 return DD_OK;
951 HRESULT WINAPI
952 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
953 D3DPRIMITIVETYPE d3dptPrimitiveType,
954 DWORD d3dvtVertexType,
955 LPVOID lpvVertices,
956 DWORD dwVertexCount,
957 LPWORD dwIndices,
958 DWORD dwIndexCount,
959 DWORD dwFlags)
961 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
962 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
964 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
966 return DD_OK;
969 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
970 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
971 #else
972 # define XCAST(fun) (void*)
973 #endif
975 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
977 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
978 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
979 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
980 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
981 XCAST(GetCaps) Main_IDirect3DDeviceImpl_7_GetCaps,
982 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
983 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
984 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
985 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
986 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
987 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
988 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
989 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
990 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
991 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
992 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
993 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
994 XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
995 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
996 XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
997 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
998 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
999 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1000 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1001 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1002 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1003 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1004 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1005 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1006 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1007 XCAST(DrawPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1008 XCAST(DrawIndexedPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1009 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB,
1010 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
1011 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1012 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
1013 XCAST(SetTexture) Main_IDirect3DDeviceImpl_7_SetTexture,
1014 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1015 XCAST(SetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1016 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1017 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1018 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1019 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1020 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1021 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1022 XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
1023 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1024 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1025 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1026 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1029 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1030 #undef XCAST
1031 #endif
1034 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1035 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1036 #else
1037 # define XCAST(fun) (void*)
1038 #endif
1040 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1042 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1043 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1044 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1045 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1046 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1047 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1048 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1049 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1050 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1051 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1052 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1053 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1054 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1055 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1056 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1057 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1058 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1059 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1060 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1061 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1062 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1063 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1064 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1065 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1066 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1067 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1068 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1069 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1070 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1071 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1072 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1073 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1074 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1075 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1076 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1077 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1078 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1079 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1080 XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
1081 XCAST(SetTexture) Main_IDirect3DDeviceImpl_3_SetTexture,
1082 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1083 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1084 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1087 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1088 #undef XCAST
1089 #endif
1092 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1093 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1094 #else
1095 # define XCAST(fun) (void*)
1096 #endif
1098 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1100 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1101 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1102 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1103 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1104 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1105 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
1106 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1107 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1108 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1109 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1110 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1111 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1112 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1113 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1114 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1115 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1116 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1117 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1118 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1119 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1120 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1121 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1122 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1123 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1124 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1125 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1126 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1127 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1128 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1129 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1130 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1131 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1132 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1133 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1136 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1137 #undef XCAST
1138 #endif
1141 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1142 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1143 #else
1144 # define XCAST(fun) (void*)
1145 #endif
1147 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1149 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1150 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1151 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1152 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1153 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1154 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1155 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
1156 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1157 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1158 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1159 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1160 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1161 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1162 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1163 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1164 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1165 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1166 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1167 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1168 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1169 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1170 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1171 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1174 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1175 #undef XCAST
1176 #endif
1178 /* TODO for both these functions :
1179 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1180 by other OpenGL code in D3D
1181 - handle the case where no 'Begin / EndScene' was done between two locks
1182 - handle the rectangles in the unlock too
1184 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1186 /* First, check if we need to do anything */
1187 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1188 GLenum buffer_type;
1189 GLenum prev_read;
1190 RECT loc_rect;
1192 ENTER_GL();
1194 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1195 glFlush();
1197 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1198 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1199 /* Application wants to lock the front buffer */
1200 glReadBuffer(GL_FRONT);
1201 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1202 /* Application wants to lock the back buffer */
1203 glReadBuffer(GL_BACK);
1204 } else {
1205 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1208 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1209 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1210 } else {
1211 WARN(" unsupported pixel format.\n");
1212 LEAVE_GL();
1213 return;
1215 if (pRect == NULL) {
1216 loc_rect.top = 0;
1217 loc_rect.left = 0;
1218 loc_rect.bottom = This->surface_desc.dwHeight;
1219 loc_rect.right = This->surface_desc.dwWidth;
1220 } else {
1221 loc_rect = *pRect;
1223 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1224 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1225 + loc_rect.top * This->surface_desc.u1.lPitch
1226 + loc_rect.left * GET_BPP(This->surface_desc)));
1227 glReadBuffer(prev_read);
1228 LEAVE_GL();
1232 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1234 /* First, check if we need to do anything */
1235 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1236 GLenum buffer_type;
1237 GLenum prev_draw;
1239 ENTER_GL();
1241 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1243 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1244 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1245 /* Application wants to lock the front buffer */
1246 glDrawBuffer(GL_FRONT);
1247 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1248 /* Application wants to lock the back buffer */
1249 glDrawBuffer(GL_BACK);
1250 } else {
1251 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1254 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1255 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1256 } else {
1257 WARN(" unsupported pixel format.\n");
1258 LEAVE_GL();
1259 return;
1262 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
1263 GL_RGB, buffer_type, This->surface_desc.lpSurface);
1264 glDrawBuffer(prev_draw);
1266 LEAVE_GL();
1270 HRESULT
1271 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
1273 IDirect3DDeviceImpl *object;
1274 IDirect3DDeviceGLImpl *gl_object;
1275 IDirectDrawSurfaceImpl *surf;
1276 HDC device_context;
1277 XVisualInfo *vis;
1278 int num;
1279 XVisualInfo template;
1280 GLenum buffer;
1282 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1283 if (object == NULL) return DDERR_OUTOFMEMORY;
1285 gl_object = (IDirect3DDeviceGLImpl *) object;
1287 object->ref = 1;
1288 object->d3d = d3d;
1289 object->surface = surface;
1290 object->viewport_list = NULL;
1291 object->current_viewport = NULL;
1292 object->current_texture = NULL;
1293 object->set_context = set_context;
1295 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1297 device_context = GetDC(surface->ddraw_owner->window);
1298 gl_object->display = get_display(device_context);
1299 gl_object->drawable = get_drawable(device_context);
1300 ReleaseDC(surface->ddraw_owner->window,device_context);
1302 ENTER_GL();
1303 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1304 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
1305 if (vis == NULL) {
1306 HeapFree(GetProcessHeap(), 0, object);
1307 ERR("No visual found !\n");
1308 LEAVE_GL();
1309 return DDERR_INVALIDPARAMS;
1310 } else {
1311 TRACE(" visual found\n");
1314 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
1315 NULL, GL_TRUE);
1317 if (gl_object->gl_context == NULL) {
1318 HeapFree(GetProcessHeap(), 0, object);
1319 ERR("Error in context creation !\n");
1320 LEAVE_GL();
1321 return DDERR_INVALIDPARAMS;
1322 } else {
1323 TRACE(" context created (%p)\n", gl_object->gl_context);
1326 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
1327 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
1328 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
1329 surf->aux_ctx = (LPVOID) gl_object->display;
1330 surf->aux_data = (LPVOID) gl_object->drawable;
1331 surf->aux_flip = opengl_flip;
1332 buffer = GL_BACK;
1333 break;
1336 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
1337 if (surf == NULL) {
1338 TRACE(" no double buffering : drawing on the front buffer\n");
1339 buffer = GL_FRONT;
1342 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
1343 for (; surf != NULL; surf = surf->next_attached) {
1344 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
1345 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
1346 /* Override the Lock / Unlock function for all these surfaces */
1347 surf->lock_update = d3ddevice_lock_update;
1348 surf->unlock_update = d3ddevice_unlock_update;
1350 surf->d3ddevice = object;
1353 gl_object->render_state.src = GL_ONE;
1354 gl_object->render_state.dst = GL_ZERO;
1355 gl_object->render_state.mag = GL_NEAREST;
1356 gl_object->render_state.min = GL_NEAREST;
1357 gl_object->vertex_type = 0;
1359 /* Allocate memory for the matrices */
1360 gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1361 gl_object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1362 gl_object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1364 memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float));
1365 memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float));
1366 memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float));
1368 /* Initialisation */
1369 TRACE(" setting current context\n");
1370 LEAVE_GL();
1371 object->set_context(object);
1372 ENTER_GL();
1373 TRACE(" current context set\n");
1374 glClearColor(0.0, 0.0, 0.0, 0.0);
1375 glColor3f(1.0, 1.0, 1.0);
1376 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1377 glDrawBuffer(buffer);
1378 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
1379 LEAVE_GL();
1381 /* fill_device_capabilities(d3d->ddraw); */
1383 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
1384 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
1385 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
1386 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
1388 *obj = object;
1390 TRACE(" creating implementation at %p.\n", *obj);
1392 return DD_OK;