- added enumeration of the Reference device (some games seems to need
[wine/wine-kai.git] / dlls / ddraw / d3ddevice / mesa.c
blobef70ed8ba2f4a2373222b05574df16fc2cbd2a83
1 /* Direct3D Device
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the MESA implementation of all the D3D devices that
5 * Wine supports.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
24 #include <string.h>
26 #include "windef.h"
27 #include "winerror.h"
28 #include "objbase.h"
29 #include "ddraw.h"
30 #include "d3d.h"
31 #include "wine/debug.h"
33 #include "mesa_private.h"
34 #include "main.h"
36 #include "x11drv.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
40 /* They are non-static as they are used by Direct3D in the creation function */
41 const GUID IID_D3DDEVICE_OpenGL = {
42 0x31416d44,
43 0x86ae,
44 0x11d2,
45 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
48 #ifndef HAVE_GLEXT_PROTOTYPES
49 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
50 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
51 GLsizei width, GLenum format, GLenum type,
52 const GLvoid *table);
53 #endif
55 static const float id_mat[16] = {
56 1.0, 0.0, 0.0, 0.0,
57 0.0, 1.0, 0.0, 0.0,
58 0.0, 0.0, 1.0, 0.0,
59 0.0, 0.0, 0.0, 1.0
62 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
63 D3DPRIMITIVETYPE d3dptPrimitiveType,
64 DWORD d3dvtVertexType,
65 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
66 DWORD dwStartVertex,
67 DWORD dwVertexCount,
68 LPWORD dwIndices,
69 DWORD dwIndexCount,
70 DWORD dwFlags) ;
72 /* retrieve the X display to use on a given DC */
73 inline static Display *get_display( HDC hdc )
75 Display *display;
76 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
78 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
79 sizeof(display), (LPSTR)&display )) display = NULL;
81 return display;
85 /* retrieve the X drawable to use on a given DC */
86 inline static Drawable get_drawable( HDC hdc )
88 Drawable drawable;
89 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
91 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
92 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
94 return drawable;
98 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
100 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
101 ENTER_GL();
102 glXSwapBuffers((Display*)display,(Drawable)drawable);
103 LEAVE_GL();
104 return TRUE;
108 /*******************************************************************************
109 * OpenGL static functions
111 static void set_context(IDirect3DDeviceImpl* This)
113 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
115 ENTER_GL();
116 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
117 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
118 ERR("Error in setting current context (context %p drawable %ld)!\n",
119 glThis->gl_context, glThis->drawable);
121 LEAVE_GL();
124 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
126 pc->dwSize = sizeof(*pc);
127 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
128 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
129 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
130 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
131 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
132 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
133 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
134 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
135 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
136 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
137 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
138 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
139 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
140 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
141 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
142 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
143 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
144 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
145 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
146 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
147 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
148 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
149 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
150 pc->dwStippleWidth = 32;
151 pc->dwStippleHeight = 32;
154 static void fill_opengl_caps(D3DDEVICEDESC *d1)
156 /* GLint maxlight; */
158 d1->dwSize = sizeof(*d1);
159 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
160 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
161 d1->dcmColorModel = D3DCOLOR_RGB;
162 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
163 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
164 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
165 /* D3D 7 capabilities */
166 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
167 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
168 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
169 d1->bClipping = TRUE;
170 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
171 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
172 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
173 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
174 fill_opengl_primcaps(&(d1->dpcLineCaps));
175 fill_opengl_primcaps(&(d1->dpcTriCaps));
176 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
177 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
178 d1->dwMaxBufferSize = 0;
179 d1->dwMaxVertexCount = 65536;
180 d1->dwMinTextureWidth = 1;
181 d1->dwMinTextureHeight = 1;
182 d1->dwMaxTextureWidth = 1024;
183 d1->dwMaxTextureHeight = 1024;
184 d1->dwMinStippleWidth = 1;
185 d1->dwMinStippleHeight = 1;
186 d1->dwMaxStippleWidth = 32;
187 d1->dwMaxStippleHeight = 32;
188 d1->dwMaxTextureRepeat = 16;
189 d1->dwMaxTextureAspectRatio = 1024;
190 d1->dwMaxAnisotropy = 0;
191 d1->dvGuardBandLeft = 0.0;
192 d1->dvGuardBandRight = 0.0;
193 d1->dvGuardBandTop = 0.0;
194 d1->dvGuardBandBottom = 0.0;
195 d1->dvExtentsAdjust = 0.0;
196 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
197 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
198 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
199 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
200 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
201 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
204 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
206 D3DDEVICEDESC d1;
208 /* Copy first D3D1/2/3 capabilities */
209 fill_opengl_caps(&d1);
211 /* And fill the D3D7 one with it */
212 d->dwDevCaps = d1.dwDevCaps;
213 d->dpcLineCaps = d1.dpcLineCaps;
214 d->dpcTriCaps = d1.dpcTriCaps;
215 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
216 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
217 d->dwMinTextureWidth = d1.dwMinTextureWidth;
218 d->dwMinTextureHeight = d1.dwMinTextureHeight;
219 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
220 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
221 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
222 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
223 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
224 d->dvGuardBandLeft = d1.dvGuardBandLeft;
225 d->dvGuardBandTop = d1.dvGuardBandTop;
226 d->dvGuardBandRight = d1.dvGuardBandRight;
227 d->dvGuardBandBottom = d1.dvGuardBandBottom;
228 d->dvExtentsAdjust = d1.dvExtentsAdjust;
229 d->dwStencilCaps = d1.dwStencilCaps;
230 d->dwFVFCaps = d1.dwFVFCaps;
231 d->dwTextureOpCaps = d1.dwTextureOpCaps;
232 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
233 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
234 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
235 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
236 d->deviceGUID = IID_IDirect3DTnLHalDevice;
237 d->wMaxUserClipPlanes = 1;
238 d->wMaxVertexBlendMatrices = 0;
239 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
240 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
241 d->dwReserved1 = 0;
242 d->dwReserved2 = 0;
243 d->dwReserved3 = 0;
244 d->dwReserved4 = 0;
247 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
248 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
250 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
251 const char *ext_string;
252 Mesa_DeviceCapabilities *devcap;
254 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
255 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
257 ENTER_GL();
258 ext_string = glGetString(GL_EXTENSIONS);
259 /* Query for the ColorTable Extension */
260 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
261 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
262 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
263 } else {
264 TRACE("Color table extension not found.\n");
266 LEAVE_GL();
268 #endif
272 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
274 D3DDEVICEDESC d1, d2;
275 HRESULT ret_value;
277 fill_opengl_caps(&d1);
278 d2 = d1;
280 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
281 ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
282 if (ret_value != D3DENUMRET_OK)
283 return ret_value;
285 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
286 ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
287 if (ret_value != D3DENUMRET_OK)
288 return ret_value;
290 return D3DENUMRET_OK;
293 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
295 D3DDEVICEDESC7 ddesc;
297 fill_opengl_caps_7(&ddesc);
299 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
301 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
304 ULONG WINAPI
305 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
307 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
308 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
310 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
311 if (!--(This->ref)) {
312 /* Release texture associated with the device */
313 if (This->current_texture[0] != NULL)
314 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
316 /* And warn the D3D object that this device is no longer active... */
317 This->d3d->removed_device(This->d3d, This);
319 HeapFree(GetProcessHeap(), 0, This->world_mat);
320 HeapFree(GetProcessHeap(), 0, This->view_mat);
321 HeapFree(GetProcessHeap(), 0, This->proj_mat);
323 ENTER_GL();
324 glXDestroyContext(glThis->display, glThis->gl_context);
325 LEAVE_GL();
327 HeapFree(GetProcessHeap(), 0, This);
328 return 0;
330 return This->ref;
333 HRESULT WINAPI
334 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
335 LPD3DDEVICEDESC lpD3DHWDevDesc,
336 LPD3DDEVICEDESC lpD3DHELDevDesc)
338 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
339 D3DDEVICEDESC desc;
340 DWORD dwSize;
342 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
344 fill_opengl_caps(&desc);
345 dwSize = lpD3DHWDevDesc->dwSize;
346 memset(lpD3DHWDevDesc, 0, dwSize);
347 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
349 dwSize = lpD3DHELDevDesc->dwSize;
350 memset(lpD3DHELDevDesc, 0, dwSize);
351 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
353 TRACE(" returning caps : (no dump function yet)\n");
355 return DD_OK;
358 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
359 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
360 LPVOID context)
362 DDSURFACEDESC sdesc;
363 LPDDPIXELFORMAT pformat;
365 /* Do the texture enumeration */
366 sdesc.dwSize = sizeof(DDSURFACEDESC);
367 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
368 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
369 pformat = &(sdesc.ddpfPixelFormat);
370 pformat->dwSize = sizeof(DDPIXELFORMAT);
371 pformat->dwFourCC = 0;
373 TRACE("Enumerating GL_RGBA unpacked (32)\n");
374 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
375 pformat->u1.dwRGBBitCount = 32;
376 pformat->u2.dwRBitMask = 0xFF000000;
377 pformat->u3.dwGBitMask = 0x00FF0000;
378 pformat->u4.dwBBitMask = 0x0000FF00;
379 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
380 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
381 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
383 TRACE("Enumerating GL_RGB unpacked (24)\n");
384 pformat->dwFlags = DDPF_RGB;
385 pformat->u1.dwRGBBitCount = 24;
386 pformat->u2.dwRBitMask = 0x00FF0000;
387 pformat->u3.dwGBitMask = 0x0000FF00;
388 pformat->u4.dwBBitMask = 0x000000FF;
389 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
390 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
391 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
393 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
394 pformat->dwFlags = DDPF_RGB;
395 pformat->u1.dwRGBBitCount = 16;
396 pformat->u2.dwRBitMask = 0x0000F800;
397 pformat->u3.dwGBitMask = 0x000007E0;
398 pformat->u4.dwBBitMask = 0x0000001F;
399 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
400 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
401 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
403 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
404 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
405 pformat->u1.dwRGBBitCount = 16;
406 pformat->u2.dwRBitMask = 0x0000F800;
407 pformat->u3.dwGBitMask = 0x000007C0;
408 pformat->u4.dwBBitMask = 0x0000003E;
409 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
410 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
411 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
413 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
414 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
415 pformat->u1.dwRGBBitCount = 16;
416 pformat->u2.dwRBitMask = 0x0000F000;
417 pformat->u3.dwGBitMask = 0x00000F00;
418 pformat->u4.dwBBitMask = 0x000000F0;
419 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
420 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
421 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
423 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (16)\n");
424 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
425 pformat->u1.dwRGBBitCount = 16;
426 pformat->u2.dwRBitMask = 0x00007C00;
427 pformat->u3.dwGBitMask = 0x000003E0;
428 pformat->u4.dwBBitMask = 0x0000001F;
429 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
430 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
431 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
433 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
434 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
435 pformat->u1.dwRGBBitCount = 16;
436 pformat->u2.dwRBitMask = 0x00000F00;
437 pformat->u3.dwGBitMask = 0x000000F0;
438 pformat->u4.dwBBitMask = 0x0000000F;
439 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
440 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
441 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
443 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
444 pformat->dwFlags = DDPF_RGB;
445 pformat->u1.dwRGBBitCount = 8;
446 pformat->u2.dwRBitMask = 0x000000E0;
447 pformat->u3.dwGBitMask = 0x0000001C;
448 pformat->u4.dwBBitMask = 0x00000003;
449 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
450 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
451 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
453 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
454 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
455 pformat->u1.dwRGBBitCount = 16;
456 pformat->u2.dwRBitMask = 0x00007C00;
457 pformat->u3.dwGBitMask = 0x000003E0;
458 pformat->u4.dwBBitMask = 0x0000001F;
459 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
460 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
461 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
463 TRACE("Enumerating Paletted (8)\n");
464 pformat->dwFlags = DDPF_PALETTEINDEXED8;
465 pformat->u1.dwRGBBitCount = 8;
466 pformat->u2.dwRBitMask = 0x00000000;
467 pformat->u3.dwGBitMask = 0x00000000;
468 pformat->u4.dwBBitMask = 0x00000000;
469 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
470 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
471 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
473 TRACE("End of enumeration\n");
474 return DD_OK;
478 HRESULT
479 d3ddevice_find(IDirect3DImpl *d3d,
480 LPD3DFINDDEVICESEARCH lpD3DDFS,
481 LPD3DFINDDEVICERESULT lplpD3DDevice)
483 D3DDEVICEDESC desc;
485 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
486 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
487 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
488 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
490 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
491 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
492 if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
493 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0) &&
494 (IsEqualGUID(&IID_IDirect3DRefDevice, &(lpD3DDFS->guid)) == 0)) {
495 TRACE(" no match for this GUID.\n");
496 return DDERR_INVALIDPARAMS;
500 /* Now return our own GUID */
501 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
502 fill_opengl_caps(&desc);
503 lplpD3DDevice->ddHwDesc = desc;
504 lplpD3DDevice->ddSwDesc = desc;
506 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
508 return D3D_OK;
511 HRESULT WINAPI
512 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
513 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
514 LPVOID lpArg)
516 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
517 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
518 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
521 HRESULT WINAPI
522 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
523 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
524 LPVOID lpArg)
526 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
527 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
528 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
531 HRESULT WINAPI
532 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
533 D3DRENDERSTATETYPE dwRenderStateType,
534 DWORD dwRenderState)
536 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
537 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
538 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
540 /* Call the render state functions */
541 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
543 return DD_OK;
546 HRESULT WINAPI
547 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
548 D3DLIGHTSTATETYPE dwLightStateType,
549 DWORD dwLightState)
551 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
552 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
554 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
556 switch (dwLightStateType) {
557 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
558 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
560 if (mat != NULL) {
561 ENTER_GL();
562 mat->activate(mat);
563 LEAVE_GL();
564 } else {
565 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
567 } break;
569 case D3DLIGHTSTATE_AMBIENT: /* 2 */
570 /* Call the render_state function... */
571 set_render_state(D3DRENDERSTATE_AMBIENT, dwLightState, &(glThis->render_state));
572 break;
574 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
575 UNSUP(COLORMODEL);
576 UNSUP(FOGMODE);
577 UNSUP(FOGSTART);
578 UNSUP(FOGEND);
579 UNSUP(FOGDENSITY);
580 UNSUP(COLORVERTEX);
581 #undef UNSUP
583 default:
584 TRACE("Unexpected Light State Type\n");
585 return DDERR_INVALIDPARAMS;
588 return DD_OK;
591 HRESULT WINAPI
592 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
593 D3DTRANSFORMSTATETYPE dtstTransformStateType,
594 LPD3DMATRIX lpD3DMatrix)
596 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
597 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
599 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
601 ENTER_GL();
603 /* Using a trial and failure approach, I found that the order of
604 Direct3D transformations that works best is :
606 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
608 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
609 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
611 If anyone has a good explanation of the three different matrices in
612 the SDK online documentation, feel free to point it to me. For example,
613 which matrices transform lights ? In OpenGL only the PROJECTION matrix
614 transform the lights, not the MODELVIEW. Using the matrix names, I
615 supposed that PROJECTION and VIEW (all 'camera' related names) do
616 transform lights, but WORLD do not. It may be wrong though... */
618 /* After reading through both OpenGL and Direct3D documentations, I
619 thought that D3D matrices were written in 'line major mode' transposed
620 from OpenGL's 'column major mode'. But I found out that a simple memcpy
621 works fine to transfer one matrix format to the other (it did not work
622 when transposing)....
624 So :
625 1) are the documentations wrong
626 2) does the matrix work even if they are not read correctly
627 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
628 loading using glLoadMatrix ?
630 Anyway, I always use 'conv_mat' to transfer the matrices from one format
631 to the other so that if I ever find out that I need to transpose them, I
632 will able to do it quickly, only by changing the macro conv_mat. */
634 switch (dtstTransformStateType) {
635 case D3DTRANSFORMSTATE_WORLD: {
636 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
637 conv_mat(lpD3DMatrix, This->world_mat);
638 if (glThis->last_vertices_transformed == FALSE) {
639 glMatrixMode(GL_MODELVIEW);
640 glLoadMatrixf((float *) This->view_mat);
641 glMultMatrixf((float *) This->world_mat);
643 } break;
645 case D3DTRANSFORMSTATE_VIEW: {
646 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
647 conv_mat(lpD3DMatrix, This->view_mat);
648 if (glThis->last_vertices_transformed == FALSE) {
649 glMatrixMode(GL_MODELVIEW);
650 glLoadMatrixf((float *) This->view_mat);
651 glMultMatrixf((float *) This->world_mat);
653 } break;
655 case D3DTRANSFORMSTATE_PROJECTION: {
656 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
657 conv_mat(lpD3DMatrix, This->proj_mat);
658 if (glThis->last_vertices_transformed == FALSE) {
659 glMatrixMode(GL_PROJECTION);
660 glLoadMatrixf((float *) This->proj_mat);
662 } break;
664 default:
665 ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
666 break;
668 LEAVE_GL();
670 return DD_OK;
673 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
675 switch (d3dpt) {
676 case D3DPT_POINTLIST:
677 TRACE("Start POINTS\n");
678 glBegin(GL_POINTS);
679 break;
681 case D3DPT_LINELIST:
682 TRACE("Start LINES\n");
683 glBegin(GL_LINES);
684 break;
686 case D3DPT_LINESTRIP:
687 TRACE("Start LINE_STRIP\n");
688 glBegin(GL_LINE_STRIP);
689 break;
691 case D3DPT_TRIANGLELIST:
692 TRACE("Start TRIANGLES\n");
693 glBegin(GL_TRIANGLES);
694 break;
696 case D3DPT_TRIANGLESTRIP:
697 TRACE("Start TRIANGLE_STRIP\n");
698 glBegin(GL_TRIANGLE_STRIP);
699 break;
701 case D3DPT_TRIANGLEFAN:
702 TRACE("Start TRIANGLE_FAN\n");
703 glBegin(GL_TRIANGLE_FAN);
704 break;
706 default:
707 TRACE("Unhandled primitive\n");
708 break;
712 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
713 BOOLEAN vertex_transformed,
714 BOOLEAN vertex_lit) {
715 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
717 /* Puts GL in the correct lighting / transformation mode */
718 if ((vertex_transformed == FALSE) &&
719 (glThis->last_vertices_transformed == TRUE)) {
720 /* Need to put the correct transformation again if we go from Transformed
721 vertices to non-transformed ones.
723 glMatrixMode(GL_MODELVIEW);
724 glLoadMatrixf((float *) This->view_mat);
725 glMultMatrixf((float *) This->world_mat);
726 glMatrixMode(GL_PROJECTION);
727 glLoadMatrixf((float *) This->proj_mat);
729 if (glThis->render_state.fog_on == TRUE) glEnable(GL_FOG);
730 } else if ((vertex_transformed == TRUE) &&
731 (glThis->last_vertices_transformed == FALSE)) {
732 GLfloat height, width;
733 GLfloat trans_mat[16];
735 width = glThis->parent.surface->surface_desc.dwWidth;
736 height = glThis->parent.surface->surface_desc.dwHeight;
738 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
739 to OpenGL screen coordinates (ie the upper left corner is not the same).
740 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
741 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
742 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
743 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
744 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
745 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
747 glMatrixMode(GL_MODELVIEW);
748 glLoadIdentity();
749 glMatrixMode(GL_PROJECTION);
750 glLoadMatrixf(trans_mat);
752 /* Remove also fogging... */
753 glDisable(GL_FOG);
756 /* Handle the 'no-normal' case */
757 if (vertex_lit == FALSE)
758 glDisable(GL_LIGHTING);
759 else if (glThis->render_state.lighting_enable == TRUE)
760 glEnable(GL_LIGHTING);
762 /* Handle the code for pre-vertex material properties */
763 if (vertex_transformed == FALSE) {
764 if (glThis->render_state.lighting_enable == TRUE) {
765 if ((glThis->render_state.color_diffuse != D3DMCS_MATERIAL) ||
766 (glThis->render_state.color_specular != D3DMCS_MATERIAL) ||
767 (glThis->render_state.color_ambient != D3DMCS_MATERIAL) ||
768 (glThis->render_state.color_emissive != D3DMCS_MATERIAL)) {
769 glEnable(GL_COLOR_MATERIAL);
774 /* And save the current state */
775 glThis->last_vertices_transformed = vertex_transformed;
779 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
780 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
782 D3DDRAWPRIMITIVESTRIDEDDATA strided;
784 switch (d3dvt) {
785 case D3DVT_VERTEX: {
786 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
787 strided.position.dwStride = sizeof(D3DVERTEX);
788 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
789 strided.normal.dwStride = sizeof(D3DVERTEX);
790 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
791 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
792 draw_primitive_strided_7(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
793 } break;
795 case D3DVT_LVERTEX: {
796 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
797 strided.position.dwStride = sizeof(D3DLVERTEX);
798 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
799 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
800 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
801 strided.specular.dwStride = sizeof(D3DLVERTEX);
802 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
803 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
804 draw_primitive_strided_7(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
805 } break;
807 case D3DVT_TLVERTEX: {
808 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
809 strided.position.dwStride = sizeof(D3DTLVERTEX);
810 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
811 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
812 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
813 strided.specular.dwStride = sizeof(D3DTLVERTEX);
814 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
815 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
816 draw_primitive_strided_7(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
817 } break;
819 default:
820 FIXME("Unhandled vertex type\n");
821 break;
825 HRESULT WINAPI
826 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
827 D3DPRIMITIVETYPE d3dptPrimitiveType,
828 D3DVERTEXTYPE d3dvtVertexType,
829 LPVOID lpvVertices,
830 DWORD dwVertexCount,
831 DWORD dwFlags)
833 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
834 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
836 ENTER_GL();
837 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
838 LEAVE_GL();
840 return DD_OK;
843 HRESULT WINAPI
844 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
845 D3DPRIMITIVETYPE d3dptPrimitiveType,
846 D3DVERTEXTYPE d3dvtVertexType,
847 LPVOID lpvVertices,
848 DWORD dwVertexCount,
849 LPWORD dwIndices,
850 DWORD dwIndexCount,
851 DWORD dwFlags)
853 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
854 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
856 ENTER_GL();
857 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
858 LEAVE_GL();
860 return DD_OK;
863 HRESULT WINAPI
864 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
865 LPD3DEXECUTEBUFFERDESC lpDesc,
866 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
867 IUnknown* pUnkOuter)
869 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
870 IDirect3DExecuteBufferImpl *ret;
871 HRESULT ret_value;
873 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
875 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
876 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
878 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
880 return ret_value;
883 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
885 DWORD size = 0;
886 DWORD elts = 0;
888 if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
889 if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
890 if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
891 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
892 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
893 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
894 default: TRACE(" matrix weighting not handled yet...\n");
896 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
897 elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
899 if (elements) *elements = elts;
901 return size;
904 void dump_flexible_vertex(DWORD d3dvtVertexType)
906 static const flag_info flags[] = {
907 FE(D3DFVF_NORMAL),
908 FE(D3DFVF_RESERVED1),
909 FE(D3DFVF_DIFFUSE),
910 FE(D3DFVF_SPECULAR)
912 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
913 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
914 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
915 GEN_CASE(D3DFVF_XYZ);
916 GEN_CASE(D3DFVF_XYZRHW);
917 GEN_CASE(D3DFVF_XYZB1);
918 GEN_CASE(D3DFVF_XYZB2);
919 GEN_CASE(D3DFVF_XYZB3);
920 GEN_CASE(D3DFVF_XYZB4);
921 GEN_CASE(D3DFVF_XYZB5);
923 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
924 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
925 GEN_CASE(D3DFVF_TEX0);
926 GEN_CASE(D3DFVF_TEX1);
927 GEN_CASE(D3DFVF_TEX2);
928 GEN_CASE(D3DFVF_TEX3);
929 GEN_CASE(D3DFVF_TEX4);
930 GEN_CASE(D3DFVF_TEX5);
931 GEN_CASE(D3DFVF_TEX6);
932 GEN_CASE(D3DFVF_TEX7);
933 GEN_CASE(D3DFVF_TEX8);
935 #undef GEN_CASE
936 DPRINTF("\n");
939 /* These are the various handler used in the generic path */
940 inline static void handle_xyz(D3DVALUE *coords) {
941 glVertex3fv(coords);
943 inline static void handle_xyzrhw(D3DVALUE *coords) {
944 if (coords[3] < 1e-8)
945 glVertex3fv(coords);
946 else {
947 GLfloat w = 1.0 / coords[3];
949 glVertex4f(coords[0] * w,
950 coords[1] * w,
951 coords[2] * w,
955 inline static void handle_normal(D3DVALUE *coords) {
956 glNormal3fv(coords);
959 inline static void handle_diffuse_base(RenderState *rs, DWORD *color) {
960 if (rs->alpha_blend_enable == TRUE) {
961 glColor4ub((*color >> 16) & 0xFF,
962 (*color >> 8) & 0xFF,
963 (*color >> 0) & 0xFF,
964 (*color >> 24) & 0xFF);
965 } else {
966 glColor3ub((*color >> 16) & 0xFF,
967 (*color >> 8) & 0xFF,
968 (*color >> 0) & 0xFF);
972 inline static void handle_specular_base(RenderState *rs, DWORD *color) {
973 glColor4ub((*color >> 16) & 0xFF,
974 (*color >> 8) & 0xFF,
975 (*color >> 0) & 0xFF,
976 (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
979 inline static void handle_diffuse(RenderState *rs, DWORD *color) {
980 if (rs->lighting_enable == TRUE) {
981 if (rs->color_diffuse == D3DMCS_COLOR1) {
982 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
983 handle_diffuse_base(rs, color);
985 if (rs->color_ambient == D3DMCS_COLOR1) {
986 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
987 handle_diffuse_base(rs, color);
989 if ((rs->color_specular == D3DMCS_COLOR1) && (rs->specular_enable == TRUE)) {
990 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
991 handle_diffuse_base(rs, color);
993 if (rs->color_emissive == D3DMCS_COLOR1) {
994 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
995 handle_diffuse_base(rs, color);
997 } else {
998 handle_diffuse_base(rs, color);
1002 inline static void handle_specular(RenderState *rs, DWORD *color) {
1003 if (rs->lighting_enable == TRUE) {
1004 if (rs->color_diffuse == D3DMCS_COLOR2) {
1005 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
1006 handle_specular(rs, color);
1008 if (rs->color_ambient == D3DMCS_COLOR2) {
1009 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
1010 handle_specular(rs, color);
1012 if ((rs->color_specular == D3DMCS_COLOR2) && (rs->specular_enable == TRUE)) {
1013 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
1014 handle_specular(rs, color);
1016 if (rs->color_emissive == D3DMCS_COLOR2) {
1017 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
1018 handle_specular(rs, color);
1021 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
1024 inline static void handle_diffuse_and_specular(RenderState *rs, DWORD *color_d, DWORD *color_s, BOOLEAN transformed) {
1025 if (transformed == TRUE) {
1026 if (rs->fog_on == TRUE) {
1027 /* Special case where the specular value is used to do fogging. TODO */
1029 if (rs->specular_enable == TRUE) {
1030 /* Standard specular value in transformed mode. TODO */
1032 handle_diffuse_base(rs, color_d);
1033 } else {
1034 if (rs->lighting_enable == TRUE) {
1035 handle_diffuse(rs, color_d);
1036 handle_specular(rs, color_s);
1037 } else {
1038 /* In that case, only put the diffuse color... */
1039 handle_diffuse_base(rs, color_d);
1044 inline static void handle_texture(D3DVALUE *coords) {
1045 glTexCoord2fv(coords);
1047 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
1048 /* For the moment, draw only the first texture.. */
1049 if (tex_index == 0) glTexCoord2fv(coords);
1052 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
1053 D3DPRIMITIVETYPE d3dptPrimitiveType,
1054 DWORD d3dvtVertexType,
1055 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1056 DWORD dwStartVertex,
1057 DWORD dwVertexCount,
1058 LPWORD dwIndices,
1059 DWORD dwIndexCount,
1060 DWORD dwFlags)
1062 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
1063 if (TRACE_ON(ddraw)) {
1064 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
1067 ENTER_GL();
1068 draw_primitive_handle_GL_state(This,
1069 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
1070 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
1071 draw_primitive_start_GL(d3dptPrimitiveType);
1073 /* Some fast paths first before the generic case.... */
1074 if (d3dvtVertexType == D3DFVF_VERTEX) {
1075 int index;
1077 for (index = 0; index < dwIndexCount; index++) {
1078 int i = (dwIndices == NULL) ? index : dwIndices[index];
1079 D3DVALUE *normal =
1080 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1081 D3DVALUE *tex_coord =
1082 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1083 D3DVALUE *position =
1084 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1086 handle_normal(normal);
1087 handle_texture(tex_coord);
1088 handle_xyz(position);
1090 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
1091 position[0], position[1], position[2],
1092 normal[0], normal[1], normal[2],
1093 tex_coord[0], tex_coord[1]);
1095 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
1096 int index;
1098 for (index = 0; index < dwIndexCount; index++) {
1099 int i = (dwIndices == NULL) ? index : dwIndices[index];
1100 DWORD *color_d =
1101 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1102 DWORD *color_s =
1103 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1104 D3DVALUE *tex_coord =
1105 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1106 D3DVALUE *position =
1107 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1109 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, TRUE);
1110 handle_texture(tex_coord);
1111 handle_xyzrhw(position);
1113 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1114 position[0], position[1], position[2], position[3],
1115 (*color_d >> 16) & 0xFF,
1116 (*color_d >> 8) & 0xFF,
1117 (*color_d >> 0) & 0xFF,
1118 (*color_d >> 24) & 0xFF,
1119 (*color_s >> 16) & 0xFF,
1120 (*color_s >> 8) & 0xFF,
1121 (*color_s >> 0) & 0xFF,
1122 (*color_s >> 24) & 0xFF,
1123 tex_coord[0], tex_coord[1]);
1125 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1126 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1127 /* This is the 'slow path' but that should support all possible vertex formats out there...
1128 Note that people should write a fast path for all vertex formats out there...
1130 int index;
1131 for (index = 0; index < dwIndexCount; index++) {
1132 int i = (dwIndices == NULL) ? index : dwIndices[index];
1134 if (d3dvtVertexType & D3DFVF_NORMAL) {
1135 D3DVALUE *normal =
1136 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1137 handle_normal(normal);
1139 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1140 DWORD *color_d =
1141 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1142 DWORD *color_s =
1143 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1144 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, (d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW);
1145 } else {
1146 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1147 DWORD *color_s =
1148 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1149 handle_specular(&(glThis->render_state), color_s);
1150 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1151 DWORD *color_d =
1152 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1153 handle_diffuse(&(glThis->render_state), color_d);
1157 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1158 /* Special case for single texture... */
1159 D3DVALUE *tex_coord =
1160 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1161 handle_texture(tex_coord);
1162 } else {
1163 int tex_index;
1164 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1165 D3DVALUE *tex_coord =
1166 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1167 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1168 handle_textures(tex_coord, tex_index);
1171 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1172 D3DVALUE *position =
1173 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1174 handle_xyz(position);
1175 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1176 D3DVALUE *position =
1177 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1178 handle_xyzrhw(position);
1181 if (TRACE_ON(ddraw)) {
1182 int tex_index;
1184 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1185 D3DVALUE *position =
1186 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1187 TRACE(" %f %f %f", position[0], position[1], position[2]);
1188 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1189 D3DVALUE *position =
1190 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1191 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1193 if (d3dvtVertexType & D3DFVF_NORMAL) {
1194 D3DVALUE *normal =
1195 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1196 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1198 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1199 DWORD *color_d =
1200 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1201 DPRINTF(" / %02lx %02lx %02lx %02lx",
1202 (*color_d >> 16) & 0xFF,
1203 (*color_d >> 8) & 0xFF,
1204 (*color_d >> 0) & 0xFF,
1205 (*color_d >> 24) & 0xFF);
1207 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1208 DWORD *color_s =
1209 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1210 DPRINTF(" / %02lx %02lx %02lx %02lx",
1211 (*color_s >> 16) & 0xFF,
1212 (*color_s >> 8) & 0xFF,
1213 (*color_s >> 0) & 0xFF,
1214 (*color_s >> 24) & 0xFF);
1216 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1217 D3DVALUE *tex_coord =
1218 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1219 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1220 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1222 DPRINTF("\n");
1225 } else {
1226 ERR(" matrix weighting not handled yet....\n");
1229 glEnd();
1231 /* Whatever the case, disable the color material stuff */
1232 glDisable(GL_COLOR_MATERIAL);
1234 LEAVE_GL();
1235 TRACE("End\n");
1238 static void draw_primitive_7(IDirect3DDeviceImpl *This,
1239 D3DPRIMITIVETYPE d3dptPrimitiveType,
1240 DWORD d3dvtVertexType,
1241 LPVOID lpvVertices,
1242 DWORD dwStartVertex,
1243 DWORD dwVertexCount,
1244 LPWORD dwIndices,
1245 DWORD dwIndexCount,
1246 DWORD dwFlags)
1248 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1249 int current_offset = 0;
1250 int tex_index;
1252 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1253 strided.position.lpvData = lpvVertices;
1254 current_offset += 3 * sizeof(D3DVALUE);
1255 } else {
1256 strided.position.lpvData = lpvVertices;
1257 current_offset += 4 * sizeof(D3DVALUE);
1259 if (d3dvtVertexType & D3DFVF_NORMAL) {
1260 strided.normal.lpvData = ((char *) lpvVertices) + current_offset;
1261 current_offset += 3 * sizeof(D3DVALUE);
1263 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1264 strided.diffuse.lpvData = ((char *) lpvVertices) + current_offset;
1265 current_offset += sizeof(DWORD);
1267 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1268 strided.specular.lpvData = ((char *) lpvVertices) + current_offset;
1269 current_offset += sizeof(DWORD);
1271 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1272 strided.textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset;
1273 current_offset += 2 * sizeof(D3DVALUE);
1275 strided.position.dwStride = current_offset;
1276 strided.normal.dwStride = current_offset;
1277 strided.diffuse.dwStride = current_offset;
1278 strided.specular.dwStride = current_offset;
1279 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
1280 strided.textureCoords[tex_index].dwStride = current_offset;
1282 draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwStartVertex, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1285 HRESULT WINAPI
1286 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1287 D3DPRIMITIVETYPE d3dptPrimitiveType,
1288 DWORD d3dvtVertexType,
1289 LPVOID lpvVertices,
1290 DWORD dwVertexCount,
1291 DWORD dwFlags)
1293 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1294 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1296 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1298 return DD_OK;
1301 HRESULT WINAPI
1302 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1303 D3DPRIMITIVETYPE d3dptPrimitiveType,
1304 DWORD d3dvtVertexType,
1305 LPVOID lpvVertices,
1306 DWORD dwVertexCount,
1307 LPWORD dwIndices,
1308 DWORD dwIndexCount,
1309 DWORD dwFlags)
1311 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1312 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1314 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1316 return DD_OK;
1319 HRESULT WINAPI
1320 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1321 D3DPRIMITIVETYPE d3dptPrimitiveType,
1322 DWORD dwVertexType,
1323 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1324 DWORD dwVertexCount,
1325 DWORD dwFlags)
1327 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1328 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1329 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1330 return DD_OK;
1333 HRESULT WINAPI
1334 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1335 D3DPRIMITIVETYPE d3dptPrimitiveType,
1336 DWORD dwVertexType,
1337 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1338 DWORD dwVertexCount,
1339 LPWORD lpIndex,
1340 DWORD dwIndexCount,
1341 DWORD dwFlags)
1343 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1344 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1345 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1346 return DD_OK;
1349 HRESULT WINAPI
1350 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1351 D3DPRIMITIVETYPE d3dptPrimitiveType,
1352 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1353 DWORD dwStartVertex,
1354 DWORD dwNumVertices,
1355 DWORD dwFlags)
1357 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1358 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1360 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1362 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1364 return DD_OK;
1367 HRESULT WINAPI
1368 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1369 D3DPRIMITIVETYPE d3dptPrimitiveType,
1370 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1371 DWORD dwStartVertex,
1372 DWORD dwNumVertices,
1373 LPWORD lpwIndices,
1374 DWORD dwIndexCount,
1375 DWORD dwFlags)
1377 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1378 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1380 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1382 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1384 return DD_OK;
1387 HRESULT WINAPI
1388 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1389 DWORD dwStage,
1390 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1391 DWORD dwState)
1393 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1394 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1395 GLenum gl_state;
1397 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1399 if (TRACE_ON(ddraw)) {
1400 TRACE(" Stage type is : ");
1401 switch (d3dTexStageStateType) {
1402 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1403 GEN_CASE(D3DTSS_COLOROP);
1404 GEN_CASE(D3DTSS_COLORARG1);
1405 GEN_CASE(D3DTSS_COLORARG2);
1406 GEN_CASE(D3DTSS_ALPHAOP);
1407 GEN_CASE(D3DTSS_ALPHAARG1);
1408 GEN_CASE(D3DTSS_ALPHAARG2);
1409 GEN_CASE(D3DTSS_BUMPENVMAT00);
1410 GEN_CASE(D3DTSS_BUMPENVMAT01);
1411 GEN_CASE(D3DTSS_BUMPENVMAT10);
1412 GEN_CASE(D3DTSS_BUMPENVMAT11);
1413 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1414 GEN_CASE(D3DTSS_ADDRESS);
1415 GEN_CASE(D3DTSS_ADDRESSU);
1416 GEN_CASE(D3DTSS_ADDRESSV);
1417 GEN_CASE(D3DTSS_BORDERCOLOR);
1418 GEN_CASE(D3DTSS_MAGFILTER);
1419 GEN_CASE(D3DTSS_MINFILTER);
1420 GEN_CASE(D3DTSS_MIPFILTER);
1421 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1422 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1423 GEN_CASE(D3DTSS_MAXANISOTROPY);
1424 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1425 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1426 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1427 #undef GEN_CASE
1428 default: DPRINTF("UNKNOWN !!!");
1430 DPRINTF(" => ");
1433 switch (d3dTexStageStateType) {
1434 case D3DTSS_MINFILTER:
1435 switch ((D3DTEXTUREMINFILTER) dwState) {
1436 case D3DTFN_POINT:
1437 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1438 gl_state = GL_NEAREST;
1439 break;
1440 case D3DTFN_LINEAR:
1441 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1442 gl_state = GL_LINEAR;
1443 break;
1444 default:
1445 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1446 gl_state = GL_LINEAR;
1447 break;
1449 glThis->render_state.min = gl_state;
1450 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1451 break;
1453 case D3DTSS_MAGFILTER:
1454 switch ((D3DTEXTUREMAGFILTER) dwState) {
1455 case D3DTFG_POINT:
1456 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1457 gl_state = GL_NEAREST;
1458 break;
1459 case D3DTFG_LINEAR:
1460 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1461 gl_state = GL_LINEAR;
1462 break;
1463 default:
1464 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1465 gl_state = GL_LINEAR;
1466 break;
1468 glThis->render_state.mag = gl_state;
1469 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1470 break;
1472 case D3DTSS_ADDRESS:
1473 case D3DTSS_ADDRESSU:
1474 case D3DTSS_ADDRESSV: {
1475 GLenum arg = GL_REPEAT; /* Default value */
1476 switch ((D3DTEXTUREADDRESS) dwState) {
1477 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1478 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1479 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1480 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1482 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1483 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1484 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1485 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1486 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1487 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1488 } break;
1490 default:
1491 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1494 return DD_OK;
1497 HRESULT WINAPI
1498 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1499 DWORD dwStage,
1500 LPDIRECTDRAWSURFACE7 lpTexture2)
1502 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1503 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1505 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1507 if (This->current_texture[dwStage] != NULL) {
1508 /* Seems that this is not right... Need to test in real Windows
1509 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1512 ENTER_GL();
1513 if (lpTexture2 == NULL) {
1514 TRACE(" disabling 2D texturing.\n");
1515 glBindTexture(GL_TEXTURE_2D, 0);
1516 glDisable(GL_TEXTURE_2D);
1517 } else {
1518 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1519 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
1521 This->current_texture[dwStage] = tex_impl;
1522 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1524 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1526 glEnable(GL_TEXTURE_2D);
1527 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1528 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glThis->render_state.mag);
1529 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glThis->render_state.min);
1531 LEAVE_GL();
1533 return DD_OK;
1536 HRESULT WINAPI
1537 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1538 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1540 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1541 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1543 fill_opengl_caps_7(lpD3DHELDevDesc);
1545 TRACE(" returning caps : no dump function yet.\n");
1547 return DD_OK;
1550 HRESULT WINAPI
1551 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1552 LPD3DMATERIAL7 lpMat)
1554 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1555 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1557 if (TRACE_ON(ddraw)) {
1558 TRACE(" material is : \n");
1559 dump_D3DMATERIAL7(lpMat);
1562 This->current_material = *lpMat;
1564 glMaterialfv(GL_FRONT_AND_BACK,
1565 GL_DIFFUSE,
1566 (float *) &(This->current_material.u.diffuse));
1567 glMaterialfv(GL_FRONT_AND_BACK,
1568 GL_AMBIENT,
1569 (float *) &(This->current_material.u1.ambient));
1570 glMaterialfv(GL_FRONT_AND_BACK,
1571 GL_SPECULAR,
1572 (float *) &(This->current_material.u2.specular));
1573 glMaterialfv(GL_FRONT_AND_BACK,
1574 GL_EMISSION,
1575 (float *) &(This->current_material.u3.emissive));
1576 glMaterialf(GL_FRONT_AND_BACK,
1577 GL_SHININESS,
1578 This->current_material.u4.power); /* Not sure about this... */
1580 return DD_OK;
1584 HRESULT WINAPI
1585 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1586 DWORD dwLightIndex,
1587 LPD3DLIGHT7 lpLight)
1589 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1590 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1592 if (TRACE_ON(ddraw)) {
1593 TRACE(" setting light : \n");
1594 dump_D3DLIGHT7(lpLight);
1597 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1598 This->set_lights |= 0x00000001 << dwLightIndex;
1599 This->light_parameters[dwLightIndex] = *lpLight;
1601 switch (lpLight->dltType) {
1602 case D3DLIGHT_DIRECTIONAL: { /* 3 */
1603 float direction[4];
1605 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1606 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1607 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1609 direction[0] = lpLight->dvDirection.u1.x;
1610 direction[1] = lpLight->dvDirection.u2.y;
1611 direction[2] = lpLight->dvDirection.u3.z;
1612 direction[3] = 0.0; /* This is a directional light */
1614 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1615 } break;
1617 default: WARN(" light type not handled yet...\n");
1620 return DD_OK;
1623 HRESULT WINAPI
1624 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1625 DWORD dwLightIndex,
1626 BOOL bEnable)
1628 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1629 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1631 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1633 if (bEnable) {
1634 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1635 /* Set the default parameters.. */
1636 TRACE(" setting default light parameters...\n");
1637 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1639 glEnable(GL_LIGHT0 + dwLightIndex);
1640 } else {
1641 glDisable(GL_LIGHT0 + dwLightIndex);
1644 return DD_OK;
1647 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1648 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1649 #else
1650 # define XCAST(fun) (void*)
1651 #endif
1653 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1655 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1656 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1657 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1658 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1659 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1660 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1661 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1662 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1663 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1664 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1665 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1666 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1667 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1668 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1669 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1670 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1671 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1672 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1673 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1674 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1675 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1676 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1677 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1678 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1679 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1680 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1681 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1682 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1683 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1684 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1685 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1686 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1687 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1688 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1689 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1690 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1691 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1692 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1693 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1694 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1695 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1696 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1697 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1698 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1699 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1700 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1701 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1702 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1703 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1704 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1707 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1708 #undef XCAST
1709 #endif
1712 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1713 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1714 #else
1715 # define XCAST(fun) (void*)
1716 #endif
1718 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1720 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1721 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1722 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1723 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1724 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1725 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1726 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1727 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1728 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1729 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1730 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1731 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1732 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1733 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1734 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1735 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1736 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1737 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1738 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1739 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1740 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1741 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1742 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1743 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1744 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1745 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1746 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1747 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1748 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1749 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1750 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1751 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1752 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1753 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1754 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1755 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1756 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1757 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1758 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1759 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1760 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1761 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1762 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1765 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1766 #undef XCAST
1767 #endif
1770 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1771 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1772 #else
1773 # define XCAST(fun) (void*)
1774 #endif
1776 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1778 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1779 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1780 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1781 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1782 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1783 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
1784 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1785 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1786 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1787 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1788 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1789 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1790 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1791 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1792 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1793 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1794 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1795 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1796 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1797 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1798 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1799 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1800 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1801 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1802 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1803 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1804 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1805 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1806 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1807 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1808 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1809 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1810 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1811 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1814 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1815 #undef XCAST
1816 #endif
1819 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1820 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1821 #else
1822 # define XCAST(fun) (void*)
1823 #endif
1825 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1827 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1828 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1829 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1830 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1831 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1832 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1833 XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
1834 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1835 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1836 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1837 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1838 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1839 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1840 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1841 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1842 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1843 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1844 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1845 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1846 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1847 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1848 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1849 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1852 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1853 #undef XCAST
1854 #endif
1856 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1857 DWORD dwCount,
1858 LPD3DRECT lpRects,
1859 DWORD dwFlags,
1860 DWORD dwColor,
1861 D3DVALUE dvZ,
1862 DWORD dwStencil)
1864 GLboolean ztest;
1865 GLfloat old_z_clear_value;
1866 GLbitfield bitfield = 0;
1867 GLint old_stencil_clear_value;
1868 GLfloat old_color_clear_value[4];
1870 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1871 if (TRACE_ON(ddraw)) {
1872 if (dwCount > 0) {
1873 int i;
1874 TRACE(" rectangles : \n");
1875 for (i = 0; i < dwCount; i++) {
1876 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1881 if (dwCount > 1) {
1882 WARN(" Warning, this function only for now clears the whole screen...\n");
1885 /* Clears the screen */
1886 ENTER_GL();
1887 if (dwFlags & D3DCLEAR_ZBUFFER) {
1888 bitfield |= GL_DEPTH_BUFFER_BIT;
1889 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1890 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1891 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1892 glClearDepth(dvZ);
1893 TRACE(" depth value : %f\n", dvZ);
1895 if (dwFlags & D3DCLEAR_STENCIL) {
1896 bitfield |= GL_STENCIL_BUFFER_BIT;
1897 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1898 glClearStencil(dwStencil);
1899 TRACE(" stencil value : %ld\n", dwStencil);
1901 if (dwFlags & D3DCLEAR_TARGET) {
1902 bitfield |= GL_COLOR_BUFFER_BIT;
1903 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1904 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1905 ((dwColor >> 8) & 0xFF) / 255.0,
1906 ((dwColor >> 0) & 0xFF) / 255.0,
1907 ((dwColor >> 24) & 0xFF) / 255.0);
1908 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1911 glClear(bitfield);
1913 if (dwFlags & D3DCLEAR_ZBUFFER) {
1914 glDepthMask(ztest);
1915 glClearDepth(old_z_clear_value);
1917 if (dwFlags & D3DCLEAR_STENCIL) {
1918 bitfield |= GL_STENCIL_BUFFER_BIT;
1919 glClearStencil(old_stencil_clear_value);
1921 if (dwFlags & D3DCLEAR_TARGET) {
1922 bitfield |= GL_COLOR_BUFFER_BIT;
1923 glClearColor(old_color_clear_value[0],
1924 old_color_clear_value[1],
1925 old_color_clear_value[2],
1926 old_color_clear_value[3]);
1929 LEAVE_GL();
1931 return DD_OK;
1934 HRESULT
1935 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1936 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1937 DWORD dwFlags, LPDDBLTFX lpbltfx)
1939 if (dwFlags & DDBLT_COLORFILL) {
1940 /* This is easy to handle for the D3D Device... */
1941 DWORD color = lpbltfx->u5.dwFillColor;
1942 TRACE(" executing D3D Device override.\n");
1943 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1944 return DD_OK;
1946 return DDERR_INVALIDPARAMS;
1949 HRESULT
1950 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1951 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1952 LPRECT rsrc, DWORD trans)
1954 return DDERR_INVALIDPARAMS;
1958 /* TODO for both these functions :
1959 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1960 by other OpenGL code in D3D
1961 - handle the case where no 'Begin / EndScene' was done between two locks
1962 - handle the rectangles in the unlock too
1963 - handle pitch correctly...
1965 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1967 /* First, check if we need to do anything */
1968 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1969 GLenum buffer_type;
1970 GLenum prev_read;
1971 RECT loc_rect;
1973 ENTER_GL();
1975 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1976 glFlush();
1978 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1979 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1980 /* Application wants to lock the front buffer */
1981 glReadBuffer(GL_FRONT);
1982 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1983 /* Application wants to lock the back buffer */
1984 glReadBuffer(GL_BACK);
1985 } else {
1986 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1989 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1990 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1991 } else {
1992 WARN(" unsupported pixel format.\n");
1993 LEAVE_GL();
1994 return;
1996 if (pRect == NULL) {
1997 loc_rect.top = 0;
1998 loc_rect.left = 0;
1999 loc_rect.bottom = This->surface_desc.dwHeight;
2000 loc_rect.right = This->surface_desc.dwWidth;
2001 } else {
2002 loc_rect = *pRect;
2004 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
2005 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
2006 + loc_rect.top * This->surface_desc.u1.lPitch
2007 + loc_rect.left * GET_BPP(This->surface_desc)));
2008 glReadBuffer(prev_read);
2009 LEAVE_GL();
2013 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
2015 /* First, check if we need to do anything */
2016 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
2017 GLenum buffer_type;
2018 GLenum prev_draw;
2020 ENTER_GL();
2022 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
2024 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
2025 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2026 /* Application wants to lock the front buffer */
2027 glDrawBuffer(GL_FRONT);
2028 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2029 /* Application wants to lock the back buffer */
2030 glDrawBuffer(GL_BACK);
2031 } else {
2032 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
2035 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2036 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2037 } else {
2038 WARN(" unsupported pixel format.\n");
2039 LEAVE_GL();
2040 return;
2042 glRasterPos2f(0.0, 0.0);
2043 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
2044 GL_RGB, buffer_type, This->surface_desc.lpSurface);
2045 glDrawBuffer(prev_draw);
2047 LEAVE_GL();
2051 HRESULT
2052 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
2054 IDirect3DDeviceImpl *object;
2055 IDirect3DDeviceGLImpl *gl_object;
2056 IDirectDrawSurfaceImpl *surf;
2057 HDC device_context;
2058 XVisualInfo *vis;
2059 int num;
2060 XVisualInfo template;
2061 GLenum buffer;
2062 int light;
2064 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
2065 if (object == NULL) return DDERR_OUTOFMEMORY;
2067 gl_object = (IDirect3DDeviceGLImpl *) object;
2069 object->ref = 1;
2070 object->d3d = d3d;
2071 object->surface = surface;
2072 object->set_context = set_context;
2073 object->clear = d3ddevice_clear;
2075 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
2077 device_context = GetDC(surface->ddraw_owner->window);
2078 gl_object->display = get_display(device_context);
2079 gl_object->drawable = get_drawable(device_context);
2080 ReleaseDC(surface->ddraw_owner->window,device_context);
2082 ENTER_GL();
2083 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2084 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2085 if (vis == NULL) {
2086 HeapFree(GetProcessHeap(), 0, object);
2087 ERR("No visual found !\n");
2088 LEAVE_GL();
2089 return DDERR_INVALIDPARAMS;
2090 } else {
2091 TRACE(" visual found\n");
2094 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2095 NULL, GL_TRUE);
2097 if (gl_object->gl_context == NULL) {
2098 HeapFree(GetProcessHeap(), 0, object);
2099 ERR("Error in context creation !\n");
2100 LEAVE_GL();
2101 return DDERR_INVALIDPARAMS;
2102 } else {
2103 TRACE(" context created (%p)\n", gl_object->gl_context);
2106 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2107 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2108 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2109 surf->aux_ctx = (LPVOID) gl_object->display;
2110 surf->aux_data = (LPVOID) gl_object->drawable;
2111 surf->aux_flip = opengl_flip;
2112 buffer = GL_BACK;
2113 break;
2116 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2117 if (surf == NULL) {
2118 TRACE(" no double buffering : drawing on the front buffer\n");
2119 buffer = GL_FRONT;
2122 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2123 for (; surf != NULL; surf = surf->next_attached) {
2124 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2125 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2126 /* Override the Lock / Unlock function for all these surfaces */
2127 surf->lock_update = d3ddevice_lock_update;
2128 surf->unlock_update = d3ddevice_unlock_update;
2129 /* And install also the blt / bltfast overrides */
2130 surf->aux_blt = d3ddevice_blt;
2131 surf->aux_bltfast = d3ddevice_bltfast;
2133 surf->d3ddevice = object;
2136 gl_object->render_state.src = GL_ONE;
2137 gl_object->render_state.dst = GL_ZERO;
2138 gl_object->render_state.mag = GL_NEAREST;
2139 gl_object->render_state.min = GL_NEAREST;
2140 gl_object->render_state.alpha_ref = 0.0; /* No actual idea about the real default value... */
2141 gl_object->render_state.alpha_func = GL_ALWAYS; /* Here either but it seems logical */
2142 gl_object->render_state.alpha_blend_enable = FALSE;
2143 gl_object->render_state.fog_on = FALSE;
2144 gl_object->render_state.stencil_func = GL_ALWAYS;
2145 gl_object->render_state.stencil_mask = 0xFFFFFFFF;
2146 gl_object->render_state.stencil_ref = 0;
2147 gl_object->render_state.stencil_enable = FALSE;
2148 gl_object->render_state.stencil_fail = GL_KEEP;
2149 gl_object->render_state.stencil_zfail = GL_KEEP;
2150 gl_object->render_state.stencil_pass = GL_KEEP;
2151 gl_object->render_state.lighting_enable = FALSE;
2152 gl_object->render_state.specular_enable = FALSE;
2153 gl_object->render_state.color_diffuse = D3DMCS_COLOR1;
2154 gl_object->render_state.color_specular = D3DMCS_COLOR2;
2155 gl_object->render_state.color_ambient = D3DMCS_COLOR2;
2156 gl_object->render_state.color_emissive = D3DMCS_MATERIAL;
2158 /* Set the various light parameters */
2159 for (light = 0; light < MAX_LIGHTS; light++) {
2160 /* Only set the fields that are not zero-created */
2161 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2162 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2163 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2164 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2165 object->light_parameters[light].dvDirection.u3.z = 1.0;
2168 /* Allocate memory for the matrices */
2169 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2170 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2171 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2172 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2173 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2174 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2176 /* Initialisation */
2177 TRACE(" setting current context\n");
2178 LEAVE_GL();
2179 object->set_context(object);
2180 ENTER_GL();
2181 TRACE(" current context set\n");
2182 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2183 glClearColor(0.0, 0.0, 0.0, 0.0);
2184 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2185 glDrawBuffer(buffer);
2186 glReadBuffer(buffer);
2187 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2188 LEAVE_GL();
2190 /* fill_device_capabilities(d3d->ddraw); */
2192 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2193 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2194 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2195 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2197 *obj = object;
2199 TRACE(" creating implementation at %p.\n", *obj);
2201 /* And finally warn D3D that this device is now present */
2202 object->d3d->added_device(object->d3d, object);
2204 return DD_OK;