Implementation of (Get|Set)ClipPlane for d3d7.
[wine/multimedia.git] / dlls / ddraw / d3ddevice / mesa.c
blobc2f175e41fbf1236e9497fb1f2d98dd1be5f6e3e
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 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(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 dref, d1, d2;
275 HRESULT ret_value;
277 fill_opengl_caps(&dref);
279 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
280 d1 = dref;
281 d2 = dref;
282 ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
283 if (ret_value != D3DENUMRET_OK)
284 return ret_value;
286 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
287 d1 = dref;
288 d2 = dref;
289 ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
290 if (ret_value != D3DENUMRET_OK)
291 return ret_value;
293 return D3DENUMRET_OK;
296 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
298 D3DDEVICEDESC7 ddesc;
300 fill_opengl_caps_7(&ddesc);
302 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
304 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
307 ULONG WINAPI
308 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
310 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
311 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
313 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
314 if (!--(This->ref)) {
315 int i;
316 /* Release texture associated with the device */
317 for (i = 0; i < MAX_TEXTURES; i++)
318 if (This->current_texture[i] != NULL)
319 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[i], IDirectDrawSurface7));
321 /* And warn the D3D object that this device is no longer active... */
322 This->d3d->removed_device(This->d3d, This);
324 HeapFree(GetProcessHeap(), 0, This->world_mat);
325 HeapFree(GetProcessHeap(), 0, This->view_mat);
326 HeapFree(GetProcessHeap(), 0, This->proj_mat);
328 ENTER_GL();
329 glXDestroyContext(glThis->display, glThis->gl_context);
330 LEAVE_GL();
331 HeapFree(GetProcessHeap(), 0, This->clipping_planes);
333 HeapFree(GetProcessHeap(), 0, This);
334 return 0;
336 return This->ref;
339 HRESULT WINAPI
340 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
341 LPD3DDEVICEDESC lpD3DHWDevDesc,
342 LPD3DDEVICEDESC lpD3DHELDevDesc)
344 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
345 D3DDEVICEDESC desc;
346 DWORD dwSize;
348 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
350 fill_opengl_caps(&desc);
351 dwSize = lpD3DHWDevDesc->dwSize;
352 memset(lpD3DHWDevDesc, 0, dwSize);
353 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
355 dwSize = lpD3DHELDevDesc->dwSize;
356 memset(lpD3DHELDevDesc, 0, dwSize);
357 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
359 TRACE(" returning caps : (no dump function yet)\n");
361 return DD_OK;
364 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
365 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
366 LPVOID context)
368 DDSURFACEDESC sdesc;
369 LPDDPIXELFORMAT pformat;
371 /* Do the texture enumeration */
372 sdesc.dwSize = sizeof(DDSURFACEDESC);
373 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
374 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
375 pformat = &(sdesc.ddpfPixelFormat);
376 pformat->dwSize = sizeof(DDPIXELFORMAT);
377 pformat->dwFourCC = 0;
379 TRACE("Enumerating GL_RGBA unpacked (32)\n");
380 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
381 pformat->u1.dwRGBBitCount = 32;
382 pformat->u2.dwRBitMask = 0xFF000000;
383 pformat->u3.dwGBitMask = 0x00FF0000;
384 pformat->u4.dwBBitMask = 0x0000FF00;
385 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
386 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
387 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
389 TRACE("Enumerating GL_RGB unpacked (24)\n");
390 pformat->dwFlags = DDPF_RGB;
391 pformat->u1.dwRGBBitCount = 24;
392 pformat->u2.dwRBitMask = 0x00FF0000;
393 pformat->u3.dwGBitMask = 0x0000FF00;
394 pformat->u4.dwBBitMask = 0x000000FF;
395 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
396 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
397 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
399 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
400 pformat->dwFlags = DDPF_RGB;
401 pformat->u1.dwRGBBitCount = 16;
402 pformat->u2.dwRBitMask = 0x0000F800;
403 pformat->u3.dwGBitMask = 0x000007E0;
404 pformat->u4.dwBBitMask = 0x0000001F;
405 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
406 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
407 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
409 /* Note : even if this is an 'emulated' texture format, it needs to be first
410 as some dumb applications seem to rely on that. */
411 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n");
412 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
413 pformat->u1.dwRGBBitCount = 16;
414 pformat->u2.dwRBitMask = 0x00007C00;
415 pformat->u3.dwGBitMask = 0x000003E0;
416 pformat->u4.dwBBitMask = 0x0000001F;
417 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
418 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
419 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
421 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
422 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
423 pformat->u1.dwRGBBitCount = 16;
424 pformat->u2.dwRBitMask = 0x00000F00;
425 pformat->u3.dwGBitMask = 0x000000F0;
426 pformat->u4.dwBBitMask = 0x0000000F;
427 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
428 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
429 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
431 #if 0
432 /* This is a compromise : some games choose the first 16 bit texture format with alpha they
433 find enumerated, others the last one. And both want to have the ARGB one.
435 So basically, forget our OpenGL roots and do not even enumerate our RGBA ones.
437 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
438 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
439 pformat->u1.dwRGBBitCount = 16;
440 pformat->u2.dwRBitMask = 0x0000F000;
441 pformat->u3.dwGBitMask = 0x00000F00;
442 pformat->u4.dwBBitMask = 0x000000F0;
443 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
444 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
445 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
447 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
448 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
449 pformat->u1.dwRGBBitCount = 16;
450 pformat->u2.dwRBitMask = 0x0000F800;
451 pformat->u3.dwGBitMask = 0x000007C0;
452 pformat->u4.dwBBitMask = 0x0000003E;
453 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
454 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
455 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
456 #endif
458 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
459 pformat->dwFlags = DDPF_RGB;
460 pformat->u1.dwRGBBitCount = 8;
461 pformat->u2.dwRBitMask = 0x000000E0;
462 pformat->u3.dwGBitMask = 0x0000001C;
463 pformat->u4.dwBBitMask = 0x00000003;
464 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
465 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
466 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
468 TRACE("Enumerating Paletted (8)\n");
469 pformat->dwFlags = DDPF_PALETTEINDEXED8;
470 pformat->u1.dwRGBBitCount = 8;
471 pformat->u2.dwRBitMask = 0x00000000;
472 pformat->u3.dwGBitMask = 0x00000000;
473 pformat->u4.dwBBitMask = 0x00000000;
474 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
475 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
476 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
478 TRACE("End of enumeration\n");
479 return DD_OK;
483 HRESULT
484 d3ddevice_find(IDirect3DImpl *d3d,
485 LPD3DFINDDEVICESEARCH lpD3DDFS,
486 LPD3DFINDDEVICERESULT lplpD3DDevice)
488 D3DDEVICEDESC desc;
490 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
491 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
492 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
493 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
495 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
496 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
497 if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
498 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0) &&
499 (IsEqualGUID(&IID_IDirect3DRefDevice, &(lpD3DDFS->guid)) == 0)) {
500 TRACE(" no match for this GUID.\n");
501 return DDERR_INVALIDPARAMS;
505 /* Now return our own GUID */
506 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
507 fill_opengl_caps(&desc);
508 lplpD3DDevice->ddHwDesc = desc;
509 lplpD3DDevice->ddSwDesc = desc;
511 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
513 return D3D_OK;
516 HRESULT WINAPI
517 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
518 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
519 LPVOID lpArg)
521 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
522 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
523 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
526 HRESULT WINAPI
527 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
528 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
529 LPVOID lpArg)
531 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
532 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
533 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
536 HRESULT WINAPI
537 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
538 D3DRENDERSTATETYPE dwRenderStateType,
539 DWORD dwRenderState)
541 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
542 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
543 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
545 /* Call the render state functions */
546 set_render_state(glThis, dwRenderStateType, dwRenderState);
547 store_render_state(dwRenderStateType, dwRenderState, &glThis->parent.state_block);
549 return DD_OK;
552 HRESULT WINAPI
553 GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
554 D3DRENDERSTATETYPE dwRenderStateType,
555 LPDWORD lpdwRenderState)
557 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
558 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
559 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState);
561 /* Call the render state functions */
562 get_render_state(dwRenderStateType, lpdwRenderState, &glThis->parent.state_block);
564 return DD_OK;
567 HRESULT WINAPI
568 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
569 D3DLIGHTSTATETYPE dwLightStateType,
570 DWORD dwLightState)
572 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
573 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
575 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
577 switch (dwLightStateType) {
578 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
579 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
581 if (mat != NULL) {
582 ENTER_GL();
583 mat->activate(mat);
584 LEAVE_GL();
585 } else {
586 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
588 } break;
590 case D3DLIGHTSTATE_AMBIENT: /* 2 */
591 /* Call the render_state function... */
592 set_render_state(glThis, D3DRENDERSTATE_AMBIENT, dwLightState);
593 break;
595 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
596 UNSUP(COLORMODEL);
597 UNSUP(FOGMODE);
598 UNSUP(FOGSTART);
599 UNSUP(FOGEND);
600 UNSUP(FOGDENSITY);
601 UNSUP(COLORVERTEX);
602 #undef UNSUP
604 default:
605 TRACE("Unexpected Light State Type\n");
606 return DDERR_INVALIDPARAMS;
609 This->state_block.light_state[dwLightStateType] = dwLightState;
611 return DD_OK;
614 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
616 switch (d3dpt) {
617 case D3DPT_POINTLIST:
618 TRACE("Start POINTS\n");
619 glBegin(GL_POINTS);
620 break;
622 case D3DPT_LINELIST:
623 TRACE("Start LINES\n");
624 glBegin(GL_LINES);
625 break;
627 case D3DPT_LINESTRIP:
628 TRACE("Start LINE_STRIP\n");
629 glBegin(GL_LINE_STRIP);
630 break;
632 case D3DPT_TRIANGLELIST:
633 TRACE("Start TRIANGLES\n");
634 glBegin(GL_TRIANGLES);
635 break;
637 case D3DPT_TRIANGLESTRIP:
638 TRACE("Start TRIANGLE_STRIP\n");
639 glBegin(GL_TRIANGLE_STRIP);
640 break;
642 case D3DPT_TRIANGLEFAN:
643 TRACE("Start TRIANGLE_FAN\n");
644 glBegin(GL_TRIANGLE_FAN);
645 break;
647 default:
648 TRACE("Unhandled primitive\n");
649 break;
653 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
654 BOOLEAN vertex_transformed,
655 BOOLEAN vertex_lit) {
656 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
658 /* Puts GL in the correct lighting / transformation mode */
659 if ((vertex_transformed == FALSE) &&
660 (glThis->transform_state != GL_TRANSFORM_NORMAL)) {
661 /* Need to put the correct transformation again if we go from Transformed
662 vertices to non-transformed ones.
664 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
665 This->world_mat, This->view_mat, This->proj_mat);
666 glThis->transform_state = GL_TRANSFORM_NORMAL;
668 if (glThis->render_state.fog_on == TRUE)
669 glEnable(GL_FOG);
670 } else if ((vertex_transformed == TRUE) &&
671 (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
672 /* Set our orthographic projection */
673 glThis->transform_state = GL_TRANSFORM_ORTHO;
674 d3ddevice_set_ortho(This);
676 /* Remove also fogging... */
677 glDisable(GL_FOG);
680 /* Handle the 'no-normal' case */
681 if (vertex_lit == FALSE)
682 glDisable(GL_LIGHTING);
683 else if (glThis->render_state.lighting_enable == TRUE)
684 glEnable(GL_LIGHTING);
686 /* Handle the code for pre-vertex material properties */
687 if (vertex_transformed == FALSE) {
688 if (glThis->render_state.lighting_enable == TRUE) {
689 if ((glThis->render_state.color_diffuse != D3DMCS_MATERIAL) ||
690 (glThis->render_state.color_specular != D3DMCS_MATERIAL) ||
691 (glThis->render_state.color_ambient != D3DMCS_MATERIAL) ||
692 (glThis->render_state.color_emissive != D3DMCS_MATERIAL)) {
693 glEnable(GL_COLOR_MATERIAL);
700 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
701 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
703 D3DDRAWPRIMITIVESTRIDEDDATA strided;
705 switch (d3dvt) {
706 case D3DVT_VERTEX: {
707 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
708 strided.position.dwStride = sizeof(D3DVERTEX);
709 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
710 strided.normal.dwStride = sizeof(D3DVERTEX);
711 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
712 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
713 draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
714 } break;
716 case D3DVT_LVERTEX: {
717 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
718 strided.position.dwStride = sizeof(D3DLVERTEX);
719 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
720 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
721 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
722 strided.specular.dwStride = sizeof(D3DLVERTEX);
723 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
724 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
725 draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
726 } break;
728 case D3DVT_TLVERTEX: {
729 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
730 strided.position.dwStride = sizeof(D3DTLVERTEX);
731 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
732 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
733 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
734 strided.specular.dwStride = sizeof(D3DTLVERTEX);
735 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
736 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
737 draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
738 } break;
740 default:
741 FIXME("Unhandled vertex type\n");
742 break;
746 HRESULT WINAPI
747 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
748 D3DPRIMITIVETYPE d3dptPrimitiveType,
749 D3DVERTEXTYPE d3dvtVertexType,
750 LPVOID lpvVertices,
751 DWORD dwVertexCount,
752 DWORD dwFlags)
754 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
756 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
757 if (TRACE_ON(ddraw)) {
758 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
761 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
763 return DD_OK;
766 HRESULT WINAPI
767 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
768 D3DPRIMITIVETYPE d3dptPrimitiveType,
769 D3DVERTEXTYPE d3dvtVertexType,
770 LPVOID lpvVertices,
771 DWORD dwVertexCount,
772 LPWORD dwIndices,
773 DWORD dwIndexCount,
774 DWORD dwFlags)
776 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
777 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
778 if (TRACE_ON(ddraw)) {
779 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
782 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
784 return DD_OK;
787 HRESULT WINAPI
788 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
789 LPD3DEXECUTEBUFFERDESC lpDesc,
790 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
791 IUnknown* pUnkOuter)
793 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
794 IDirect3DExecuteBufferImpl *ret;
795 HRESULT ret_value;
797 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
799 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
800 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
802 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
804 return ret_value;
807 /* These are the various handler used in the generic path */
808 inline static void handle_xyz(D3DVALUE *coords) {
809 glVertex3fv(coords);
811 inline static void handle_xyzrhw(D3DVALUE *coords) {
812 if (coords[3] < 1e-8)
813 glVertex3fv(coords);
814 else {
815 GLfloat w = 1.0 / coords[3];
817 glVertex4f(coords[0] * w,
818 coords[1] * w,
819 coords[2] * w,
823 inline static void handle_normal(D3DVALUE *coords) {
824 glNormal3fv(coords);
827 inline static void handle_diffuse_base(RenderState *rs, DWORD *color) {
828 if (rs->alpha_blend_enable == TRUE) {
829 glColor4ub((*color >> 16) & 0xFF,
830 (*color >> 8) & 0xFF,
831 (*color >> 0) & 0xFF,
832 (*color >> 24) & 0xFF);
833 } else {
834 glColor3ub((*color >> 16) & 0xFF,
835 (*color >> 8) & 0xFF,
836 (*color >> 0) & 0xFF);
840 inline static void handle_specular_base(RenderState *rs, DWORD *color) {
841 glColor4ub((*color >> 16) & 0xFF,
842 (*color >> 8) & 0xFF,
843 (*color >> 0) & 0xFF,
844 (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
847 inline static void handle_diffuse(RenderState *rs, DWORD *color) {
848 if (rs->lighting_enable == TRUE) {
849 if (rs->color_diffuse == D3DMCS_COLOR1) {
850 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
851 handle_diffuse_base(rs, color);
853 if (rs->color_ambient == D3DMCS_COLOR1) {
854 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
855 handle_diffuse_base(rs, color);
857 if ((rs->color_specular == D3DMCS_COLOR1) && (rs->specular_enable == TRUE)) {
858 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
859 handle_diffuse_base(rs, color);
861 if (rs->color_emissive == D3DMCS_COLOR1) {
862 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
863 handle_diffuse_base(rs, color);
865 } else {
866 handle_diffuse_base(rs, color);
870 inline static void handle_specular(RenderState *rs, DWORD *color) {
871 if (rs->lighting_enable == TRUE) {
872 if (rs->color_diffuse == D3DMCS_COLOR2) {
873 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
874 handle_specular(rs, color);
876 if (rs->color_ambient == D3DMCS_COLOR2) {
877 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
878 handle_specular(rs, color);
880 if ((rs->color_specular == D3DMCS_COLOR2) && (rs->specular_enable == TRUE)) {
881 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
882 handle_specular(rs, color);
884 if (rs->color_emissive == D3DMCS_COLOR2) {
885 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
886 handle_specular(rs, color);
889 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
892 inline static void handle_diffuse_and_specular(RenderState *rs, DWORD *color_d, DWORD *color_s, BOOLEAN transformed) {
893 if (transformed == TRUE) {
894 if (rs->fog_on == TRUE) {
895 /* Special case where the specular value is used to do fogging. TODO */
897 if (rs->specular_enable == TRUE) {
898 /* Standard specular value in transformed mode. TODO */
900 handle_diffuse_base(rs, color_d);
901 } else {
902 if (rs->lighting_enable == TRUE) {
903 handle_diffuse(rs, color_d);
904 handle_specular(rs, color_s);
905 } else {
906 /* In that case, only put the diffuse color... */
907 handle_diffuse_base(rs, color_d);
912 inline static void handle_texture(D3DVALUE *coords) {
913 glTexCoord2fv(coords);
915 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
916 /* For the moment, draw only the first texture.. */
917 if (tex_index == 0) glTexCoord2fv(coords);
920 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
921 D3DPRIMITIVETYPE d3dptPrimitiveType,
922 DWORD d3dvtVertexType,
923 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
924 DWORD dwStartVertex,
925 DWORD dwVertexCount,
926 LPWORD dwIndices,
927 DWORD dwIndexCount,
928 DWORD dwFlags)
930 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
931 if (TRACE_ON(ddraw)) {
932 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
935 ENTER_GL();
936 draw_primitive_handle_GL_state(This,
937 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
938 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
939 draw_primitive_start_GL(d3dptPrimitiveType);
941 /* Some fast paths first before the generic case.... */
942 if (d3dvtVertexType == D3DFVF_VERTEX) {
943 int index;
945 for (index = 0; index < dwIndexCount; index++) {
946 int i = (dwIndices == NULL) ? index : dwIndices[index];
947 D3DVALUE *normal =
948 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
949 D3DVALUE *tex_coord =
950 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
951 D3DVALUE *position =
952 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
954 handle_normal(normal);
955 handle_texture(tex_coord);
956 handle_xyz(position);
958 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
959 position[0], position[1], position[2],
960 normal[0], normal[1], normal[2],
961 tex_coord[0], tex_coord[1]);
963 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
964 int index;
966 for (index = 0; index < dwIndexCount; index++) {
967 int i = (dwIndices == NULL) ? index : dwIndices[index];
968 DWORD *color_d =
969 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
970 DWORD *color_s =
971 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
972 D3DVALUE *tex_coord =
973 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
974 D3DVALUE *position =
975 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
977 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, TRUE);
978 handle_texture(tex_coord);
979 handle_xyzrhw(position);
981 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
982 position[0], position[1], position[2], position[3],
983 (*color_d >> 16) & 0xFF,
984 (*color_d >> 8) & 0xFF,
985 (*color_d >> 0) & 0xFF,
986 (*color_d >> 24) & 0xFF,
987 (*color_s >> 16) & 0xFF,
988 (*color_s >> 8) & 0xFF,
989 (*color_s >> 0) & 0xFF,
990 (*color_s >> 24) & 0xFF,
991 tex_coord[0], tex_coord[1]);
993 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
994 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
995 /* This is the 'slow path' but that should support all possible vertex formats out there...
996 Note that people should write a fast path for all vertex formats out there...
998 int index;
999 for (index = 0; index < dwIndexCount; index++) {
1000 int i = (dwIndices == NULL) ? index : dwIndices[index];
1002 if (d3dvtVertexType & D3DFVF_NORMAL) {
1003 D3DVALUE *normal =
1004 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1005 handle_normal(normal);
1007 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1008 DWORD *color_d =
1009 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1010 DWORD *color_s =
1011 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1012 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, (d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW);
1013 } else {
1014 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1015 DWORD *color_s =
1016 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1017 handle_specular(&(glThis->render_state), color_s);
1018 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1019 DWORD *color_d =
1020 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1021 handle_diffuse(&(glThis->render_state), color_d);
1025 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1026 /* Special case for single texture... */
1027 D3DVALUE *tex_coord =
1028 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1029 handle_texture(tex_coord);
1030 } else {
1031 int tex_index;
1032 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1033 D3DVALUE *tex_coord =
1034 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1035 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1036 handle_textures(tex_coord, tex_index);
1039 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1040 D3DVALUE *position =
1041 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1042 handle_xyz(position);
1043 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1044 D3DVALUE *position =
1045 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1046 handle_xyzrhw(position);
1049 if (TRACE_ON(ddraw)) {
1050 int tex_index;
1052 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1053 D3DVALUE *position =
1054 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1055 TRACE(" %f %f %f", position[0], position[1], position[2]);
1056 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1057 D3DVALUE *position =
1058 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1059 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1061 if (d3dvtVertexType & D3DFVF_NORMAL) {
1062 D3DVALUE *normal =
1063 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1064 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1066 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1067 DWORD *color_d =
1068 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1069 DPRINTF(" / %02lx %02lx %02lx %02lx",
1070 (*color_d >> 16) & 0xFF,
1071 (*color_d >> 8) & 0xFF,
1072 (*color_d >> 0) & 0xFF,
1073 (*color_d >> 24) & 0xFF);
1075 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1076 DWORD *color_s =
1077 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1078 DPRINTF(" / %02lx %02lx %02lx %02lx",
1079 (*color_s >> 16) & 0xFF,
1080 (*color_s >> 8) & 0xFF,
1081 (*color_s >> 0) & 0xFF,
1082 (*color_s >> 24) & 0xFF);
1084 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1085 D3DVALUE *tex_coord =
1086 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1087 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1088 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1090 DPRINTF("\n");
1093 } else {
1094 ERR(" matrix weighting not handled yet....\n");
1097 glEnd();
1099 /* Whatever the case, disable the color material stuff */
1100 glDisable(GL_COLOR_MATERIAL);
1102 LEAVE_GL();
1103 TRACE("End\n");
1106 HRESULT WINAPI
1107 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1108 D3DPRIMITIVETYPE d3dptPrimitiveType,
1109 DWORD d3dvtVertexType,
1110 LPVOID lpvVertices,
1111 DWORD dwVertexCount,
1112 DWORD dwFlags)
1114 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1115 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1117 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1118 if (TRACE_ON(ddraw)) {
1119 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1122 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1123 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1125 return DD_OK;
1128 HRESULT WINAPI
1129 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1130 D3DPRIMITIVETYPE d3dptPrimitiveType,
1131 DWORD d3dvtVertexType,
1132 LPVOID lpvVertices,
1133 DWORD dwVertexCount,
1134 LPWORD dwIndices,
1135 DWORD dwIndexCount,
1136 DWORD dwFlags)
1138 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1139 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1141 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1142 if (TRACE_ON(ddraw)) {
1143 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1146 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1147 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1149 return DD_OK;
1152 HRESULT WINAPI
1153 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1154 D3DPRIMITIVETYPE d3dptPrimitiveType,
1155 DWORD dwVertexType,
1156 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1157 DWORD dwVertexCount,
1158 DWORD dwFlags)
1160 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1162 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1163 if (TRACE_ON(ddraw)) {
1164 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1166 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1168 return DD_OK;
1171 HRESULT WINAPI
1172 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1173 D3DPRIMITIVETYPE d3dptPrimitiveType,
1174 DWORD dwVertexType,
1175 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1176 DWORD dwVertexCount,
1177 LPWORD lpIndex,
1178 DWORD dwIndexCount,
1179 DWORD dwFlags)
1181 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1183 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1184 if (TRACE_ON(ddraw)) {
1185 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1188 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1190 return DD_OK;
1193 HRESULT WINAPI
1194 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1195 D3DPRIMITIVETYPE d3dptPrimitiveType,
1196 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1197 DWORD dwStartVertex,
1198 DWORD dwNumVertices,
1199 DWORD dwFlags)
1201 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1202 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1203 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1205 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1206 if (TRACE_ON(ddraw)) {
1207 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1210 if (vb_impl->processed == TRUE) {
1211 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1212 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1214 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1215 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1216 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1218 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1219 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1221 } else {
1222 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1223 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1226 return DD_OK;
1229 HRESULT WINAPI
1230 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1231 D3DPRIMITIVETYPE d3dptPrimitiveType,
1232 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1233 DWORD dwStartVertex,
1234 DWORD dwNumVertices,
1235 LPWORD lpwIndices,
1236 DWORD dwIndexCount,
1237 DWORD dwFlags)
1239 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1240 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1241 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1243 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1244 if (TRACE_ON(ddraw)) {
1245 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1248 if (vb_impl->processed == TRUE) {
1249 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1250 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1252 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1253 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1254 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1256 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1257 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1259 } else {
1260 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1261 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1264 return DD_OK;
1267 HRESULT WINAPI
1268 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1269 DWORD dwStage,
1270 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1271 DWORD dwState)
1273 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1274 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1275 GLenum gl_state;
1277 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1279 if (TRACE_ON(ddraw)) {
1280 TRACE(" Stage type is : ");
1281 switch (d3dTexStageStateType) {
1282 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1283 GEN_CASE(D3DTSS_COLOROP);
1284 GEN_CASE(D3DTSS_COLORARG1);
1285 GEN_CASE(D3DTSS_COLORARG2);
1286 GEN_CASE(D3DTSS_ALPHAOP);
1287 GEN_CASE(D3DTSS_ALPHAARG1);
1288 GEN_CASE(D3DTSS_ALPHAARG2);
1289 GEN_CASE(D3DTSS_BUMPENVMAT00);
1290 GEN_CASE(D3DTSS_BUMPENVMAT01);
1291 GEN_CASE(D3DTSS_BUMPENVMAT10);
1292 GEN_CASE(D3DTSS_BUMPENVMAT11);
1293 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1294 GEN_CASE(D3DTSS_ADDRESS);
1295 GEN_CASE(D3DTSS_ADDRESSU);
1296 GEN_CASE(D3DTSS_ADDRESSV);
1297 GEN_CASE(D3DTSS_BORDERCOLOR);
1298 GEN_CASE(D3DTSS_MAGFILTER);
1299 GEN_CASE(D3DTSS_MINFILTER);
1300 GEN_CASE(D3DTSS_MIPFILTER);
1301 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1302 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1303 GEN_CASE(D3DTSS_MAXANISOTROPY);
1304 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1305 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1306 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1307 #undef GEN_CASE
1308 default: DPRINTF("UNKNOWN !!!");
1310 DPRINTF(" => ");
1313 switch (d3dTexStageStateType) {
1314 case D3DTSS_MINFILTER:
1315 switch ((D3DTEXTUREMINFILTER) dwState) {
1316 case D3DTFN_POINT:
1317 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1318 gl_state = GL_NEAREST;
1319 break;
1320 case D3DTFN_LINEAR:
1321 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1322 gl_state = GL_LINEAR;
1323 break;
1324 default:
1325 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1326 gl_state = GL_LINEAR;
1327 break;
1329 glThis->render_state.min = gl_state;
1330 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1331 break;
1333 case D3DTSS_MAGFILTER:
1334 switch ((D3DTEXTUREMAGFILTER) dwState) {
1335 case D3DTFG_POINT:
1336 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1337 gl_state = GL_NEAREST;
1338 break;
1339 case D3DTFG_LINEAR:
1340 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1341 gl_state = GL_LINEAR;
1342 break;
1343 default:
1344 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1345 gl_state = GL_LINEAR;
1346 break;
1348 glThis->render_state.mag = gl_state;
1349 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1350 break;
1352 case D3DTSS_ADDRESS:
1353 case D3DTSS_ADDRESSU:
1354 case D3DTSS_ADDRESSV: {
1355 GLenum arg = GL_REPEAT; /* Default value */
1356 switch ((D3DTEXTUREADDRESS) dwState) {
1357 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1358 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1359 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1360 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1362 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1363 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1365 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1366 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1368 } break;
1370 default:
1371 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1374 This->state_block.texture_stage_state[dwStage][d3dTexStageStateType-1] = dwState;
1376 return DD_OK;
1379 HRESULT WINAPI
1380 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1381 DWORD dwStage,
1382 LPDIRECTDRAWSURFACE7 lpTexture2)
1384 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1385 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1387 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1389 if (This->current_texture[dwStage] != NULL) {
1390 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7));
1393 ENTER_GL();
1394 if (lpTexture2 == NULL) {
1395 This->current_texture[dwStage] = NULL;
1397 TRACE(" disabling 2D texturing.\n");
1398 glBindTexture(GL_TEXTURE_2D, 0);
1399 glDisable(GL_TEXTURE_2D);
1400 } else {
1401 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1403 This->current_texture[dwStage] = tex_impl;
1404 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1406 glEnable(GL_TEXTURE_2D);
1407 gltex_upload_texture(tex_impl);
1409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glThis->render_state.mag);
1410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glThis->render_state.min);
1412 LEAVE_GL();
1414 return DD_OK;
1417 HRESULT WINAPI
1418 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1419 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1421 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1422 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1424 fill_opengl_caps_7(lpD3DHELDevDesc);
1426 TRACE(" returning caps : no dump function yet.\n");
1428 return DD_OK;
1431 HRESULT WINAPI
1432 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1433 LPD3DMATERIAL7 lpMat)
1435 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1436 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1438 if (TRACE_ON(ddraw)) {
1439 TRACE(" material is : \n");
1440 dump_D3DMATERIAL7(lpMat);
1443 This->current_material = *lpMat;
1445 glMaterialfv(GL_FRONT_AND_BACK,
1446 GL_DIFFUSE,
1447 (float *) &(This->current_material.u.diffuse));
1448 glMaterialfv(GL_FRONT_AND_BACK,
1449 GL_AMBIENT,
1450 (float *) &(This->current_material.u1.ambient));
1451 glMaterialfv(GL_FRONT_AND_BACK,
1452 GL_SPECULAR,
1453 (float *) &(This->current_material.u2.specular));
1454 glMaterialfv(GL_FRONT_AND_BACK,
1455 GL_EMISSION,
1456 (float *) &(This->current_material.u3.emissive));
1457 glMaterialf(GL_FRONT_AND_BACK,
1458 GL_SHININESS,
1459 This->current_material.u4.power); /* Not sure about this... */
1461 return DD_OK;
1465 HRESULT WINAPI
1466 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1467 DWORD dwLightIndex,
1468 LPD3DLIGHT7 lpLight)
1470 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1471 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1473 if (TRACE_ON(ddraw)) {
1474 TRACE(" setting light : \n");
1475 dump_D3DLIGHT7(lpLight);
1478 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1479 This->set_lights |= 0x00000001 << dwLightIndex;
1480 This->light_parameters[dwLightIndex] = *lpLight;
1482 switch (lpLight->dltType) {
1483 case D3DLIGHT_DIRECTIONAL: {
1484 float direction[4];
1485 float cut_off = 180.0;
1487 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1488 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1489 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1490 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1492 direction[0] = lpLight->dvDirection.u1.x;
1493 direction[1] = lpLight->dvDirection.u2.y;
1494 direction[2] = lpLight->dvDirection.u3.z;
1495 direction[3] = 0.0;
1496 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1497 } break;
1499 case D3DLIGHT_POINT: {
1500 float position[4];
1501 float cut_off = 180.0;
1503 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1504 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1505 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1506 position[0] = lpLight->dvPosition.u1.x;
1507 position[1] = lpLight->dvPosition.u2.y;
1508 position[2] = lpLight->dvPosition.u3.z;
1509 position[3] = 1.0;
1510 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1511 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1512 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1513 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1514 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1515 } break;
1517 case D3DLIGHT_SPOT: {
1518 float direction[4];
1519 float position[4];
1520 float cut_off = 90.0 * (lpLight->dvPhi / M_PI);
1522 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1523 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1524 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1526 direction[0] = lpLight->dvDirection.u1.x;
1527 direction[1] = lpLight->dvDirection.u2.y;
1528 direction[2] = lpLight->dvDirection.u3.z;
1529 direction[3] = 0.0;
1530 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_DIRECTION, (float *) direction);
1531 position[0] = lpLight->dvPosition.u1.x;
1532 position[1] = lpLight->dvPosition.u2.y;
1533 position[2] = lpLight->dvPosition.u3.z;
1534 position[3] = 1.0;
1535 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1536 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1537 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1538 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1539 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1540 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_EXPONENT, &(lpLight->dvFalloff));
1541 if ((lpLight->dvTheta != 0.0) || (lpLight->dvTheta != lpLight->dvPhi)) {
1542 WARN("dvTheta not fully supported yet !\n");
1544 } break;
1546 default: WARN(" light type not handled yet...\n");
1549 return DD_OK;
1552 HRESULT WINAPI
1553 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1554 DWORD dwLightIndex,
1555 BOOL bEnable)
1557 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1558 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1560 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1562 if (bEnable) {
1563 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1564 /* Set the default parameters.. */
1565 TRACE(" setting default light parameters...\n");
1566 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1568 glEnable(GL_LIGHT0 + dwLightIndex);
1569 } else {
1570 glDisable(GL_LIGHT0 + dwLightIndex);
1573 return DD_OK;
1576 HRESULT WINAPI
1577 GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, CONST D3DVALUE* pPlaneEquation)
1579 ICOM_THIS(IDirect3DDeviceImpl,iface);
1580 GLdouble plane[4];
1582 TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
1584 if (dwIndex>=This->max_clipping_planes) {
1585 return DDERR_INVALIDPARAMS;
1588 TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] );
1590 memcpy( This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4]));
1591 plane[0] = pPlaneEquation[0];
1592 plane[1] = pPlaneEquation[1];
1593 plane[2] = pPlaneEquation[2];
1594 plane[3] = pPlaneEquation[3];
1596 /* XXX: is here also code needed to handle the transformation of the world? */
1597 glClipPlane( GL_CLIP_PLANE0+dwIndex, (const GLdouble*)(&plane) );
1599 return D3D_OK;
1602 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1603 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1604 #else
1605 # define XCAST(fun) (void*)
1606 #endif
1608 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1610 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1611 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1612 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1613 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1614 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1615 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1616 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1617 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1618 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1619 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1620 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1621 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1622 XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1623 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1624 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1625 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1626 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1627 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1628 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1629 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1630 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1631 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1632 XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1633 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1634 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1635 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1636 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1637 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1638 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1639 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1640 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1641 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1642 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1643 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1644 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1645 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1646 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1647 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1648 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1649 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1650 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1651 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1652 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1653 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1654 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1655 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1656 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1657 XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane,
1658 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1659 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1662 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1663 #undef XCAST
1664 #endif
1667 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1668 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1669 #else
1670 # define XCAST(fun) (void*)
1671 #endif
1673 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1675 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1676 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1677 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1678 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1679 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1680 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1681 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1682 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1683 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1684 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1685 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1686 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1687 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1688 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1689 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1690 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1691 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1692 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1693 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1694 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1695 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1696 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1697 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1698 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1699 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1700 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1701 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1702 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1703 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1704 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1705 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1706 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1707 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1708 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1709 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1710 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1711 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1712 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1713 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1714 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1715 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1716 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1717 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1720 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1721 #undef XCAST
1722 #endif
1725 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1726 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1727 #else
1728 # define XCAST(fun) (void*)
1729 #endif
1731 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1733 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1734 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1735 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1736 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1737 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1738 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
1739 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1740 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1741 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1742 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1743 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1744 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1745 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1746 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1747 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1748 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1749 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1750 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1751 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1752 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1753 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1754 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1755 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1756 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1757 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1758 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1759 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1760 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1761 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1762 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1763 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1764 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1765 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1766 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1769 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1770 #undef XCAST
1771 #endif
1774 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1775 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1776 #else
1777 # define XCAST(fun) (void*)
1778 #endif
1780 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1782 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1783 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1784 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1785 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1786 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1787 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1788 XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
1789 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1790 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1791 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1792 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1793 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1794 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1795 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1796 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1797 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1798 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1799 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1800 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1801 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1802 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1803 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1804 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1807 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1808 #undef XCAST
1809 #endif
1811 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1812 DWORD dwCount,
1813 LPD3DRECT lpRects,
1814 DWORD dwFlags,
1815 DWORD dwColor,
1816 D3DVALUE dvZ,
1817 DWORD dwStencil)
1819 GLboolean ztest;
1820 GLfloat old_z_clear_value;
1821 GLbitfield bitfield = 0;
1822 GLint old_stencil_clear_value;
1823 GLfloat old_color_clear_value[4];
1825 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1826 if (TRACE_ON(ddraw)) {
1827 if (dwCount > 0) {
1828 int i;
1829 TRACE(" rectangles : \n");
1830 for (i = 0; i < dwCount; i++) {
1831 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1836 if (dwCount > 1) {
1837 WARN(" Warning, this function only for now clears the whole screen...\n");
1840 /* Clears the screen */
1841 ENTER_GL();
1842 if (dwFlags & D3DCLEAR_ZBUFFER) {
1843 bitfield |= GL_DEPTH_BUFFER_BIT;
1844 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1845 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1846 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1847 glClearDepth(dvZ);
1848 TRACE(" depth value : %f\n", dvZ);
1850 if (dwFlags & D3DCLEAR_STENCIL) {
1851 bitfield |= GL_STENCIL_BUFFER_BIT;
1852 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1853 glClearStencil(dwStencil);
1854 TRACE(" stencil value : %ld\n", dwStencil);
1856 if (dwFlags & D3DCLEAR_TARGET) {
1857 bitfield |= GL_COLOR_BUFFER_BIT;
1858 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1859 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1860 ((dwColor >> 8) & 0xFF) / 255.0,
1861 ((dwColor >> 0) & 0xFF) / 255.0,
1862 ((dwColor >> 24) & 0xFF) / 255.0);
1863 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1866 glClear(bitfield);
1868 if (dwFlags & D3DCLEAR_ZBUFFER) {
1869 glDepthMask(ztest);
1870 glClearDepth(old_z_clear_value);
1872 if (dwFlags & D3DCLEAR_STENCIL) {
1873 bitfield |= GL_STENCIL_BUFFER_BIT;
1874 glClearStencil(old_stencil_clear_value);
1876 if (dwFlags & D3DCLEAR_TARGET) {
1877 bitfield |= GL_COLOR_BUFFER_BIT;
1878 glClearColor(old_color_clear_value[0],
1879 old_color_clear_value[1],
1880 old_color_clear_value[2],
1881 old_color_clear_value[3]);
1884 LEAVE_GL();
1886 return DD_OK;
1889 HRESULT
1890 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1891 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1892 DWORD dwFlags, LPDDBLTFX lpbltfx)
1894 if (dwFlags & DDBLT_COLORFILL) {
1895 /* This is easy to handle for the D3D Device... */
1896 DWORD color = lpbltfx->u5.dwFillColor;
1897 TRACE(" executing D3D Device override.\n");
1898 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1899 return DD_OK;
1901 return DDERR_INVALIDPARAMS;
1904 HRESULT
1905 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1906 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1907 LPRECT rsrc, DWORD trans)
1909 return DDERR_INVALIDPARAMS;
1912 void
1913 d3ddevice_set_ortho(IDirect3DDeviceImpl *This)
1915 GLfloat height, width;
1916 GLfloat trans_mat[16];
1918 width = This->surface->surface_desc.dwWidth;
1919 height = This->surface->surface_desc.dwHeight;
1921 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
1922 to OpenGL screen coordinates (ie the upper left corner is not the same).
1923 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
1924 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
1925 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
1926 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
1927 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
1928 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
1930 glMatrixMode(GL_MODELVIEW);
1931 glLoadIdentity();
1932 glMatrixMode(GL_PROJECTION);
1933 glLoadMatrixf(trans_mat);
1936 void
1937 d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
1938 D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
1940 if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
1941 glMatrixMode(GL_MODELVIEW);
1942 glLoadMatrixf((float *) view_mat);
1943 glMultMatrixf((float *) world_mat);
1945 if ((matrices & PROJMAT_CHANGED) != 0) {
1946 glMatrixMode(GL_PROJECTION);
1947 glLoadMatrixf((float *) proj_mat);
1951 void
1952 d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
1954 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1955 if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
1956 /* This will force an update of the transform state at the next drawing. */
1957 glThis->transform_state = GL_TRANSFORM_NONE;
1961 /* TODO for both these functions :
1962 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1963 by other OpenGL code in D3D
1964 - handle the case where no 'Begin / EndScene' was done between two locks
1965 - handle the rectangles in the unlock too
1966 - handle pitch correctly...
1968 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1970 /* First, check if we need to do anything */
1971 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1972 GLenum buffer_type;
1973 GLenum prev_read;
1974 RECT loc_rect;
1976 ENTER_GL();
1978 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1979 glFlush();
1981 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1982 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1983 /* Application wants to lock the front buffer */
1984 glReadBuffer(GL_FRONT);
1985 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1986 /* Application wants to lock the back buffer */
1987 glReadBuffer(GL_BACK);
1988 } else {
1989 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1992 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1993 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1994 } else {
1995 WARN(" unsupported pixel format.\n");
1996 LEAVE_GL();
1997 return;
1999 if (pRect == NULL) {
2000 loc_rect.top = 0;
2001 loc_rect.left = 0;
2002 loc_rect.bottom = This->surface_desc.dwHeight;
2003 loc_rect.right = This->surface_desc.dwWidth;
2004 } else {
2005 loc_rect = *pRect;
2007 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
2008 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
2009 + loc_rect.top * This->surface_desc.u1.lPitch
2010 + loc_rect.left * GET_BPP(This->surface_desc)));
2011 glReadBuffer(prev_read);
2012 LEAVE_GL();
2016 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
2018 /* First, check if we need to do anything */
2019 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
2020 GLenum buffer_type;
2021 GLenum prev_draw;
2023 ENTER_GL();
2025 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
2027 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
2028 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2029 /* Application wants to lock the front buffer */
2030 glDrawBuffer(GL_FRONT);
2031 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2032 /* Application wants to lock the back buffer */
2033 glDrawBuffer(GL_BACK);
2034 } else {
2035 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
2038 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2039 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2040 } else {
2041 WARN(" unsupported pixel format.\n");
2042 LEAVE_GL();
2043 return;
2045 glRasterPos2f(0.0, 0.0);
2046 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
2047 GL_RGB, buffer_type, This->surface_desc.lpSurface);
2048 glDrawBuffer(prev_draw);
2050 LEAVE_GL();
2054 HRESULT
2055 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
2057 IDirect3DDeviceImpl *object;
2058 IDirect3DDeviceGLImpl *gl_object;
2059 IDirectDrawSurfaceImpl *surf;
2060 HDC device_context;
2061 XVisualInfo *vis;
2062 int num;
2063 XVisualInfo template;
2064 GLenum buffer = GL_FRONT;
2065 int light;
2066 GLint max_clipping_planes = 0;
2068 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
2069 if (object == NULL) return DDERR_OUTOFMEMORY;
2071 gl_object = (IDirect3DDeviceGLImpl *) object;
2073 object->ref = 1;
2074 object->d3d = d3d;
2075 object->surface = surface;
2076 object->set_context = set_context;
2077 object->clear = d3ddevice_clear;
2078 object->set_matrices = d3ddevice_set_matrices;
2079 object->matrices_updated = d3ddevice_matrices_updated;
2081 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
2083 device_context = GetDC(surface->ddraw_owner->window);
2084 gl_object->display = get_display(device_context);
2085 gl_object->drawable = get_drawable(device_context);
2086 ReleaseDC(surface->ddraw_owner->window,device_context);
2088 ENTER_GL();
2089 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2090 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2091 if (vis == NULL) {
2092 HeapFree(GetProcessHeap(), 0, object);
2093 ERR("No visual found !\n");
2094 LEAVE_GL();
2095 return DDERR_INVALIDPARAMS;
2096 } else {
2097 TRACE(" visual found\n");
2100 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2101 NULL, GL_TRUE);
2103 if (gl_object->gl_context == NULL) {
2104 HeapFree(GetProcessHeap(), 0, object);
2105 ERR("Error in context creation !\n");
2106 LEAVE_GL();
2107 return DDERR_INVALIDPARAMS;
2108 } else {
2109 TRACE(" context created (%p)\n", gl_object->gl_context);
2112 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2113 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2114 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2115 surf->aux_ctx = (LPVOID) gl_object->display;
2116 surf->aux_data = (LPVOID) gl_object->drawable;
2117 surf->aux_flip = opengl_flip;
2118 buffer = GL_BACK;
2119 break;
2122 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2123 if (surf == NULL) {
2124 TRACE(" no double buffering : drawing on the front buffer\n");
2125 buffer = GL_FRONT;
2128 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2129 for (; surf != NULL; surf = surf->next_attached) {
2130 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2131 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2132 /* Override the Lock / Unlock function for all these surfaces */
2133 surf->lock_update = d3ddevice_lock_update;
2134 surf->unlock_update = d3ddevice_unlock_update;
2135 /* And install also the blt / bltfast overrides */
2136 surf->aux_blt = d3ddevice_blt;
2137 surf->aux_bltfast = d3ddevice_bltfast;
2139 surf->d3ddevice = object;
2142 /* FIXME: These 4 statements are kept for compatibility but should be removed as soon
2143 as they are correctly handled */
2144 gl_object->render_state.fog_on = FALSE;
2145 gl_object->render_state.stencil_enable = FALSE;
2146 gl_object->render_state.lighting_enable = FALSE;
2147 gl_object->render_state.specular_enable = FALSE;
2149 /* Set the various light parameters */
2150 for (light = 0; light < MAX_LIGHTS; light++) {
2151 /* Only set the fields that are not zero-created */
2152 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2153 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2154 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2155 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2156 object->light_parameters[light].dvDirection.u3.z = 1.0;
2159 /* Allocate memory for the matrices */
2160 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2161 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2162 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2163 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2164 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2165 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2167 /* allocate the clipping planes */
2168 glGetIntegerv(GL_MAX_CLIP_PLANES,&max_clipping_planes);
2169 if (max_clipping_planes>32) {
2170 object->max_clipping_planes=32;
2171 } else {
2172 object->max_clipping_planes = max_clipping_planes;
2174 TRACE(" capable of %d clipping planes\n", (int)object->max_clipping_planes );
2175 object->clipping_planes = (d3d7clippingplane*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane));
2177 /* Initialisation */
2178 TRACE(" setting current context\n");
2179 LEAVE_GL();
2180 object->set_context(object);
2181 ENTER_GL();
2182 TRACE(" current context set\n");
2184 glClearColor(0.0, 0.0, 0.0, 0.0);
2185 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2186 glDrawBuffer(buffer);
2187 glReadBuffer(buffer);
2188 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2189 LEAVE_GL();
2191 /* fill_device_capabilities(d3d->ddraw); */
2193 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2194 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2195 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2196 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2198 *obj = object;
2200 TRACE(" creating implementation at %p.\n", *obj);
2202 /* And finally warn D3D that this device is now present */
2203 object->d3d->added_device(object->d3d, object);
2205 /* FIXME: Should handle other versions than just 7 */
2206 InitDefaultStateBlock(&object->state_block,7);
2207 /* Apply default render state values */
2208 apply_render_state(gl_object, &object->state_block);
2209 /* FIXME: do something similar for ligh_state and texture_stage_state */
2211 return DD_OK;