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
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 #ifndef HAVE_GLEXT_PROTOTYPES
49 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
50 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
51 GLsizei width, GLenum format, GLenum type,
55 static const float id_mat[16] = {
62 /* retrieve the X display to use on a given DC */
63 inline static Display *get_display( HDC hdc )
66 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
68 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
69 sizeof(display), (LPSTR)&display )) display = NULL;
75 /* retrieve the X drawable to use on a given DC */
76 inline static Drawable get_drawable( HDC hdc )
79 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
81 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
82 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
88 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
90 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
92 glXSwapBuffers((Display*)display,(Drawable)drawable);
98 /*******************************************************************************
99 * OpenGL static functions
101 static void set_context(IDirect3DDeviceImpl* This)
103 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
106 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
107 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
108 ERR("Error in setting current context (context %p drawable %ld)!\n",
109 glThis->gl_context, glThis->drawable);
114 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
116 pc->dwSize = sizeof(*pc);
117 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
118 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
119 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
120 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
121 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
122 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
123 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
124 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
125 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
126 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
127 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
128 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
129 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
130 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
131 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
132 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
133 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
134 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
135 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
136 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
137 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
138 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
139 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
140 pc->dwStippleWidth = 32;
141 pc->dwStippleHeight = 32;
144 static void fill_opengl_caps(D3DDEVICEDESC *d1)
146 /* GLint maxlight; */
148 d1->dwSize = sizeof(*d1);
149 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
150 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
151 d1->dcmColorModel = D3DCOLOR_RGB;
152 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
153 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
154 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
155 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
156 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
157 d1->bClipping = TRUE;
158 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
159 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
160 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
161 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
162 fill_opengl_primcaps(&(d1->dpcLineCaps));
163 fill_opengl_primcaps(&(d1->dpcTriCaps));
164 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
165 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
166 d1->dwMaxBufferSize = 0;
167 d1->dwMaxVertexCount = 65536;
168 d1->dwMinTextureWidth = 1;
169 d1->dwMinTextureHeight = 1;
170 d1->dwMaxTextureWidth = 1024;
171 d1->dwMaxTextureHeight = 1024;
172 d1->dwMinStippleWidth = 1;
173 d1->dwMinStippleHeight = 1;
174 d1->dwMaxStippleWidth = 32;
175 d1->dwMaxStippleHeight = 32;
176 d1->dwMaxTextureRepeat = 16;
177 d1->dwMaxTextureAspectRatio = 1024;
178 d1->dwMaxAnisotropy = 0;
179 d1->dvGuardBandLeft = 0.0;
180 d1->dvGuardBandRight = 0.0;
181 d1->dvGuardBandTop = 0.0;
182 d1->dvGuardBandBottom = 0.0;
183 d1->dvExtentsAdjust = 0.0;
184 d1->dwStencilCaps = 0; /* TODO add proper caps according to what OpenGL can do */
185 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
186 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
187 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
188 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
191 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
195 /* Copy first D3D1/2/3 capabilities */
196 fill_opengl_caps(&d1);
198 /* And fill the D3D7 one with it */
199 d->dwDevCaps = d1.dwDevCaps;
200 d->dpcLineCaps = d1.dpcLineCaps;
201 d->dpcTriCaps = d1.dpcTriCaps;
202 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
203 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
204 d->dwMinTextureWidth = d1.dwMinTextureWidth;
205 d->dwMinTextureHeight = d1.dwMinTextureHeight;
206 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
207 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
208 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
209 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
210 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
211 d->dvGuardBandLeft = d1.dvGuardBandLeft;
212 d->dvGuardBandTop = d1.dvGuardBandTop;
213 d->dvGuardBandRight = d1.dvGuardBandRight;
214 d->dvGuardBandBottom = d1.dvGuardBandBottom;
215 d->dvExtentsAdjust = d1.dvExtentsAdjust;
216 d->dwStencilCaps = d1.dwStencilCaps;
217 d->dwFVFCaps = d1.dwFVFCaps;
218 d->dwTextureOpCaps = d1.dwTextureOpCaps;
219 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
220 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
221 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
222 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
223 d->deviceGUID = IID_IDirect3DTnLHalDevice;
224 d->wMaxUserClipPlanes = 1;
225 d->wMaxVertexBlendMatrices = 0;
226 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
227 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
234 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
235 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
237 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
238 const char *ext_string;
239 Mesa_DeviceCapabilities *devcap;
241 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
242 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
245 ext_string = glGetString(GL_EXTENSIONS);
246 /* Query for the ColorTable Extension */
247 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
248 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
249 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
251 TRACE("Color table extension not found.\n");
259 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
261 D3DDEVICEDESC d1, d2;
263 fill_opengl_caps(&d1);
266 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
267 return cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
270 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
272 D3DDEVICEDESC7 ddesc;
274 fill_opengl_caps_7(&ddesc);
276 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
278 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
282 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
284 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
285 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
287 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
288 if (!--(This->ref)) {
289 /* Release texture associated with the device */
290 if (This->current_texture[0] != NULL)
291 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
293 if (glThis->handler) HeapFree(GetProcessHeap(), 0, This);
296 glXDestroyContext(glThis->display, glThis->gl_context);
299 HeapFree(GetProcessHeap(), 0, This);
306 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
307 LPD3DDEVICEDESC lpD3DHWDevDesc,
308 LPD3DDEVICEDESC lpD3DHELDevDesc)
310 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
314 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
316 fill_opengl_caps(&desc);
317 dwSize = lpD3DHWDevDesc->dwSize;
318 memset(lpD3DHWDevDesc, 0, dwSize);
319 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
321 dwSize = lpD3DHELDevDesc->dwSize;
322 memset(lpD3DHELDevDesc, 0, dwSize);
323 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
325 TRACE(" returning caps : (no dump function yet)\n");
330 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
331 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
335 LPDDPIXELFORMAT pformat;
337 /* Do the texture enumeration */
338 sdesc.dwSize = sizeof(DDSURFACEDESC);
339 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
340 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
341 pformat = &(sdesc.ddpfPixelFormat);
342 pformat->dwSize = sizeof(DDPIXELFORMAT);
343 pformat->dwFourCC = 0;
345 TRACE("Enumerating GL_RGBA unpacked (32)\n");
346 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
347 pformat->u1.dwRGBBitCount = 32;
348 pformat->u2.dwRBitMask = 0xFF000000;
349 pformat->u3.dwGBitMask = 0x00FF0000;
350 pformat->u4.dwBBitMask = 0x0000FF00;
351 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
352 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
353 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
355 TRACE("Enumerating GL_RGB unpacked (24)\n");
356 pformat->dwFlags = DDPF_RGB;
357 pformat->u1.dwRGBBitCount = 24;
358 pformat->u2.dwRBitMask = 0x00FF0000;
359 pformat->u3.dwGBitMask = 0x0000FF00;
360 pformat->u4.dwBBitMask = 0x000000FF;
361 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
362 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
363 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
365 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
366 pformat->dwFlags = DDPF_RGB;
367 pformat->u1.dwRGBBitCount = 16;
368 pformat->u2.dwRBitMask = 0x0000F800;
369 pformat->u3.dwGBitMask = 0x000007E0;
370 pformat->u4.dwBBitMask = 0x0000001F;
371 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
372 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
373 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
375 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
376 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
377 pformat->u1.dwRGBBitCount = 16;
378 pformat->u2.dwRBitMask = 0x0000F800;
379 pformat->u3.dwGBitMask = 0x000007C0;
380 pformat->u4.dwBBitMask = 0x0000003E;
381 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
382 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
383 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
385 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
386 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
387 pformat->u1.dwRGBBitCount = 16;
388 pformat->u2.dwRBitMask = 0x0000F000;
389 pformat->u3.dwGBitMask = 0x00000F00;
390 pformat->u4.dwBBitMask = 0x000000F0;
391 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
392 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
393 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
395 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (16)\n");
396 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
397 pformat->u1.dwRGBBitCount = 16;
398 pformat->u2.dwRBitMask = 0x00007C00;
399 pformat->u3.dwGBitMask = 0x000003E0;
400 pformat->u4.dwBBitMask = 0x0000001F;
401 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
402 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
403 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
405 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
406 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
407 pformat->u1.dwRGBBitCount = 16;
408 pformat->u2.dwRBitMask = 0x00000F00;
409 pformat->u3.dwGBitMask = 0x000000F0;
410 pformat->u4.dwBBitMask = 0x0000000F;
411 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
412 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
413 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
415 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
416 pformat->dwFlags = DDPF_RGB;
417 pformat->u1.dwRGBBitCount = 8;
418 pformat->u2.dwRBitMask = 0x000000E0;
419 pformat->u3.dwGBitMask = 0x0000001C;
420 pformat->u4.dwBBitMask = 0x00000003;
421 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
422 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
423 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
425 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
426 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
427 pformat->u1.dwRGBBitCount = 16;
428 pformat->u2.dwRBitMask = 0x00007C00;
429 pformat->u3.dwGBitMask = 0x000003E0;
430 pformat->u4.dwBBitMask = 0x0000001F;
431 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
432 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
433 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
435 TRACE("Enumerating Paletted (8)\n");
436 pformat->dwFlags = DDPF_PALETTEINDEXED8;
437 pformat->u1.dwRGBBitCount = 8;
438 pformat->u2.dwRBitMask = 0x00000000;
439 pformat->u3.dwGBitMask = 0x00000000;
440 pformat->u4.dwBBitMask = 0x00000000;
441 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
442 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
443 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
445 TRACE("End of enumeration\n");
451 d3ddevice_find(IDirect3DImpl *d3d,
452 LPD3DFINDDEVICESEARCH lpD3DDFS,
453 LPD3DFINDDEVICERESULT lplpD3DDevice)
457 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
458 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
459 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
460 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
462 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
463 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
464 if ((IsEqualGUID( &IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
465 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0)) {
466 TRACE(" no match for this GUID.\n");
467 return DDERR_INVALIDPARAMS;
471 /* Now return our own GUID */
472 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
473 fill_opengl_caps(&desc);
474 lplpD3DDevice->ddHwDesc = desc;
475 lplpD3DDevice->ddSwDesc = desc;
477 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
483 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
484 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
487 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
488 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
489 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
493 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
494 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
497 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
498 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
499 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
503 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
504 D3DRENDERSTATETYPE dwRenderStateType,
507 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
508 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
509 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
511 /* Call the render state functions */
512 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
518 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
519 D3DLIGHTSTATETYPE dwLightStateType,
522 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
523 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
525 switch (dwLightStateType) {
526 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
527 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
534 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
538 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
541 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
542 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
543 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
546 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
550 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
560 TRACE("Unexpected Light State Type\n");
561 return DDERR_INVALIDPARAMS;
568 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
569 D3DTRANSFORMSTATETYPE dtstTransformStateType,
570 LPD3DMATRIX lpD3DMatrix)
572 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
573 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
575 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
579 /* Using a trial and failure approach, I found that the order of
580 Direct3D transformations that works best is :
582 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
584 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
585 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
587 If anyone has a good explanation of the three different matrices in
588 the SDK online documentation, feel free to point it to me. For example,
589 which matrices transform lights ? In OpenGL only the PROJECTION matrix
590 transform the lights, not the MODELVIEW. Using the matrix names, I
591 supposed that PROJECTION and VIEW (all 'camera' related names) do
592 transform lights, but WORLD do not. It may be wrong though... */
594 /* After reading through both OpenGL and Direct3D documentations, I
595 thought that D3D matrices were written in 'line major mode' transposed
596 from OpenGL's 'column major mode'. But I found out that a simple memcpy
597 works fine to transfer one matrix format to the other (it did not work
598 when transposing)....
601 1) are the documentations wrong
602 2) does the matrix work even if they are not read correctly
603 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
604 loading using glLoadMatrix ?
606 Anyway, I always use 'conv_mat' to transfer the matrices from one format
607 to the other so that if I ever find out that I need to transpose them, I
608 will able to do it quickly, only by changing the macro conv_mat. */
610 switch (dtstTransformStateType) {
611 case D3DTRANSFORMSTATE_WORLD: {
612 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
613 conv_mat(lpD3DMatrix, glThis->world_mat);
614 glMatrixMode(GL_MODELVIEW);
615 glLoadMatrixf((float *) glThis->view_mat);
616 glMultMatrixf((float *) glThis->world_mat);
619 case D3DTRANSFORMSTATE_VIEW: {
620 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
621 conv_mat(lpD3DMatrix, glThis->view_mat);
622 glMatrixMode(GL_MODELVIEW);
623 glLoadMatrixf((float *) glThis->view_mat);
624 glMultMatrixf((float *) glThis->world_mat);
627 case D3DTRANSFORMSTATE_PROJECTION: {
628 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
629 conv_mat(lpD3DMatrix, glThis->proj_mat);
630 glMatrixMode(GL_PROJECTION);
631 glLoadMatrixf((float *) glThis->proj_mat);
635 ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType);
643 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
646 case D3DPT_POINTLIST:
647 TRACE("Start POINTS\n");
652 TRACE("Start LINES\n");
656 case D3DPT_LINESTRIP:
657 TRACE("Start LINE_STRIP\n");
658 glBegin(GL_LINE_STRIP);
661 case D3DPT_TRIANGLELIST:
662 TRACE("Start TRIANGLES\n");
663 glBegin(GL_TRIANGLES);
666 case D3DPT_TRIANGLESTRIP:
667 TRACE("Start TRIANGLE_STRIP\n");
668 glBegin(GL_TRIANGLE_STRIP);
671 case D3DPT_TRIANGLEFAN:
672 TRACE("Start TRIANGLE_FAN\n");
673 glBegin(GL_TRIANGLE_FAN);
677 TRACE("Unhandled primitive\n");
682 static void draw_primitive_handle_GL_state(IDirect3DDeviceGLImpl *glThis,
683 BOOLEAN vertex_transformed,
684 BOOLEAN vertex_lit) {
685 /* Puts GL in the correct lighting / transformation mode */
686 if ((glThis->last_vertices_transformed == TRUE) && (vertex_transformed == FALSE)) {
687 /* Need to put the correct transformation again if we go from Transformed
688 vertices to non-transformed ones.
690 glMatrixMode(GL_MODELVIEW);
691 glLoadMatrixf((float *) glThis->view_mat);
692 glMultMatrixf((float *) glThis->world_mat);
693 glMatrixMode(GL_PROJECTION);
694 glLoadMatrixf((float *) glThis->proj_mat);
695 } else if ((glThis->last_vertices_transformed == FALSE) && (vertex_transformed == TRUE)) {
696 GLdouble height, width, minZ, maxZ;
698 glMatrixMode(GL_MODELVIEW);
700 glMatrixMode(GL_PROJECTION);
703 if (glThis->parent.current_viewport == NULL) {
704 ERR("No current viewport !\n");
705 /* Using standard values */
711 if (glThis->parent.current_viewport->use_vp2 == 1) {
712 height = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwHeight;
713 width = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwWidth;
714 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMinZ;
715 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMaxZ;
717 height = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwHeight;
718 width = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwWidth;
719 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMinZ;
720 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMaxZ;
723 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
726 if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) {
727 glEnable(GL_LIGHTING);
728 } else if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == TRUE)) {
729 glDisable(GL_LIGHTING);
732 /* And save the current state */
733 glThis->last_vertices_transformed = vertex_transformed;
734 glThis->last_vertices_lit = vertex_lit;
738 inline static void draw_primitive(IDirect3DDeviceGLImpl *glThis, DWORD maxvert, WORD *index,
739 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
743 draw_primitive_handle_GL_state(glThis, d3dvt == D3DVT_TLVERTEX, d3dvt != D3DVT_VERTEX);
744 draw_primitive_start_GL(d3dpt);
746 /* Draw the primitives */
747 for (vx_index = 0; vx_index < maxvert; vx_index++) {
750 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
752 glNormal3f(vx->u4.nx, vx->u5.ny, vx->u6.nz);
753 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
754 TRACE(" V: %f %f %f\n", vx->u1.x, vx->u2.y, vx->u3.z);
757 case D3DVT_LVERTEX: {
758 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
759 DWORD col = vx->u4.color;
761 glColor4ub((col >> 16) & 0xFF,
765 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
766 TRACE(" LV: %f %f %f (%02lx %02lx %02lx %02lx)\n",
767 vx->u1.x, vx->u2.y, vx->u3.z,
768 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), ((col >> 24) & 0xFF));
771 case D3DVT_TLVERTEX: {
772 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
773 DWORD col = vx->u5.color;
775 glColor4ub((col >> 16) & 0xFF,
779 glTexCoord2f(vx->u7.tu, vx->u8.tv);
780 if (vx->u4.rhw < 0.01)
781 glVertex3f(vx->u1.sx,
785 glVertex4f(vx->u1.sx / vx->u4.rhw,
786 vx->u2.sy / vx->u4.rhw,
787 vx->u3.sz / vx->u4.rhw,
789 TRACE(" TLV: %f %f %f (%02lx %02lx %02lx %02lx) (%f %f) (%f)\n",
790 vx->u1.sx, vx->u2.sy, vx->u3.sz,
791 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), ((col >> 24) & 0xFF),
792 vx->u7.tu, vx->u8.tv, vx->u4.rhw);
796 FIXME("Unhandled vertex type\n");
806 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
807 D3DPRIMITIVETYPE d3dptPrimitiveType,
808 D3DVERTEXTYPE d3dvtVertexType,
813 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
814 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
817 draw_primitive((IDirect3DDeviceGLImpl *) This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
824 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
825 D3DPRIMITIVETYPE d3dptPrimitiveType,
826 D3DVERTEXTYPE d3dvtVertexType,
833 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
834 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
837 draw_primitive((IDirect3DDeviceGLImpl *) This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
844 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
845 LPD3DEXECUTEBUFFERDESC lpDesc,
846 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
849 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
850 IDirect3DExecuteBufferImpl *ret;
853 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
855 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
856 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
858 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
863 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
868 if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
869 if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
870 if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
871 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
872 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
873 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
874 default: TRACE(" matrix weighting not handled yet...\n");
876 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
877 elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
879 if (elements) *elements = elts;
884 void dump_flexible_vertex(DWORD d3dvtVertexType)
886 static const flag_info flags[] = {
888 FE(D3DFVF_RESERVED1),
892 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
893 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
894 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
895 GEN_CASE(D3DFVF_XYZ);
896 GEN_CASE(D3DFVF_XYZRHW);
897 GEN_CASE(D3DFVF_XYZB1);
898 GEN_CASE(D3DFVF_XYZB2);
899 GEN_CASE(D3DFVF_XYZB3);
900 GEN_CASE(D3DFVF_XYZB4);
901 GEN_CASE(D3DFVF_XYZB5);
903 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
904 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
905 GEN_CASE(D3DFVF_TEX0);
906 GEN_CASE(D3DFVF_TEX1);
907 GEN_CASE(D3DFVF_TEX2);
908 GEN_CASE(D3DFVF_TEX3);
909 GEN_CASE(D3DFVF_TEX4);
910 GEN_CASE(D3DFVF_TEX5);
911 GEN_CASE(D3DFVF_TEX6);
912 GEN_CASE(D3DFVF_TEX7);
913 GEN_CASE(D3DFVF_TEX8);
919 /* Some types used by the fast paths... */
945 #define GET_COMPONENT(cpnt,i,type) ((type*)(lpD3DDrawPrimStrideData->cpnt.lpvData+i*lpD3DDrawPrimStrideData->cpnt.dwStride))
946 #define GET_POSITION(i) GET_COMPONENT(position,i,VERTEX_COORDS)
947 #define GET_NORMAL(i) GET_COMPONENT(normal,i,NORMAL_COORDS)
948 #define GET_DIFFUSE(i) *GET_COMPONENT(diffuse,i,DWORD)
949 #define GET_SPECULAR(i) *GET_COMPONENT(specular,i,DWORD)
950 #define GET_TEXTURE(i,n) GET_COMPONENT(textureCoords[n],i,TEXTURE_COORDS)
952 /* These are the various handler used in the generic path */
953 inline static void handle_xyz(float *coords) {
956 inline static void handle_xyzrhw(float *coords) {
957 if (coords[3] < 0.00001)
958 glVertex3f(coords[0], coords[1], coords[2]);
960 glVertex4f(coords[0] / coords[3],
961 coords[1] / coords[3],
962 coords[2] / coords[3],
965 inline static void handle_normal(float *coords) {
968 inline static void handle_specular(DWORD color) {
969 /* Specular not handled yet properly... */
971 inline static void handle_diffuse(DWORD color) {
972 glColor4ub((color >> 16) & 0xFF,
975 (color >> 24) & 0xFF);
977 inline static void handle_texture(float *coords, int stage, int single) {
979 /* Special case for single texture... */
980 glTexCoord2fv(coords);
982 /* Multitexturing not handled yet */
986 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
987 D3DPRIMITIVETYPE d3dptPrimitiveType,
988 DWORD d3dvtVertexType,
989 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
995 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
996 if (TRACE_ON(ddraw)) {
997 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
1001 draw_primitive_handle_GL_state(glThis,
1002 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
1003 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
1004 draw_primitive_start_GL(d3dptPrimitiveType);
1006 /* Some fast paths first before the generic case.... */
1007 if (d3dvtVertexType == D3DFVF_VERTEX) {
1010 for (index = 0; index < dwIndexCount; index++) {
1011 int i = (dwIndices == NULL) ? index : dwIndices[index];
1013 glNormal3fv(&GET_NORMAL(i)->nx);
1014 glTexCoord2fv(&GET_TEXTURE(i,0)->u);
1015 glVertex3fv(&GET_POSITION(i)->x);
1016 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
1017 GET_POSITION(i)->x,GET_POSITION(i)->y,GET_POSITION(i)->z,
1018 GET_NORMAL(i)->nx,GET_NORMAL(i)->ny,GET_NORMAL(i)->nz,
1019 GET_TEXTURE(i,0)->u,GET_TEXTURE(i,0)->v);
1021 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
1024 for (index = 0; index < dwIndexCount; index++) {
1025 int i = (dwIndices == NULL) ? index : dwIndices[index];
1027 glColor4ub((GET_DIFFUSE(i) >> 16) & 0xFF,
1028 (GET_DIFFUSE(i) >> 8) & 0xFF,
1029 (GET_DIFFUSE(i) >> 0) & 0xFF,
1030 (GET_DIFFUSE(i) >> 24) & 0xFF);
1031 /* Todo : handle specular... */
1032 glTexCoord2fv(&GET_TEXTURE(i,0)->u);
1033 if (GET_POSITION(i)->rhw < 0.00001)
1034 glVertex3fv(&GET_POSITION(i)->x);
1036 glVertex4f(GET_POSITION(i)->x / GET_POSITION(i)->rhw,
1037 GET_POSITION(i)->y / GET_POSITION(i)->rhw,
1038 GET_POSITION(i)->z / GET_POSITION(i)->rhw,
1039 1.0 / GET_POSITION(i)->rhw);
1041 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1042 GET_POSITION(i)->x,GET_POSITION(i)->y,GET_POSITION(i)->z,GET_POSITION(i)->rhw,
1043 (GET_DIFFUSE(i) >> 16) & 0xFF,
1044 (GET_DIFFUSE(i) >> 8) & 0xFF,
1045 (GET_DIFFUSE(i) >> 0) & 0xFF,
1046 (GET_DIFFUSE(i) >> 24) & 0xFF,
1047 (GET_SPECULAR(i) >> 16) & 0xFF,
1048 (GET_SPECULAR(i) >> 8) & 0xFF,
1049 (GET_SPECULAR(i) >> 0) & 0xFF,
1050 (GET_SPECULAR(i) >> 24) & 0xFF,
1051 GET_TEXTURE(i,0)->u,GET_TEXTURE(i,0)->v);
1053 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1054 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1055 /* This is the 'slow path' but that should support all possible vertex formats out there...
1056 Note that people should write a fast path for all vertex formats out there...
1059 for (index = 0; index < dwIndexCount; index++) {
1060 int i = (dwIndices == NULL) ? index : dwIndices[index];
1061 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1062 handle_xyz(&GET_POSITION(i)->x);
1064 handle_xyzrhw(&GET_POSITION(i)->x);
1066 if (d3dvtVertexType & D3DFVF_NORMAL) {
1067 handle_normal(&GET_NORMAL(i)->nx);
1069 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1070 handle_diffuse(GET_DIFFUSE(i));
1072 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1073 /* Todo : handle specular... */
1075 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1076 /* Special case for single texture... */
1077 handle_texture(&GET_TEXTURE(i,0)->u,0,1);
1080 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1081 /* Multitexturing not handled yet */
1086 ERR(" matrix weighting not handled yet....\n");
1094 static void draw_primitive_7(IDirect3DDeviceImpl *This,
1095 D3DPRIMITIVETYPE d3dptPrimitiveType,
1096 DWORD d3dvtVertexType,
1098 DWORD dwVertexCount,
1103 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1104 int current_offset = 0;
1107 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1108 strided.position.lpvData = lpvVertices;
1109 current_offset += 3 * sizeof(D3DVALUE);
1111 strided.position.lpvData = lpvVertices;
1112 current_offset += 4 * sizeof(D3DVALUE);
1114 if (d3dvtVertexType & D3DFVF_NORMAL) {
1115 strided.normal.lpvData = lpvVertices + current_offset;
1116 current_offset += 3 * sizeof(D3DVALUE);
1118 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1119 strided.diffuse.lpvData = lpvVertices + current_offset;
1120 current_offset += sizeof(DWORD);
1122 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1123 strided.specular.lpvData = lpvVertices + current_offset;
1124 current_offset += sizeof(DWORD);
1126 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1127 strided.textureCoords[tex_index].lpvData = lpvVertices + current_offset;
1128 current_offset += 2*sizeof(D3DVALUE);
1130 strided.position.dwStride = current_offset;
1131 strided.normal.dwStride = current_offset;
1132 strided.diffuse.dwStride = current_offset;
1133 strided.specular.dwStride = current_offset;
1134 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
1135 strided.textureCoords[tex_index].dwStride = current_offset;
1137 draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1141 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1142 D3DPRIMITIVETYPE d3dptPrimitiveType,
1143 DWORD d3dvtVertexType,
1145 DWORD dwVertexCount,
1148 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1149 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1151 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, NULL, dwVertexCount, dwFlags);
1157 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1158 D3DPRIMITIVETYPE d3dptPrimitiveType,
1159 DWORD d3dvtVertexType,
1161 DWORD dwVertexCount,
1166 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1167 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1169 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1175 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1176 D3DPRIMITIVETYPE d3dptPrimitiveType,
1178 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1179 DWORD dwVertexCount,
1182 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1183 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1184 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, NULL, dwVertexCount, dwFlags);
1189 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1190 D3DPRIMITIVETYPE d3dptPrimitiveType,
1192 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1193 DWORD dwVertexCount,
1198 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1199 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1200 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1205 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1207 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1210 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1211 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1214 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1216 if (TRACE_ON(ddraw)) {
1217 TRACE(" Stage type is : ");
1218 switch (d3dTexStageStateType) {
1219 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1220 GEN_CASE(D3DTSS_COLOROP);
1221 GEN_CASE(D3DTSS_COLORARG1);
1222 GEN_CASE(D3DTSS_COLORARG2);
1223 GEN_CASE(D3DTSS_ALPHAOP);
1224 GEN_CASE(D3DTSS_ALPHAARG1);
1225 GEN_CASE(D3DTSS_ALPHAARG2);
1226 GEN_CASE(D3DTSS_BUMPENVMAT00);
1227 GEN_CASE(D3DTSS_BUMPENVMAT01);
1228 GEN_CASE(D3DTSS_BUMPENVMAT10);
1229 GEN_CASE(D3DTSS_BUMPENVMAT11);
1230 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1231 GEN_CASE(D3DTSS_ADDRESS);
1232 GEN_CASE(D3DTSS_ADDRESSU);
1233 GEN_CASE(D3DTSS_ADDRESSV);
1234 GEN_CASE(D3DTSS_BORDERCOLOR);
1235 GEN_CASE(D3DTSS_MAGFILTER);
1236 GEN_CASE(D3DTSS_MINFILTER);
1237 GEN_CASE(D3DTSS_MIPFILTER);
1238 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1239 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1240 GEN_CASE(D3DTSS_MAXANISOTROPY);
1241 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1242 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1243 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1245 default: DPRINTF("UNKNOWN !!!");
1250 switch (d3dTexStageStateType) {
1251 case D3DTSS_MINFILTER:
1252 switch ((D3DTEXTUREMINFILTER) dwState) {
1254 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1255 gl_state = GL_NEAREST;
1258 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1259 gl_state = GL_LINEAR;
1262 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1263 gl_state = GL_LINEAR;
1266 glThis->render_state.min = gl_state;
1267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1270 case D3DTSS_MAGFILTER:
1271 switch ((D3DTEXTUREMAGFILTER) dwState) {
1273 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1274 gl_state = GL_NEAREST;
1277 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1278 gl_state = GL_LINEAR;
1281 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1282 gl_state = GL_LINEAR;
1285 glThis->render_state.mag = gl_state;
1286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1290 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1297 GL_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
1299 LPDIRECT3DTEXTURE2 lpTexture2)
1301 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1303 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1305 if (This->current_texture[dwStage] != NULL) {
1306 /* Seems that this is not right... Need to test in real Windows
1307 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1311 if (lpTexture2 == NULL) {
1312 TRACE(" disabling 2D texturing.\n");
1313 glBindTexture(GL_TEXTURE_2D, 0);
1314 glDisable(GL_TEXTURE_2D);
1316 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpTexture2);
1317 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
1319 This->current_texture[dwStage] = tex_impl;
1320 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7));
1322 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1324 glEnable(GL_TEXTURE_2D);
1325 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1333 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1334 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1336 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1337 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1339 fill_opengl_caps_7(lpD3DHELDevDesc);
1341 TRACE(" returning caps : no dump function yet.\n");
1346 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1347 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1349 # define XCAST(fun) (void*)
1352 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1354 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1355 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1356 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1357 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1358 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1359 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1360 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1361 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1362 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1363 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1364 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1365 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1366 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1367 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1368 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1369 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1370 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1371 XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
1372 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1373 XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
1374 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1375 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1376 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1377 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1378 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1379 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1380 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1381 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1382 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1383 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1384 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1385 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1386 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB,
1387 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
1388 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1389 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
1390 XCAST(SetTexture) Main_IDirect3DDeviceImpl_7_SetTexture,
1391 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1392 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1393 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1394 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1395 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1396 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1397 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1398 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1399 XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
1400 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1401 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1402 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1403 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1406 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1411 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1412 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1414 # define XCAST(fun) (void*)
1417 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1419 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1420 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1421 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1422 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1423 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1424 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1425 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1426 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1427 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1428 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1429 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1430 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1431 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1432 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1433 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1434 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1435 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1436 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1437 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1438 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1439 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1440 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1441 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1442 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1443 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1444 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1445 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1446 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1447 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1448 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1449 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1450 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1451 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1452 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1453 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1454 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1455 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1456 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1457 XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
1458 XCAST(SetTexture) GL_IDirect3DDeviceImpl_3_SetTexture,
1459 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1460 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1461 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1464 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1469 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1470 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1472 # define XCAST(fun) (void*)
1475 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1477 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1478 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1479 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1480 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1481 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1482 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
1483 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1484 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1485 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1486 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1487 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1488 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1489 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1490 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1491 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1492 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1493 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1494 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1495 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1496 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1497 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1498 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1499 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1500 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1501 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1502 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1503 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1504 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1505 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1506 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1507 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1508 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1509 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1510 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1513 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1518 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1519 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1521 # define XCAST(fun) (void*)
1524 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1526 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1527 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1528 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1529 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1530 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1531 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1532 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
1533 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1534 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1535 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1536 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1537 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1538 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1539 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1540 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1541 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1542 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1543 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1544 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1545 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1546 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1547 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1548 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1551 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1555 /* TODO for both these functions :
1556 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1557 by other OpenGL code in D3D
1558 - handle the case where no 'Begin / EndScene' was done between two locks
1559 - handle the rectangles in the unlock too
1560 - handle pitch correctly...
1562 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1564 /* First, check if we need to do anything */
1565 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1572 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1575 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1576 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1577 /* Application wants to lock the front buffer */
1578 glReadBuffer(GL_FRONT);
1579 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1580 /* Application wants to lock the back buffer */
1581 glReadBuffer(GL_BACK);
1583 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1586 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1587 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1589 WARN(" unsupported pixel format.\n");
1593 if (pRect == NULL) {
1596 loc_rect.bottom = This->surface_desc.dwHeight;
1597 loc_rect.right = This->surface_desc.dwWidth;
1601 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1602 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1603 + loc_rect.top * This->surface_desc.u1.lPitch
1604 + loc_rect.left * GET_BPP(This->surface_desc)));
1605 glReadBuffer(prev_read);
1610 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1612 /* First, check if we need to do anything */
1613 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1619 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1621 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1622 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1623 /* Application wants to lock the front buffer */
1624 glDrawBuffer(GL_FRONT);
1625 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1626 /* Application wants to lock the back buffer */
1627 glDrawBuffer(GL_BACK);
1629 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
1632 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1633 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1635 WARN(" unsupported pixel format.\n");
1639 glRasterPos2f(0.0, 0.0);
1640 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
1641 GL_RGB, buffer_type, This->surface_desc.lpSurface);
1642 glDrawBuffer(prev_draw);
1649 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
1651 IDirect3DDeviceImpl *object;
1652 IDirect3DDeviceGLImpl *gl_object;
1653 IDirectDrawSurfaceImpl *surf;
1657 XVisualInfo template;
1660 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1661 if (object == NULL) return DDERR_OUTOFMEMORY;
1663 gl_object = (IDirect3DDeviceGLImpl *) object;
1667 object->surface = surface;
1668 object->set_context = set_context;
1670 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1672 device_context = GetDC(surface->ddraw_owner->window);
1673 gl_object->display = get_display(device_context);
1674 gl_object->drawable = get_drawable(device_context);
1675 ReleaseDC(surface->ddraw_owner->window,device_context);
1678 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1679 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
1681 HeapFree(GetProcessHeap(), 0, object);
1682 ERR("No visual found !\n");
1684 return DDERR_INVALIDPARAMS;
1686 TRACE(" visual found\n");
1689 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
1692 if (gl_object->gl_context == NULL) {
1693 HeapFree(GetProcessHeap(), 0, object);
1694 ERR("Error in context creation !\n");
1696 return DDERR_INVALIDPARAMS;
1698 TRACE(" context created (%p)\n", gl_object->gl_context);
1701 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
1702 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
1703 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
1704 surf->aux_ctx = (LPVOID) gl_object->display;
1705 surf->aux_data = (LPVOID) gl_object->drawable;
1706 surf->aux_flip = opengl_flip;
1711 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
1713 TRACE(" no double buffering : drawing on the front buffer\n");
1717 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
1718 for (; surf != NULL; surf = surf->next_attached) {
1719 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
1720 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
1721 /* Override the Lock / Unlock function for all these surfaces */
1722 surf->lock_update = d3ddevice_lock_update;
1723 surf->unlock_update = d3ddevice_unlock_update;
1725 surf->d3ddevice = object;
1728 gl_object->render_state.src = GL_ONE;
1729 gl_object->render_state.dst = GL_ZERO;
1730 gl_object->render_state.mag = GL_NEAREST;
1731 gl_object->render_state.min = GL_NEAREST;
1732 gl_object->render_state.alpha_ref = 0.0; /* No actual idea about the real default value... */
1733 gl_object->render_state.alpha_func = GL_ALWAYS; /* Here either but it seems logical */
1735 /* Allocate memory for the matrices */
1736 gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1737 gl_object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1738 gl_object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1740 memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float));
1741 memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float));
1742 memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float));
1744 /* Initialisation */
1745 TRACE(" setting current context\n");
1747 object->set_context(object);
1749 TRACE(" current context set\n");
1750 glClearColor(0.0, 0.0, 0.0, 0.0);
1751 glColor3f(1.0, 1.0, 1.0);
1752 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1753 glDrawBuffer(buffer);
1754 glReadBuffer(buffer);
1755 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
1758 /* fill_device_capabilities(d3d->ddraw); */
1760 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
1761 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
1762 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
1763 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
1767 TRACE(" creating implementation at %p.\n", *obj);