2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the MESA implementation of all the D3D devices that
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/obj_base.h"
31 #include "wine/debug.h"
33 #include "mesa_private.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
= {
45 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
48 const GUID IID_D3DDEVICE2_OpenGL
= {
52 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfb }
55 const GUID IID_D3DDEVICE3_OpenGL
= {
59 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfc }
62 const GUID IID_D3DDEVICE7_OpenGL
= {
66 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfd }
69 const GUID IID_D3DDEVICE_Default
= {
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
,
89 static const float id_mat
[16] = {
96 /* retrieve the X display to use on a given DC */
97 inline static Display
*get_display( HDC hdc
)
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
;
109 /* retrieve the X drawable to use on a given DC */
110 inline static Drawable
get_drawable( HDC hdc
)
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;
122 static BOOL
opengl_flip( LPVOID display
, LPVOID drawable
)
124 TRACE("(%p, %ld)\n",(Display
*)display
,(Drawable
)drawable
);
126 glXSwapBuffers((Display
*)display
,(Drawable
)drawable
);
132 /*******************************************************************************
133 * OpenGL static functions
135 static void set_context(IDirect3DDeviceImpl
* This
) {
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
);
147 ERR("This function should not be called in the current state of the code...\n");
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
;
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
);
224 TRACE("Color table extension not found.\n");
232 HRESULT
d3device_enumerate(LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
, DWORD interface_version
)
234 D3DDEVICEDESC d1
, d2
;
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
);
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
);
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
));
267 glXDestroyContext(glThis
->display
, glThis
->gl_context
);
270 HeapFree(GetProcessHeap(), 0, This
);
277 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface
,
278 LPD3DDEVICEDESC lpD3DHWDevDesc
,
279 LPD3DDEVICEDESC lpD3DHELDevDesc
)
281 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
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");
301 static HRESULT
enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1
,
302 LPD3DENUMPIXELFORMATSCALLBACK cb_2
,
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
;
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");
405 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface
,
406 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc
,
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
);
415 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface
,
416 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc
,
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
);
425 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface
,
426 D3DRENDERSTATETYPE dwRenderStateType
,
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
));
440 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface
,
441 D3DLIGHTSTATETYPE dwLightStateType
,
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
;
456 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
460 case D3DLIGHTSTATE_AMBIENT
: { /* 2 */
463 light
[0] = ((dwLightState
>> 16) & 0xFF) / 255.0;
464 light
[1] = ((dwLightState
>> 8) & 0xFF) / 255.0;
465 light
[2] = ((dwLightState
>> 0) & 0xFF) / 255.0;
468 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, (float *) light
);
472 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
481 TRACE("Unexpected Light State Type\n");
482 return DDERR_INVALIDPARAMS
;
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
);
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)....
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
);
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
);
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
);
553 ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType
);
561 inline static void draw_primitive(IDirect3DDeviceGLImpl
*glThis
, DWORD maxvert
, WORD
*index
,
562 D3DVERTEXTYPE d3dvt
, D3DPRIMITIVETYPE d3dpt
, void *lpvertex
)
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
);
579 TRACE("Standard Vertex\n");
580 glEnable(GL_LIGHTING
);
584 TRACE("Lighted Vertex\n");
585 glDisable(GL_LIGHTING
);
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
);
598 glMatrixMode(GL_PROJECTION
);
601 if (glThis
->parent
.current_viewport
== NULL
) {
602 ERR("No current viewport !\n");
603 /* Using standard values */
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
;
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
);
626 ERR("Unhandled vertex type\n");
630 glThis
->vertex_type
= d3dvt
;
634 case D3DPT_POINTLIST
:
635 TRACE("Start POINTS\n");
640 TRACE("Start LINES\n");
644 case D3DPT_LINESTRIP
:
645 TRACE("Start LINE_STRIP\n");
646 glBegin(GL_LINE_STRIP
);
649 case D3DPT_TRIANGLELIST
:
650 TRACE("Start TRIANGLES\n");
651 glBegin(GL_TRIANGLES
);
654 case D3DPT_TRIANGLESTRIP
:
655 TRACE("Start TRIANGLE_STRIP\n");
656 glBegin(GL_TRIANGLE_STRIP
);
659 case D3DPT_TRIANGLEFAN
:
660 TRACE("Start TRIANGLE_FAN\n");
661 glBegin(GL_TRIANGLE_FAN
);
665 TRACE("Unhandled primitive\n");
669 /* Draw the primitives */
670 for (vx_index
= 0; vx_index
< maxvert
; vx_index
++) {
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
);
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));
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
,
706 glVertex4f(vx
->u1
.sx
/ vx
->u4
.rhw
,
707 vx
->u2
.sy
/ vx
->u4
.rhw
,
708 vx
->u3
.sz
/ 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
);
717 FIXME("Unhandled vertex type\n");
727 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface
,
728 D3DPRIMITIVETYPE d3dptPrimitiveType
,
729 D3DVERTEXTYPE d3dvtVertexType
,
734 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
735 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwFlags
);
738 draw_primitive((IDirect3DDeviceGLImpl
*) This
, dwVertexCount
, NULL
, d3dvtVertexType
, d3dptPrimitiveType
, lpvVertices
);
745 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface
,
746 D3DPRIMITIVETYPE d3dptPrimitiveType
,
747 D3DVERTEXTYPE d3dvtVertexType
,
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
);
758 draw_primitive((IDirect3DDeviceGLImpl
*) This
, dwIndexCount
, dwIndices
, d3dvtVertexType
, d3dptPrimitiveType
, lpvVertices
);
765 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface
,
766 LPD3DEXECUTEBUFFERDESC lpDesc
,
767 LPDIRECT3DEXECUTEBUFFER
* lplpDirect3DExecuteBuffer
,
770 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
771 IDirect3DExecuteBufferImpl
*ret
;
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
);
784 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
785 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
787 # define XCAST(fun) (void*)
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__)
849 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
850 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
852 # define XCAST(fun) (void*)
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__)
907 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
908 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
910 # define XCAST(fun) (void*)
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__)
956 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
957 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
959 # define XCAST(fun) (void*)
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__)
997 d3ddevice_create(IDirect3DDeviceImpl
**obj
, IDirect3DImpl
*d3d
, IDirectDrawSurfaceImpl
*surface
)
999 IDirect3DDeviceImpl
*object
;
1000 IDirect3DDeviceGLImpl
*gl_object
;
1001 IDirectDrawSurfaceImpl
*surf
;
1005 XVisualInfo
template;
1007 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DDeviceGLImpl
));
1008 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
1010 gl_object
= (IDirect3DDeviceGLImpl
*) object
;
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
);
1028 template.visualid
= (VisualID
)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1029 vis
= XGetVisualInfo(gl_object
->display
, VisualIDMask
, &template, &num
);
1031 HeapFree(GetProcessHeap(), 0, object
);
1032 ERR("No visual found !\n");
1034 return DDERR_INVALIDPARAMS
;
1036 TRACE(" visual found\n");
1039 gl_object
->gl_context
= glXCreateContext(gl_object
->display
, vis
,
1042 if (gl_object
->gl_context
== NULL
) {
1043 HeapFree(GetProcessHeap(), 0, object
);
1044 ERR("Error in context creation !\n");
1046 return DDERR_INVALIDPARAMS
;
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
;
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");
1079 object
->set_context(object
);
1081 TRACE(" current context set\n");
1082 glClearColor(0.0, 0.0, 0.0, 0.0);
1083 glColor3f(1.0, 1.0, 1.0);
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
);
1095 TRACE(" creating implementation at %p.\n", *obj
);