- rewrote a little bit the state magagement to remove the RenderState
[wine/multimedia.git] / dlls / ddraw / d3ddevice / mesa.c
blob0f3592057643a5e76e629e5db52123c1101da99b
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 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
28 #include "windef.h"
29 #include "winerror.h"
30 #include "objbase.h"
31 #include "ddraw.h"
32 #include "d3d.h"
33 #include "wine/debug.h"
35 #include "mesa_private.h"
36 #include "main.h"
38 #include "x11drv.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
42 /* They are non-static as they are used by Direct3D in the creation function */
43 const GUID IID_D3DDEVICE_OpenGL = {
44 0x31416d44,
45 0x86ae,
46 0x11d2,
47 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
50 #ifndef HAVE_GLEXT_PROTOTYPES
51 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
52 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
53 GLsizei width, GLenum format, GLenum type,
54 const GLvoid *table);
55 #endif
57 const float id_mat[16] = {
58 1.0, 0.0, 0.0, 0.0,
59 0.0, 1.0, 0.0, 0.0,
60 0.0, 0.0, 1.0, 0.0,
61 0.0, 0.0, 0.0, 1.0
64 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
65 D3DPRIMITIVETYPE d3dptPrimitiveType,
66 DWORD d3dvtVertexType,
67 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
68 DWORD dwStartVertex,
69 DWORD dwVertexCount,
70 LPWORD dwIndices,
71 DWORD dwIndexCount,
72 DWORD dwFlags) ;
74 /* retrieve the X display to use on a given DC */
75 inline static Display *get_display( HDC hdc )
77 Display *display;
78 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
80 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
81 sizeof(display), (LPSTR)&display )) display = NULL;
83 return display;
87 /* retrieve the X drawable to use on a given DC */
88 inline static Drawable get_drawable( HDC hdc )
90 Drawable drawable;
91 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
93 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
94 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
96 return drawable;
100 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
102 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
103 ENTER_GL();
104 glXSwapBuffers((Display*)display,(Drawable)drawable);
105 LEAVE_GL();
106 return TRUE;
110 /*******************************************************************************
111 * OpenGL static functions
113 static void set_context(IDirect3DDeviceImpl* This)
115 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
117 ENTER_GL();
118 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
119 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
120 ERR("Error in setting current context (context %p drawable %ld)!\n",
121 glThis->gl_context, glThis->drawable);
123 LEAVE_GL();
126 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
128 pc->dwSize = sizeof(*pc);
129 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
130 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
131 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
132 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
133 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
134 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
135 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
136 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
137 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
138 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
139 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
140 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
141 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
142 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
143 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
144 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
145 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
146 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
147 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
148 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
149 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
150 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
151 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
152 pc->dwStippleWidth = 32;
153 pc->dwStippleHeight = 32;
156 static void fill_opengl_caps(D3DDEVICEDESC *d1)
158 /* GLint maxlight; */
160 d1->dwSize = sizeof(*d1);
161 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
162 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
163 d1->dcmColorModel = D3DCOLOR_RGB;
164 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
165 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
166 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
167 /* D3D 7 capabilities */
168 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
169 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
170 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
171 d1->bClipping = TRUE;
172 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
173 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
174 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
175 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
176 fill_opengl_primcaps(&(d1->dpcLineCaps));
177 fill_opengl_primcaps(&(d1->dpcTriCaps));
178 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
179 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
180 d1->dwMaxBufferSize = 0;
181 d1->dwMaxVertexCount = 65536;
182 d1->dwMinTextureWidth = 1;
183 d1->dwMinTextureHeight = 1;
184 d1->dwMaxTextureWidth = 1024;
185 d1->dwMaxTextureHeight = 1024;
186 d1->dwMinStippleWidth = 1;
187 d1->dwMinStippleHeight = 1;
188 d1->dwMaxStippleWidth = 32;
189 d1->dwMaxStippleHeight = 32;
190 d1->dwMaxTextureRepeat = 16;
191 d1->dwMaxTextureAspectRatio = 1024;
192 d1->dwMaxAnisotropy = 0;
193 d1->dvGuardBandLeft = 0.0;
194 d1->dvGuardBandRight = 0.0;
195 d1->dvGuardBandTop = 0.0;
196 d1->dvGuardBandBottom = 0.0;
197 d1->dvExtentsAdjust = 0.0;
198 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
199 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
200 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
201 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
202 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
203 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
206 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
208 D3DDEVICEDESC d1;
210 /* Copy first D3D1/2/3 capabilities */
211 fill_opengl_caps(&d1);
213 /* And fill the D3D7 one with it */
214 d->dwDevCaps = d1.dwDevCaps;
215 d->dpcLineCaps = d1.dpcLineCaps;
216 d->dpcTriCaps = d1.dpcTriCaps;
217 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
218 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
219 d->dwMinTextureWidth = d1.dwMinTextureWidth;
220 d->dwMinTextureHeight = d1.dwMinTextureHeight;
221 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
222 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
223 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
224 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
225 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
226 d->dvGuardBandLeft = d1.dvGuardBandLeft;
227 d->dvGuardBandTop = d1.dvGuardBandTop;
228 d->dvGuardBandRight = d1.dvGuardBandRight;
229 d->dvGuardBandBottom = d1.dvGuardBandBottom;
230 d->dvExtentsAdjust = d1.dvExtentsAdjust;
231 d->dwStencilCaps = d1.dwStencilCaps;
232 d->dwFVFCaps = d1.dwFVFCaps;
233 d->dwTextureOpCaps = d1.dwTextureOpCaps;
234 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
235 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
236 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
237 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
238 d->deviceGUID = IID_IDirect3DTnLHalDevice;
239 d->wMaxUserClipPlanes = 1;
240 d->wMaxVertexBlendMatrices = 0;
241 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
242 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
243 d->dwReserved1 = 0;
244 d->dwReserved2 = 0;
245 d->dwReserved3 = 0;
246 d->dwReserved4 = 0;
249 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
250 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
252 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
253 const char *ext_string;
254 Mesa_DeviceCapabilities *devcap;
256 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
257 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
259 ENTER_GL();
260 ext_string = glGetString(GL_EXTENSIONS);
261 /* Query for the ColorTable Extension */
262 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
263 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
264 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
265 } else {
266 TRACE("Color table extension not found.\n");
268 LEAVE_GL();
270 #endif
274 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
276 D3DDEVICEDESC dref, d1, d2;
277 HRESULT ret_value;
279 fill_opengl_caps(&dref);
281 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
282 d1 = dref;
283 d2 = dref;
284 ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
285 if (ret_value != D3DENUMRET_OK)
286 return ret_value;
288 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
289 d1 = dref;
290 d2 = dref;
291 ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
292 if (ret_value != D3DENUMRET_OK)
293 return ret_value;
295 return D3DENUMRET_OK;
298 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
300 D3DDEVICEDESC7 ddesc;
302 fill_opengl_caps_7(&ddesc);
304 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
306 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
309 ULONG WINAPI
310 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
312 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
313 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
315 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
316 if (!--(This->ref)) {
317 int i;
318 /* Release texture associated with the device */
319 for (i = 0; i < MAX_TEXTURES; i++)
320 if (This->current_texture[i] != NULL)
321 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[i], IDirectDrawSurface7));
323 /* And warn the D3D object that this device is no longer active... */
324 This->d3d->removed_device(This->d3d, This);
326 HeapFree(GetProcessHeap(), 0, This->world_mat);
327 HeapFree(GetProcessHeap(), 0, This->view_mat);
328 HeapFree(GetProcessHeap(), 0, This->proj_mat);
330 ENTER_GL();
331 glXDestroyContext(glThis->display, glThis->gl_context);
332 LEAVE_GL();
333 HeapFree(GetProcessHeap(), 0, This->clipping_planes);
335 HeapFree(GetProcessHeap(), 0, This);
336 return 0;
338 return This->ref;
341 HRESULT WINAPI
342 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
343 LPD3DDEVICEDESC lpD3DHWDevDesc,
344 LPD3DDEVICEDESC lpD3DHELDevDesc)
346 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
347 D3DDEVICEDESC desc;
348 DWORD dwSize;
350 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
352 fill_opengl_caps(&desc);
353 dwSize = lpD3DHWDevDesc->dwSize;
354 memset(lpD3DHWDevDesc, 0, dwSize);
355 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
357 dwSize = lpD3DHELDevDesc->dwSize;
358 memset(lpD3DHELDevDesc, 0, dwSize);
359 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
361 TRACE(" returning caps : (no dump function yet)\n");
363 return DD_OK;
366 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
367 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
368 LPVOID context)
370 DDSURFACEDESC sdesc;
371 LPDDPIXELFORMAT pformat;
373 /* Do the texture enumeration */
374 sdesc.dwSize = sizeof(DDSURFACEDESC);
375 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
376 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
377 pformat = &(sdesc.ddpfPixelFormat);
378 pformat->dwSize = sizeof(DDPIXELFORMAT);
379 pformat->dwFourCC = 0;
381 TRACE("Enumerating GL_RGBA unpacked (32)\n");
382 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
383 pformat->u1.dwRGBBitCount = 32;
384 pformat->u2.dwRBitMask = 0xFF000000;
385 pformat->u3.dwGBitMask = 0x00FF0000;
386 pformat->u4.dwBBitMask = 0x0000FF00;
387 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
388 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
389 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
391 TRACE("Enumerating GL_RGB unpacked (24)\n");
392 pformat->dwFlags = DDPF_RGB;
393 pformat->u1.dwRGBBitCount = 24;
394 pformat->u2.dwRBitMask = 0x00FF0000;
395 pformat->u3.dwGBitMask = 0x0000FF00;
396 pformat->u4.dwBBitMask = 0x000000FF;
397 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
398 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
399 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
401 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
402 pformat->dwFlags = DDPF_RGB;
403 pformat->u1.dwRGBBitCount = 16;
404 pformat->u2.dwRBitMask = 0x0000F800;
405 pformat->u3.dwGBitMask = 0x000007E0;
406 pformat->u4.dwBBitMask = 0x0000001F;
407 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
408 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
409 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
411 /* Note : even if this is an 'emulated' texture format, it needs to be first
412 as some dumb applications seem to rely on that. */
413 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n");
414 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
415 pformat->u1.dwRGBBitCount = 16;
416 pformat->u2.dwRBitMask = 0x00007C00;
417 pformat->u3.dwGBitMask = 0x000003E0;
418 pformat->u4.dwBBitMask = 0x0000001F;
419 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
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_4_4_4_4 (ARGB) (16)\n");
424 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
425 pformat->u1.dwRGBBitCount = 16;
426 pformat->u2.dwRBitMask = 0x00000F00;
427 pformat->u3.dwGBitMask = 0x000000F0;
428 pformat->u4.dwBBitMask = 0x0000000F;
429 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
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 #if 0
434 /* This is a compromise : some games choose the first 16 bit texture format with alpha they
435 find enumerated, others the last one. And both want to have the ARGB one.
437 So basically, forget our OpenGL roots and do not even enumerate our RGBA ones.
439 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
440 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
441 pformat->u1.dwRGBBitCount = 16;
442 pformat->u2.dwRBitMask = 0x0000F000;
443 pformat->u3.dwGBitMask = 0x00000F00;
444 pformat->u4.dwBBitMask = 0x000000F0;
445 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
446 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
447 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
449 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
450 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
451 pformat->u1.dwRGBBitCount = 16;
452 pformat->u2.dwRBitMask = 0x0000F800;
453 pformat->u3.dwGBitMask = 0x000007C0;
454 pformat->u4.dwBBitMask = 0x0000003E;
455 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
456 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
457 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
458 #endif
460 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
461 pformat->dwFlags = DDPF_RGB;
462 pformat->u1.dwRGBBitCount = 8;
463 pformat->u2.dwRBitMask = 0x000000E0;
464 pformat->u3.dwGBitMask = 0x0000001C;
465 pformat->u4.dwBBitMask = 0x00000003;
466 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
467 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
468 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
470 TRACE("Enumerating Paletted (8)\n");
471 pformat->dwFlags = DDPF_PALETTEINDEXED8;
472 pformat->u1.dwRGBBitCount = 8;
473 pformat->u2.dwRBitMask = 0x00000000;
474 pformat->u3.dwGBitMask = 0x00000000;
475 pformat->u4.dwBBitMask = 0x00000000;
476 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
477 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
478 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
480 TRACE("End of enumeration\n");
481 return DD_OK;
485 HRESULT
486 d3ddevice_find(IDirect3DImpl *d3d,
487 LPD3DFINDDEVICESEARCH lpD3DDFS,
488 LPD3DFINDDEVICERESULT lplpD3DDevice)
490 D3DDEVICEDESC desc;
492 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
493 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
494 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
495 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
497 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
498 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
499 if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
500 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0) &&
501 (IsEqualGUID(&IID_IDirect3DRefDevice, &(lpD3DDFS->guid)) == 0)) {
502 TRACE(" no match for this GUID.\n");
503 return DDERR_INVALIDPARAMS;
507 /* Now return our own GUID */
508 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
509 fill_opengl_caps(&desc);
510 lplpD3DDevice->ddHwDesc = desc;
511 lplpD3DDevice->ddSwDesc = desc;
513 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
515 return D3D_OK;
518 HRESULT WINAPI
519 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
520 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
521 LPVOID lpArg)
523 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
524 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
525 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
528 HRESULT WINAPI
529 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
530 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
531 LPVOID lpArg)
533 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
534 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
535 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
538 HRESULT WINAPI
539 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
540 D3DRENDERSTATETYPE dwRenderStateType,
541 DWORD dwRenderState)
543 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
544 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
546 /* Call the render state functions */
547 store_render_state(This, dwRenderStateType, dwRenderState, &This->state_block);
548 set_render_state(This, dwRenderStateType, &This->state_block);
550 return DD_OK;
553 HRESULT WINAPI
554 GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
555 D3DRENDERSTATETYPE dwRenderStateType,
556 LPDWORD lpdwRenderState)
558 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
559 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState);
561 /* Call the render state functions */
562 get_render_state(This, dwRenderStateType, lpdwRenderState, &This->state_block);
564 TRACE(" - asked for rendering state : %s, returning value %08lx.\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
566 return DD_OK;
569 HRESULT WINAPI
570 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
571 D3DLIGHTSTATETYPE dwLightStateType,
572 DWORD dwLightState)
574 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
576 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
578 switch (dwLightStateType) {
579 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
580 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
582 if (mat != NULL) {
583 ENTER_GL();
584 mat->activate(mat);
585 LEAVE_GL();
586 } else {
587 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
589 } break;
591 case D3DLIGHTSTATE_AMBIENT: /* 2 */
592 IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
593 D3DRENDERSTATE_AMBIENT,
594 dwLightState);
595 break;
597 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
598 UNSUP(COLORMODEL);
599 UNSUP(FOGMODE);
600 UNSUP(FOGSTART);
601 UNSUP(FOGEND);
602 UNSUP(FOGDENSITY);
603 UNSUP(COLORVERTEX);
604 #undef UNSUP
606 default:
607 TRACE("Unexpected Light State Type\n");
608 return DDERR_INVALIDPARAMS;
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 (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1] == 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 == TRUE)
682 glDisable(GL_LIGHTING);
683 else if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)
684 glEnable(GL_LIGHTING);
686 /* Handle the code for pre-vertex material properties */
687 if (vertex_transformed == FALSE) {
688 if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) {
689 if ((This->state_block.render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
690 (This->state_block.render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
691 (This->state_block.render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
692 (This->state_block.render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] != 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(STATEBLOCK *sb, DWORD *color) {
828 if ((sb->render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] == TRUE) ||
829 (sb->render_state[D3DRENDERSTATE_ALPHABLENDENABLE - 1] == TRUE)) {
830 glColor4ub((*color >> 16) & 0xFF,
831 (*color >> 8) & 0xFF,
832 (*color >> 0) & 0xFF,
833 (*color >> 24) & 0xFF);
834 } else {
835 glColor3ub((*color >> 16) & 0xFF,
836 (*color >> 8) & 0xFF,
837 (*color >> 0) & 0xFF);
841 inline static void handle_specular_base(STATEBLOCK *sb, DWORD *color) {
842 glColor4ub((*color >> 16) & 0xFF,
843 (*color >> 8) & 0xFF,
844 (*color >> 0) & 0xFF,
845 (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
848 inline static void handle_diffuse(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
849 if ((lighted == FALSE) &&
850 (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)) {
851 if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
852 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
853 handle_diffuse_base(sb, color);
855 if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
856 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
857 handle_diffuse_base(sb, color);
859 if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR1) &&
860 (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
861 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
862 handle_diffuse_base(sb, color);
864 if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
865 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
866 handle_diffuse_base(sb, color);
868 } else {
869 handle_diffuse_base(sb, color);
873 inline static void handle_specular(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
874 if ((lighted == FALSE) &&
875 (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)) {
876 if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
877 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
878 handle_specular_base(sb, color);
880 if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
881 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
882 handle_specular_base(sb, color);
884 if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR2) &&
885 (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
886 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
887 handle_specular_base(sb, color);
889 if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
890 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
891 handle_specular_base(sb, color);
894 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
897 inline static void handle_diffuse_and_specular(STATEBLOCK *sb, DWORD *color_d, DWORD *color_s, BOOLEAN lighted) {
898 if (lighted == TRUE) {
899 if (sb->render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE) {
900 /* Special case where the specular value is used to do fogging. TODO */
902 if (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE) {
903 /* Standard specular value in transformed mode. TODO */
905 handle_diffuse_base(sb, color_d);
906 } else {
907 if (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) {
908 handle_diffuse(sb, color_d, FALSE);
909 handle_specular(sb, color_s, FALSE);
910 } else {
911 /* In that case, only put the diffuse color... */
912 handle_diffuse_base(sb, color_d);
917 inline static void handle_texture(D3DVALUE *coords) {
918 glTexCoord2fv(coords);
920 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
921 /* For the moment, draw only the first texture.. */
922 if (tex_index == 0) glTexCoord2fv(coords);
925 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
926 D3DPRIMITIVETYPE d3dptPrimitiveType,
927 DWORD d3dvtVertexType,
928 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
929 DWORD dwStartVertex,
930 DWORD dwVertexCount,
931 LPWORD dwIndices,
932 DWORD dwIndexCount,
933 DWORD dwFlags)
935 BOOLEAN vertex_lighted = (d3dvtVertexType & D3DFVF_NORMAL) == 0;
937 if (TRACE_ON(ddraw)) {
938 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
941 ENTER_GL();
942 draw_primitive_handle_GL_state(This,
943 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
944 vertex_lighted);
945 draw_primitive_start_GL(d3dptPrimitiveType);
947 /* Some fast paths first before the generic case.... */
948 if (d3dvtVertexType == D3DFVF_VERTEX) {
949 int index;
951 for (index = 0; index < dwIndexCount; index++) {
952 int i = (dwIndices == NULL) ? index : dwIndices[index];
953 D3DVALUE *normal =
954 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
955 D3DVALUE *tex_coord =
956 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
957 D3DVALUE *position =
958 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
960 handle_normal(normal);
961 handle_texture(tex_coord);
962 handle_xyz(position);
964 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
965 position[0], position[1], position[2],
966 normal[0], normal[1], normal[2],
967 tex_coord[0], tex_coord[1]);
969 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
970 int index;
972 for (index = 0; index < dwIndexCount; index++) {
973 int i = (dwIndices == NULL) ? index : dwIndices[index];
974 DWORD *color_d =
975 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
976 DWORD *color_s =
977 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
978 D3DVALUE *tex_coord =
979 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
980 D3DVALUE *position =
981 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
983 handle_diffuse_and_specular(&(This->state_block), color_d, color_s, TRUE);
984 handle_texture(tex_coord);
985 handle_xyzrhw(position);
987 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
988 position[0], position[1], position[2], position[3],
989 (*color_d >> 16) & 0xFF,
990 (*color_d >> 8) & 0xFF,
991 (*color_d >> 0) & 0xFF,
992 (*color_d >> 24) & 0xFF,
993 (*color_s >> 16) & 0xFF,
994 (*color_s >> 8) & 0xFF,
995 (*color_s >> 0) & 0xFF,
996 (*color_s >> 24) & 0xFF,
997 tex_coord[0], tex_coord[1]);
999 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1000 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1001 /* This is the 'slow path' but that should support all possible vertex formats out there...
1002 Note that people should write a fast path for all vertex formats out there...
1004 int index;
1005 for (index = 0; index < dwIndexCount; index++) {
1006 int i = (dwIndices == NULL) ? index : dwIndices[index];
1008 if (d3dvtVertexType & D3DFVF_NORMAL) {
1009 D3DVALUE *normal =
1010 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1011 handle_normal(normal);
1013 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1014 DWORD *color_d =
1015 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1016 DWORD *color_s =
1017 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1018 handle_diffuse_and_specular(&(This->state_block), color_d, color_s, vertex_lighted);
1019 } else {
1020 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1021 DWORD *color_s =
1022 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1023 handle_specular(&(This->state_block), color_s, vertex_lighted);
1024 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1025 DWORD *color_d =
1026 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1027 handle_diffuse(&(This->state_block), color_d, vertex_lighted);
1031 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1032 /* Special case for single texture... */
1033 D3DVALUE *tex_coord =
1034 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1035 handle_texture(tex_coord);
1036 } else {
1037 int tex_index;
1038 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1039 D3DVALUE *tex_coord =
1040 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1041 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1042 handle_textures(tex_coord, tex_index);
1045 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1046 D3DVALUE *position =
1047 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1048 handle_xyz(position);
1049 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1050 D3DVALUE *position =
1051 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1052 handle_xyzrhw(position);
1055 if (TRACE_ON(ddraw)) {
1056 int tex_index;
1058 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1059 D3DVALUE *position =
1060 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1061 TRACE(" %f %f %f", position[0], position[1], position[2]);
1062 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1063 D3DVALUE *position =
1064 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1065 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1067 if (d3dvtVertexType & D3DFVF_NORMAL) {
1068 D3DVALUE *normal =
1069 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1070 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1072 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1073 DWORD *color_d =
1074 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1075 DPRINTF(" / %02lx %02lx %02lx %02lx",
1076 (*color_d >> 16) & 0xFF,
1077 (*color_d >> 8) & 0xFF,
1078 (*color_d >> 0) & 0xFF,
1079 (*color_d >> 24) & 0xFF);
1081 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1082 DWORD *color_s =
1083 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1084 DPRINTF(" / %02lx %02lx %02lx %02lx",
1085 (*color_s >> 16) & 0xFF,
1086 (*color_s >> 8) & 0xFF,
1087 (*color_s >> 0) & 0xFF,
1088 (*color_s >> 24) & 0xFF);
1090 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1091 D3DVALUE *tex_coord =
1092 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1093 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1094 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1096 DPRINTF("\n");
1099 } else {
1100 ERR(" matrix weighting not handled yet....\n");
1103 glEnd();
1105 /* Whatever the case, disable the color material stuff */
1106 glDisable(GL_COLOR_MATERIAL);
1108 LEAVE_GL();
1109 TRACE("End\n");
1112 HRESULT WINAPI
1113 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1114 D3DPRIMITIVETYPE d3dptPrimitiveType,
1115 DWORD d3dvtVertexType,
1116 LPVOID lpvVertices,
1117 DWORD dwVertexCount,
1118 DWORD dwFlags)
1120 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1121 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1123 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1124 if (TRACE_ON(ddraw)) {
1125 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1128 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1129 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1131 return DD_OK;
1134 HRESULT WINAPI
1135 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1136 D3DPRIMITIVETYPE d3dptPrimitiveType,
1137 DWORD d3dvtVertexType,
1138 LPVOID lpvVertices,
1139 DWORD dwVertexCount,
1140 LPWORD dwIndices,
1141 DWORD dwIndexCount,
1142 DWORD dwFlags)
1144 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1145 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1147 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1148 if (TRACE_ON(ddraw)) {
1149 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1152 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1153 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1155 return DD_OK;
1158 HRESULT WINAPI
1159 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1160 D3DPRIMITIVETYPE d3dptPrimitiveType,
1161 DWORD dwVertexType,
1162 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1163 DWORD dwVertexCount,
1164 DWORD dwFlags)
1166 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1168 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1169 if (TRACE_ON(ddraw)) {
1170 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1172 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1174 return DD_OK;
1177 HRESULT WINAPI
1178 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1179 D3DPRIMITIVETYPE d3dptPrimitiveType,
1180 DWORD dwVertexType,
1181 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1182 DWORD dwVertexCount,
1183 LPWORD lpIndex,
1184 DWORD dwIndexCount,
1185 DWORD dwFlags)
1187 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1189 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1190 if (TRACE_ON(ddraw)) {
1191 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1194 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1196 return DD_OK;
1199 HRESULT WINAPI
1200 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1201 D3DPRIMITIVETYPE d3dptPrimitiveType,
1202 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1203 DWORD dwStartVertex,
1204 DWORD dwNumVertices,
1205 DWORD dwFlags)
1207 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1208 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1209 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1211 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1212 if (TRACE_ON(ddraw)) {
1213 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1216 if (vb_impl->processed == TRUE) {
1217 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1218 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1220 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1221 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1222 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1224 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1225 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1227 } else {
1228 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1229 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1232 return DD_OK;
1235 HRESULT WINAPI
1236 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1237 D3DPRIMITIVETYPE d3dptPrimitiveType,
1238 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1239 DWORD dwStartVertex,
1240 DWORD dwNumVertices,
1241 LPWORD lpwIndices,
1242 DWORD dwIndexCount,
1243 DWORD dwFlags)
1245 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1246 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1247 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1249 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1250 if (TRACE_ON(ddraw)) {
1251 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1254 if (vb_impl->processed == TRUE) {
1255 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1256 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1258 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1259 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1260 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1262 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1263 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1265 } else {
1266 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1267 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1270 return DD_OK;
1273 static GLenum
1274 convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwState)
1276 GLenum gl_state;
1278 switch (dwState) {
1279 case D3DTFN_POINT:
1280 gl_state = GL_NEAREST;
1281 break;
1282 case D3DTFN_LINEAR:
1283 gl_state = GL_LINEAR;
1284 break;
1285 default:
1286 gl_state = GL_LINEAR;
1287 break;
1289 return gl_state;
1292 static GLenum
1293 convert_mag_filter_to_GL(D3DTEXTUREMAGFILTER dwState)
1295 GLenum gl_state;
1297 switch (dwState) {
1298 case D3DTFG_POINT:
1299 gl_state = GL_NEAREST;
1300 break;
1301 case D3DTFG_LINEAR:
1302 gl_state = GL_LINEAR;
1303 break;
1304 default:
1305 gl_state = GL_LINEAR;
1306 break;
1308 return gl_state;
1311 HRESULT WINAPI
1312 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1313 DWORD dwStage,
1314 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1315 DWORD dwState)
1317 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1319 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1321 if (dwStage > 0) return DD_OK; /* We nothing in this case for now */
1323 if (TRACE_ON(ddraw)) {
1324 TRACE(" Stage type is : ");
1325 switch (d3dTexStageStateType) {
1326 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1327 GEN_CASE(D3DTSS_COLOROP);
1328 GEN_CASE(D3DTSS_COLORARG1);
1329 GEN_CASE(D3DTSS_COLORARG2);
1330 GEN_CASE(D3DTSS_ALPHAOP);
1331 GEN_CASE(D3DTSS_ALPHAARG1);
1332 GEN_CASE(D3DTSS_ALPHAARG2);
1333 GEN_CASE(D3DTSS_BUMPENVMAT00);
1334 GEN_CASE(D3DTSS_BUMPENVMAT01);
1335 GEN_CASE(D3DTSS_BUMPENVMAT10);
1336 GEN_CASE(D3DTSS_BUMPENVMAT11);
1337 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1338 GEN_CASE(D3DTSS_ADDRESS);
1339 GEN_CASE(D3DTSS_ADDRESSU);
1340 GEN_CASE(D3DTSS_ADDRESSV);
1341 GEN_CASE(D3DTSS_BORDERCOLOR);
1342 GEN_CASE(D3DTSS_MAGFILTER);
1343 GEN_CASE(D3DTSS_MINFILTER);
1344 GEN_CASE(D3DTSS_MIPFILTER);
1345 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1346 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1347 GEN_CASE(D3DTSS_MAXANISOTROPY);
1348 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1349 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1350 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1351 #undef GEN_CASE
1352 default: DPRINTF("UNKNOWN !!!");
1354 DPRINTF(" => ");
1357 switch (d3dTexStageStateType) {
1358 case D3DTSS_MINFILTER:
1359 if (TRACE_ON(ddraw)) {
1360 switch ((D3DTEXTUREMINFILTER) dwState) {
1361 case D3DTFN_POINT: DPRINTF("D3DTFN_POINT\n"); break;
1362 case D3DTFN_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
1363 default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
1366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert_min_filter_to_GL(dwState));
1367 break;
1369 case D3DTSS_MAGFILTER:
1370 if (TRACE_ON(ddraw)) {
1371 switch ((D3DTEXTUREMAGFILTER) dwState) {
1372 case D3DTFG_POINT: DPRINTF("D3DTFN_POINT\n"); break;
1373 case D3DTFG_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
1374 default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
1377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert_mag_filter_to_GL(dwState));
1378 break;
1380 case D3DTSS_ADDRESS:
1381 case D3DTSS_ADDRESSU:
1382 case D3DTSS_ADDRESSV: {
1383 GLenum arg = GL_REPEAT; /* Default value */
1384 switch ((D3DTEXTUREADDRESS) dwState) {
1385 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1386 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1387 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1388 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1390 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1391 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1393 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1394 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1395 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1396 } break;
1398 default:
1399 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1402 This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState;
1403 /* Some special cases when one state modifies more than one... */
1404 if (d3dTexStageStateType == D3DTSS_ADDRESS) {
1405 This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState;
1406 This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState;
1409 return DD_OK;
1412 HRESULT WINAPI
1413 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1414 DWORD dwStage,
1415 LPDIRECTDRAWSURFACE7 lpTexture2)
1417 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1419 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1421 if (dwStage > 0) return DD_OK;
1423 if (This->current_texture[dwStage] != NULL) {
1424 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7));
1427 ENTER_GL();
1428 if (lpTexture2 == NULL) {
1429 This->current_texture[dwStage] = NULL;
1431 TRACE(" disabling 2D texturing.\n");
1432 glBindTexture(GL_TEXTURE_2D, 0);
1433 glDisable(GL_TEXTURE_2D);
1434 } else {
1435 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1437 This->current_texture[dwStage] = tex_impl;
1438 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1440 glEnable(GL_TEXTURE_2D);
1441 gltex_upload_texture(tex_impl);
1443 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1444 convert_mag_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MAGFILTER - 1]));
1445 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1446 convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1]));
1448 LEAVE_GL();
1450 return DD_OK;
1453 HRESULT WINAPI
1454 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1455 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1457 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1458 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1460 fill_opengl_caps_7(lpD3DHELDevDesc);
1462 TRACE(" returning caps : no dump function yet.\n");
1464 return DD_OK;
1467 HRESULT WINAPI
1468 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1469 LPD3DMATERIAL7 lpMat)
1471 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1472 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1474 if (TRACE_ON(ddraw)) {
1475 TRACE(" material is : \n");
1476 dump_D3DMATERIAL7(lpMat);
1479 This->current_material = *lpMat;
1481 glMaterialfv(GL_FRONT_AND_BACK,
1482 GL_DIFFUSE,
1483 (float *) &(This->current_material.u.diffuse));
1484 glMaterialfv(GL_FRONT_AND_BACK,
1485 GL_AMBIENT,
1486 (float *) &(This->current_material.u1.ambient));
1487 glMaterialfv(GL_FRONT_AND_BACK,
1488 GL_SPECULAR,
1489 (float *) &(This->current_material.u2.specular));
1490 glMaterialfv(GL_FRONT_AND_BACK,
1491 GL_EMISSION,
1492 (float *) &(This->current_material.u3.emissive));
1493 glMaterialf(GL_FRONT_AND_BACK,
1494 GL_SHININESS,
1495 This->current_material.u4.power); /* Not sure about this... */
1497 return DD_OK;
1501 HRESULT WINAPI
1502 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1503 DWORD dwLightIndex,
1504 LPD3DLIGHT7 lpLight)
1506 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1507 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1509 if (TRACE_ON(ddraw)) {
1510 TRACE(" setting light : \n");
1511 dump_D3DLIGHT7(lpLight);
1514 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1515 This->set_lights |= 0x00000001 << dwLightIndex;
1516 This->light_parameters[dwLightIndex] = *lpLight;
1518 switch (lpLight->dltType) {
1519 case D3DLIGHT_DIRECTIONAL: {
1520 float direction[4];
1521 float cut_off = 180.0;
1523 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1524 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1525 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1526 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1528 direction[0] = lpLight->dvDirection.u1.x;
1529 direction[1] = lpLight->dvDirection.u2.y;
1530 direction[2] = lpLight->dvDirection.u3.z;
1531 direction[3] = 0.0;
1532 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1533 } break;
1535 case D3DLIGHT_POINT: {
1536 float position[4];
1537 float cut_off = 180.0;
1539 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1540 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1541 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1542 position[0] = lpLight->dvPosition.u1.x;
1543 position[1] = lpLight->dvPosition.u2.y;
1544 position[2] = lpLight->dvPosition.u3.z;
1545 position[3] = 1.0;
1546 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1547 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1548 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1549 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1550 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1551 } break;
1553 case D3DLIGHT_SPOT: {
1554 float direction[4];
1555 float position[4];
1556 float cut_off = 90.0 * (lpLight->dvPhi / M_PI);
1558 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1559 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1560 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1562 direction[0] = lpLight->dvDirection.u1.x;
1563 direction[1] = lpLight->dvDirection.u2.y;
1564 direction[2] = lpLight->dvDirection.u3.z;
1565 direction[3] = 0.0;
1566 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_DIRECTION, (float *) direction);
1567 position[0] = lpLight->dvPosition.u1.x;
1568 position[1] = lpLight->dvPosition.u2.y;
1569 position[2] = lpLight->dvPosition.u3.z;
1570 position[3] = 1.0;
1571 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1572 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1573 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1574 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1575 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1576 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_EXPONENT, &(lpLight->dvFalloff));
1577 if ((lpLight->dvTheta != 0.0) || (lpLight->dvTheta != lpLight->dvPhi)) {
1578 WARN("dvTheta not fully supported yet !\n");
1580 } break;
1582 default: WARN(" light type not handled yet...\n");
1585 return DD_OK;
1588 HRESULT WINAPI
1589 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1590 DWORD dwLightIndex,
1591 BOOL bEnable)
1593 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1594 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1596 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1598 if (bEnable) {
1599 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1600 /* Set the default parameters.. */
1601 TRACE(" setting default light parameters...\n");
1602 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1604 glEnable(GL_LIGHT0 + dwLightIndex);
1605 } else {
1606 glDisable(GL_LIGHT0 + dwLightIndex);
1609 return DD_OK;
1612 HRESULT WINAPI
1613 GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, CONST D3DVALUE* pPlaneEquation)
1615 ICOM_THIS(IDirect3DDeviceImpl,iface);
1616 GLdouble plane[4];
1618 TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
1620 if (dwIndex>=This->max_clipping_planes) {
1621 return DDERR_INVALIDPARAMS;
1624 TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] );
1626 memcpy( This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4]));
1627 plane[0] = pPlaneEquation[0];
1628 plane[1] = pPlaneEquation[1];
1629 plane[2] = pPlaneEquation[2];
1630 plane[3] = pPlaneEquation[3];
1632 /* XXX: is here also code needed to handle the transformation of the world? */
1633 glClipPlane( GL_CLIP_PLANE0+dwIndex, (const GLdouble*)(&plane) );
1635 return D3D_OK;
1638 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1639 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1640 #else
1641 # define XCAST(fun) (void*)
1642 #endif
1644 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1646 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1647 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1648 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1649 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1650 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1651 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1652 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1653 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1654 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1655 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1656 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1657 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1658 XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1659 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1660 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1661 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1662 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1663 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1664 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1665 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1666 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1667 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1668 XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1669 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1670 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1671 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1672 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1673 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1674 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1675 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1676 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1677 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1678 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1679 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1680 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1681 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1682 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1683 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1684 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1685 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1686 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1687 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1688 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1689 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1690 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1691 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1692 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1693 XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane,
1694 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1695 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1698 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1699 #undef XCAST
1700 #endif
1703 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1704 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1705 #else
1706 # define XCAST(fun) (void*)
1707 #endif
1709 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1711 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1712 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1713 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1714 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1715 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1716 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1717 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1718 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1719 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1720 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1721 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1722 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1723 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1724 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1725 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1726 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1727 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1728 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1729 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1730 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1731 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1732 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1733 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1734 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1735 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1736 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1737 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1738 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1739 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1740 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1741 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1742 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1743 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1744 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1745 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1746 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1747 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1748 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1749 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1750 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1751 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1752 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1753 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1756 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1757 #undef XCAST
1758 #endif
1761 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1762 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1763 #else
1764 # define XCAST(fun) (void*)
1765 #endif
1767 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1769 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1770 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1771 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1772 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1773 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1774 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
1775 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1776 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1777 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1778 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1779 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1780 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1781 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1782 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1783 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1784 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1785 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1786 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1787 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1788 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1789 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1790 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1791 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1792 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1793 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1794 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1795 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1796 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1797 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1798 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1799 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1800 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1801 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1802 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1805 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1806 #undef XCAST
1807 #endif
1810 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1811 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1812 #else
1813 # define XCAST(fun) (void*)
1814 #endif
1816 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1818 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1819 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1820 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1821 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1822 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1823 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1824 XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
1825 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1826 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1827 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1828 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1829 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1830 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1831 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1832 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1833 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1834 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1835 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1836 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1837 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1838 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1839 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1840 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1843 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1844 #undef XCAST
1845 #endif
1847 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1848 DWORD dwCount,
1849 LPD3DRECT lpRects,
1850 DWORD dwFlags,
1851 DWORD dwColor,
1852 D3DVALUE dvZ,
1853 DWORD dwStencil)
1855 GLboolean ztest;
1856 GLfloat old_z_clear_value;
1857 GLbitfield bitfield = 0;
1858 GLint old_stencil_clear_value;
1859 GLfloat old_color_clear_value[4];
1861 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1862 if (TRACE_ON(ddraw)) {
1863 if (dwCount > 0) {
1864 int i;
1865 TRACE(" rectangles : \n");
1866 for (i = 0; i < dwCount; i++) {
1867 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1872 if (dwCount > 1) {
1873 WARN(" Warning, this function only for now clears the whole screen...\n");
1876 /* Clears the screen */
1877 ENTER_GL();
1878 if (dwFlags & D3DCLEAR_ZBUFFER) {
1879 bitfield |= GL_DEPTH_BUFFER_BIT;
1880 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1881 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1882 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1883 glClearDepth(dvZ);
1884 TRACE(" depth value : %f\n", dvZ);
1886 if (dwFlags & D3DCLEAR_STENCIL) {
1887 bitfield |= GL_STENCIL_BUFFER_BIT;
1888 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1889 glClearStencil(dwStencil);
1890 TRACE(" stencil value : %ld\n", dwStencil);
1892 if (dwFlags & D3DCLEAR_TARGET) {
1893 bitfield |= GL_COLOR_BUFFER_BIT;
1894 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1895 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1896 ((dwColor >> 8) & 0xFF) / 255.0,
1897 ((dwColor >> 0) & 0xFF) / 255.0,
1898 ((dwColor >> 24) & 0xFF) / 255.0);
1899 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1902 glClear(bitfield);
1904 if (dwFlags & D3DCLEAR_ZBUFFER) {
1905 glDepthMask(ztest);
1906 glClearDepth(old_z_clear_value);
1908 if (dwFlags & D3DCLEAR_STENCIL) {
1909 bitfield |= GL_STENCIL_BUFFER_BIT;
1910 glClearStencil(old_stencil_clear_value);
1912 if (dwFlags & D3DCLEAR_TARGET) {
1913 bitfield |= GL_COLOR_BUFFER_BIT;
1914 glClearColor(old_color_clear_value[0],
1915 old_color_clear_value[1],
1916 old_color_clear_value[2],
1917 old_color_clear_value[3]);
1920 LEAVE_GL();
1922 return DD_OK;
1925 HRESULT
1926 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1927 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1928 DWORD dwFlags, LPDDBLTFX lpbltfx)
1930 if (dwFlags & DDBLT_COLORFILL) {
1931 /* This is easy to handle for the D3D Device... */
1932 DWORD color = lpbltfx->u5.dwFillColor;
1933 TRACE(" executing D3D Device override.\n");
1934 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1935 return DD_OK;
1937 return DDERR_INVALIDPARAMS;
1940 HRESULT
1941 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1942 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1943 LPRECT rsrc, DWORD trans)
1945 return DDERR_INVALIDPARAMS;
1948 void
1949 d3ddevice_set_ortho(IDirect3DDeviceImpl *This)
1951 GLfloat height, width;
1952 GLfloat trans_mat[16];
1954 width = This->surface->surface_desc.dwWidth;
1955 height = This->surface->surface_desc.dwHeight;
1957 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
1958 to OpenGL screen coordinates (ie the upper left corner is not the same).
1959 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
1960 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
1961 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
1962 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
1963 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
1964 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
1966 glMatrixMode(GL_MODELVIEW);
1967 glLoadIdentity();
1968 glMatrixMode(GL_PROJECTION);
1969 glLoadMatrixf(trans_mat);
1972 void
1973 d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
1974 D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
1976 if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
1977 glMatrixMode(GL_MODELVIEW);
1978 glLoadMatrixf((float *) view_mat);
1979 glMultMatrixf((float *) world_mat);
1981 if ((matrices & PROJMAT_CHANGED) != 0) {
1982 glMatrixMode(GL_PROJECTION);
1983 glLoadMatrixf((float *) proj_mat);
1987 void
1988 d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
1990 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1991 if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
1992 /* This will force an update of the transform state at the next drawing. */
1993 glThis->transform_state = GL_TRANSFORM_NONE;
1997 /* TODO for both these functions :
1998 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1999 by other OpenGL code in D3D
2000 - handle the case where no 'Begin / EndScene' was done between two locks
2001 - handle the rectangles in the unlock too
2002 - handle pitch correctly...
2004 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
2006 /* First, check if we need to do anything */
2007 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
2008 GLenum buffer_type;
2009 GLenum prev_read;
2010 RECT loc_rect;
2012 ENTER_GL();
2014 glGetIntegerv(GL_READ_BUFFER, &prev_read);
2015 glFlush();
2017 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
2018 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2019 /* Application wants to lock the front buffer */
2020 glReadBuffer(GL_FRONT);
2021 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2022 /* Application wants to lock the back buffer */
2023 glReadBuffer(GL_BACK);
2024 } else {
2025 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
2028 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2029 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2030 } else {
2031 WARN(" unsupported pixel format.\n");
2032 LEAVE_GL();
2033 return;
2035 if (pRect == NULL) {
2036 loc_rect.top = 0;
2037 loc_rect.left = 0;
2038 loc_rect.bottom = This->surface_desc.dwHeight;
2039 loc_rect.right = This->surface_desc.dwWidth;
2040 } else {
2041 loc_rect = *pRect;
2043 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
2044 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
2045 + loc_rect.top * This->surface_desc.u1.lPitch
2046 + loc_rect.left * GET_BPP(This->surface_desc)));
2047 glReadBuffer(prev_read);
2048 LEAVE_GL();
2052 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
2054 /* First, check if we need to do anything */
2055 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
2056 GLenum buffer_type;
2057 GLenum prev_draw;
2059 ENTER_GL();
2061 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
2063 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
2064 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2065 /* Application wants to lock the front buffer */
2066 glDrawBuffer(GL_FRONT);
2067 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2068 /* Application wants to lock the back buffer */
2069 glDrawBuffer(GL_BACK);
2070 } else {
2071 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
2074 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2075 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2076 } else {
2077 WARN(" unsupported pixel format.\n");
2078 LEAVE_GL();
2079 return;
2081 glRasterPos2f(0.0, 0.0);
2082 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
2083 GL_RGB, buffer_type, This->surface_desc.lpSurface);
2084 glDrawBuffer(prev_draw);
2086 LEAVE_GL();
2090 HRESULT
2091 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
2093 IDirect3DDeviceImpl *object;
2094 IDirect3DDeviceGLImpl *gl_object;
2095 IDirectDrawSurfaceImpl *surf;
2096 HDC device_context;
2097 XVisualInfo *vis;
2098 int num;
2099 XVisualInfo template;
2100 GLenum buffer = GL_FRONT;
2101 int light;
2102 GLint max_clipping_planes = 0;
2104 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
2105 if (object == NULL) return DDERR_OUTOFMEMORY;
2107 gl_object = (IDirect3DDeviceGLImpl *) object;
2109 object->ref = 1;
2110 object->d3d = d3d;
2111 object->surface = surface;
2112 object->set_context = set_context;
2113 object->clear = d3ddevice_clear;
2114 object->set_matrices = d3ddevice_set_matrices;
2115 object->matrices_updated = d3ddevice_matrices_updated;
2117 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
2119 device_context = GetDC(surface->ddraw_owner->window);
2120 gl_object->display = get_display(device_context);
2121 gl_object->drawable = get_drawable(device_context);
2122 ReleaseDC(surface->ddraw_owner->window,device_context);
2124 ENTER_GL();
2125 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2126 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2127 if (vis == NULL) {
2128 HeapFree(GetProcessHeap(), 0, object);
2129 ERR("No visual found !\n");
2130 LEAVE_GL();
2131 return DDERR_INVALIDPARAMS;
2132 } else {
2133 TRACE(" visual found\n");
2136 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2137 NULL, GL_TRUE);
2139 if (gl_object->gl_context == NULL) {
2140 HeapFree(GetProcessHeap(), 0, object);
2141 ERR("Error in context creation !\n");
2142 LEAVE_GL();
2143 return DDERR_INVALIDPARAMS;
2144 } else {
2145 TRACE(" context created (%p)\n", gl_object->gl_context);
2148 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2149 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2150 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2151 surf->aux_ctx = (LPVOID) gl_object->display;
2152 surf->aux_data = (LPVOID) gl_object->drawable;
2153 surf->aux_flip = opengl_flip;
2154 buffer = GL_BACK;
2155 break;
2158 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2159 if (surf == NULL) {
2160 TRACE(" no double buffering : drawing on the front buffer\n");
2161 buffer = GL_FRONT;
2164 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2165 for (; surf != NULL; surf = surf->next_attached) {
2166 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2167 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2168 /* Override the Lock / Unlock function for all these surfaces */
2169 surf->lock_update = d3ddevice_lock_update;
2170 surf->unlock_update = d3ddevice_unlock_update;
2171 /* And install also the blt / bltfast overrides */
2172 surf->aux_blt = d3ddevice_blt;
2173 surf->aux_bltfast = d3ddevice_bltfast;
2175 surf->d3ddevice = object;
2178 /* Set the various light parameters */
2179 for (light = 0; light < MAX_LIGHTS; light++) {
2180 /* Only set the fields that are not zero-created */
2181 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2182 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2183 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2184 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2185 object->light_parameters[light].dvDirection.u3.z = 1.0;
2188 /* Allocate memory for the matrices */
2189 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2190 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2191 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2192 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2193 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2194 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2196 /* allocate the clipping planes */
2197 glGetIntegerv(GL_MAX_CLIP_PLANES,&max_clipping_planes);
2198 if (max_clipping_planes>32) {
2199 object->max_clipping_planes=32;
2200 } else {
2201 object->max_clipping_planes = max_clipping_planes;
2203 TRACE(" capable of %d clipping planes\n", (int)object->max_clipping_planes );
2204 object->clipping_planes = (d3d7clippingplane*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane));
2206 /* Initialisation */
2207 TRACE(" setting current context\n");
2208 LEAVE_GL();
2209 object->set_context(object);
2210 ENTER_GL();
2211 TRACE(" current context set\n");
2213 glClearColor(0.0, 0.0, 0.0, 0.0);
2214 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2215 glDrawBuffer(buffer);
2216 glReadBuffer(buffer);
2217 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2218 LEAVE_GL();
2220 /* fill_device_capabilities(d3d->ddraw); */
2222 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2223 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2224 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2225 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2227 *obj = object;
2229 TRACE(" creating implementation at %p.\n", *obj);
2231 /* And finally warn D3D that this device is now present */
2232 object->d3d->added_device(object->d3d, object);
2234 /* FIXME: Should handle other versions than just 7 */
2235 InitDefaultStateBlock(&object->state_block, 7);
2236 /* Apply default render state values */
2237 apply_render_state(object, &object->state_block);
2238 /* FIXME: do something similar for ligh_state and texture_stage_state */
2240 return DD_OK;