Define NONAMELESS{STRUCT,UNION} explicitly in the files that need them.
[wine.git] / dlls / ddraw / d3ddevice / mesa.c
blobc59668548849208e6dfd68ab0d9fd702521d0262
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 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
545 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
547 /* Call the render state functions */
548 set_render_state(glThis, dwRenderStateType, dwRenderState);
549 store_render_state(dwRenderStateType, dwRenderState, &glThis->parent.state_block);
551 return DD_OK;
554 HRESULT WINAPI
555 GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface,
556 D3DRENDERSTATETYPE dwRenderStateType,
557 LPDWORD lpdwRenderState)
559 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
560 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
561 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState);
563 /* Call the render state functions */
564 get_render_state(dwRenderStateType, lpdwRenderState, &glThis->parent.state_block);
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);
575 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
577 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
579 switch (dwLightStateType) {
580 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
581 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
583 if (mat != NULL) {
584 ENTER_GL();
585 mat->activate(mat);
586 LEAVE_GL();
587 } else {
588 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
590 } break;
592 case D3DLIGHTSTATE_AMBIENT: /* 2 */
593 /* Call the render_state function... */
594 set_render_state(glThis, D3DRENDERSTATE_AMBIENT, 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 This->state_block.light_state[dwLightStateType] = dwLightState;
613 return DD_OK;
616 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
618 switch (d3dpt) {
619 case D3DPT_POINTLIST:
620 TRACE("Start POINTS\n");
621 glBegin(GL_POINTS);
622 break;
624 case D3DPT_LINELIST:
625 TRACE("Start LINES\n");
626 glBegin(GL_LINES);
627 break;
629 case D3DPT_LINESTRIP:
630 TRACE("Start LINE_STRIP\n");
631 glBegin(GL_LINE_STRIP);
632 break;
634 case D3DPT_TRIANGLELIST:
635 TRACE("Start TRIANGLES\n");
636 glBegin(GL_TRIANGLES);
637 break;
639 case D3DPT_TRIANGLESTRIP:
640 TRACE("Start TRIANGLE_STRIP\n");
641 glBegin(GL_TRIANGLE_STRIP);
642 break;
644 case D3DPT_TRIANGLEFAN:
645 TRACE("Start TRIANGLE_FAN\n");
646 glBegin(GL_TRIANGLE_FAN);
647 break;
649 default:
650 TRACE("Unhandled primitive\n");
651 break;
655 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
656 BOOLEAN vertex_transformed,
657 BOOLEAN vertex_lit) {
658 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
660 /* Puts GL in the correct lighting / transformation mode */
661 if ((vertex_transformed == FALSE) &&
662 (glThis->transform_state != GL_TRANSFORM_NORMAL)) {
663 /* Need to put the correct transformation again if we go from Transformed
664 vertices to non-transformed ones.
666 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
667 This->world_mat, This->view_mat, This->proj_mat);
668 glThis->transform_state = GL_TRANSFORM_NORMAL;
670 if (glThis->render_state.fog_on == TRUE)
671 glEnable(GL_FOG);
672 } else if ((vertex_transformed == TRUE) &&
673 (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
674 /* Set our orthographic projection */
675 glThis->transform_state = GL_TRANSFORM_ORTHO;
676 d3ddevice_set_ortho(This);
678 /* Remove also fogging... */
679 glDisable(GL_FOG);
682 /* Handle the 'no-normal' case */
683 if (vertex_lit == FALSE)
684 glDisable(GL_LIGHTING);
685 else if (glThis->render_state.lighting_enable == TRUE)
686 glEnable(GL_LIGHTING);
688 /* Handle the code for pre-vertex material properties */
689 if (vertex_transformed == FALSE) {
690 if (glThis->render_state.lighting_enable == TRUE) {
691 if ((glThis->render_state.color_diffuse != D3DMCS_MATERIAL) ||
692 (glThis->render_state.color_specular != D3DMCS_MATERIAL) ||
693 (glThis->render_state.color_ambient != D3DMCS_MATERIAL) ||
694 (glThis->render_state.color_emissive != D3DMCS_MATERIAL)) {
695 glEnable(GL_COLOR_MATERIAL);
702 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
703 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
705 D3DDRAWPRIMITIVESTRIDEDDATA strided;
707 switch (d3dvt) {
708 case D3DVT_VERTEX: {
709 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
710 strided.position.dwStride = sizeof(D3DVERTEX);
711 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
712 strided.normal.dwStride = sizeof(D3DVERTEX);
713 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
714 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
715 draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
716 } break;
718 case D3DVT_LVERTEX: {
719 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
720 strided.position.dwStride = sizeof(D3DLVERTEX);
721 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
722 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
723 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
724 strided.specular.dwStride = sizeof(D3DLVERTEX);
725 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
726 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
727 draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
728 } break;
730 case D3DVT_TLVERTEX: {
731 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
732 strided.position.dwStride = sizeof(D3DTLVERTEX);
733 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
734 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
735 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
736 strided.specular.dwStride = sizeof(D3DTLVERTEX);
737 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
738 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
739 draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
740 } break;
742 default:
743 FIXME("Unhandled vertex type\n");
744 break;
748 HRESULT WINAPI
749 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
750 D3DPRIMITIVETYPE d3dptPrimitiveType,
751 D3DVERTEXTYPE d3dvtVertexType,
752 LPVOID lpvVertices,
753 DWORD dwVertexCount,
754 DWORD dwFlags)
756 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
758 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
759 if (TRACE_ON(ddraw)) {
760 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
763 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
765 return DD_OK;
768 HRESULT WINAPI
769 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
770 D3DPRIMITIVETYPE d3dptPrimitiveType,
771 D3DVERTEXTYPE d3dvtVertexType,
772 LPVOID lpvVertices,
773 DWORD dwVertexCount,
774 LPWORD dwIndices,
775 DWORD dwIndexCount,
776 DWORD dwFlags)
778 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
779 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
780 if (TRACE_ON(ddraw)) {
781 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
784 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
786 return DD_OK;
789 HRESULT WINAPI
790 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
791 LPD3DEXECUTEBUFFERDESC lpDesc,
792 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
793 IUnknown* pUnkOuter)
795 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
796 IDirect3DExecuteBufferImpl *ret;
797 HRESULT ret_value;
799 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
801 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
802 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
804 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
806 return ret_value;
809 /* These are the various handler used in the generic path */
810 inline static void handle_xyz(D3DVALUE *coords) {
811 glVertex3fv(coords);
813 inline static void handle_xyzrhw(D3DVALUE *coords) {
814 if (coords[3] < 1e-8)
815 glVertex3fv(coords);
816 else {
817 GLfloat w = 1.0 / coords[3];
819 glVertex4f(coords[0] * w,
820 coords[1] * w,
821 coords[2] * w,
825 inline static void handle_normal(D3DVALUE *coords) {
826 glNormal3fv(coords);
829 inline static void handle_diffuse_base(RenderState *rs, DWORD *color) {
830 if (rs->alpha_blend_enable == TRUE) {
831 glColor4ub((*color >> 16) & 0xFF,
832 (*color >> 8) & 0xFF,
833 (*color >> 0) & 0xFF,
834 (*color >> 24) & 0xFF);
835 } else {
836 glColor3ub((*color >> 16) & 0xFF,
837 (*color >> 8) & 0xFF,
838 (*color >> 0) & 0xFF);
842 inline static void handle_specular_base(RenderState *rs, DWORD *color) {
843 glColor4ub((*color >> 16) & 0xFF,
844 (*color >> 8) & 0xFF,
845 (*color >> 0) & 0xFF,
846 (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
849 inline static void handle_diffuse(RenderState *rs, DWORD *color) {
850 if (rs->lighting_enable == TRUE) {
851 if (rs->color_diffuse == D3DMCS_COLOR1) {
852 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
853 handle_diffuse_base(rs, color);
855 if (rs->color_ambient == D3DMCS_COLOR1) {
856 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
857 handle_diffuse_base(rs, color);
859 if ((rs->color_specular == D3DMCS_COLOR1) && (rs->specular_enable == TRUE)) {
860 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
861 handle_diffuse_base(rs, color);
863 if (rs->color_emissive == D3DMCS_COLOR1) {
864 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
865 handle_diffuse_base(rs, color);
867 } else {
868 handle_diffuse_base(rs, color);
872 inline static void handle_specular(RenderState *rs, DWORD *color) {
873 if (rs->lighting_enable == TRUE) {
874 if (rs->color_diffuse == D3DMCS_COLOR2) {
875 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
876 handle_specular(rs, color);
878 if (rs->color_ambient == D3DMCS_COLOR2) {
879 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
880 handle_specular(rs, color);
882 if ((rs->color_specular == D3DMCS_COLOR2) && (rs->specular_enable == TRUE)) {
883 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
884 handle_specular(rs, color);
886 if (rs->color_emissive == D3DMCS_COLOR2) {
887 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
888 handle_specular(rs, color);
891 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
894 inline static void handle_diffuse_and_specular(RenderState *rs, DWORD *color_d, DWORD *color_s, BOOLEAN transformed) {
895 if (transformed == TRUE) {
896 if (rs->fog_on == TRUE) {
897 /* Special case where the specular value is used to do fogging. TODO */
899 if (rs->specular_enable == TRUE) {
900 /* Standard specular value in transformed mode. TODO */
902 handle_diffuse_base(rs, color_d);
903 } else {
904 if (rs->lighting_enable == TRUE) {
905 handle_diffuse(rs, color_d);
906 handle_specular(rs, color_s);
907 } else {
908 /* In that case, only put the diffuse color... */
909 handle_diffuse_base(rs, color_d);
914 inline static void handle_texture(D3DVALUE *coords) {
915 glTexCoord2fv(coords);
917 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
918 /* For the moment, draw only the first texture.. */
919 if (tex_index == 0) glTexCoord2fv(coords);
922 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
923 D3DPRIMITIVETYPE d3dptPrimitiveType,
924 DWORD d3dvtVertexType,
925 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
926 DWORD dwStartVertex,
927 DWORD dwVertexCount,
928 LPWORD dwIndices,
929 DWORD dwIndexCount,
930 DWORD dwFlags)
932 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
933 if (TRACE_ON(ddraw)) {
934 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
937 ENTER_GL();
938 draw_primitive_handle_GL_state(This,
939 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
940 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
941 draw_primitive_start_GL(d3dptPrimitiveType);
943 /* Some fast paths first before the generic case.... */
944 if (d3dvtVertexType == D3DFVF_VERTEX) {
945 int index;
947 for (index = 0; index < dwIndexCount; index++) {
948 int i = (dwIndices == NULL) ? index : dwIndices[index];
949 D3DVALUE *normal =
950 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
951 D3DVALUE *tex_coord =
952 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
953 D3DVALUE *position =
954 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
956 handle_normal(normal);
957 handle_texture(tex_coord);
958 handle_xyz(position);
960 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
961 position[0], position[1], position[2],
962 normal[0], normal[1], normal[2],
963 tex_coord[0], tex_coord[1]);
965 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
966 int index;
968 for (index = 0; index < dwIndexCount; index++) {
969 int i = (dwIndices == NULL) ? index : dwIndices[index];
970 DWORD *color_d =
971 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
972 DWORD *color_s =
973 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
974 D3DVALUE *tex_coord =
975 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
976 D3DVALUE *position =
977 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
979 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, TRUE);
980 handle_texture(tex_coord);
981 handle_xyzrhw(position);
983 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
984 position[0], position[1], position[2], position[3],
985 (*color_d >> 16) & 0xFF,
986 (*color_d >> 8) & 0xFF,
987 (*color_d >> 0) & 0xFF,
988 (*color_d >> 24) & 0xFF,
989 (*color_s >> 16) & 0xFF,
990 (*color_s >> 8) & 0xFF,
991 (*color_s >> 0) & 0xFF,
992 (*color_s >> 24) & 0xFF,
993 tex_coord[0], tex_coord[1]);
995 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
996 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
997 /* This is the 'slow path' but that should support all possible vertex formats out there...
998 Note that people should write a fast path for all vertex formats out there...
1000 int index;
1001 for (index = 0; index < dwIndexCount; index++) {
1002 int i = (dwIndices == NULL) ? index : dwIndices[index];
1004 if (d3dvtVertexType & D3DFVF_NORMAL) {
1005 D3DVALUE *normal =
1006 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1007 handle_normal(normal);
1009 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1010 DWORD *color_d =
1011 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1012 DWORD *color_s =
1013 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1014 handle_diffuse_and_specular(&(glThis->render_state), color_d, color_s, (d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW);
1015 } else {
1016 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1017 DWORD *color_s =
1018 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1019 handle_specular(&(glThis->render_state), color_s);
1020 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1021 DWORD *color_d =
1022 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1023 handle_diffuse(&(glThis->render_state), color_d);
1027 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1028 /* Special case for single texture... */
1029 D3DVALUE *tex_coord =
1030 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1031 handle_texture(tex_coord);
1032 } else {
1033 int tex_index;
1034 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1035 D3DVALUE *tex_coord =
1036 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1037 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1038 handle_textures(tex_coord, tex_index);
1041 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1042 D3DVALUE *position =
1043 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1044 handle_xyz(position);
1045 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1046 D3DVALUE *position =
1047 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1048 handle_xyzrhw(position);
1051 if (TRACE_ON(ddraw)) {
1052 int tex_index;
1054 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1055 D3DVALUE *position =
1056 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1057 TRACE(" %f %f %f", position[0], position[1], position[2]);
1058 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1059 D3DVALUE *position =
1060 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1061 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1063 if (d3dvtVertexType & D3DFVF_NORMAL) {
1064 D3DVALUE *normal =
1065 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1066 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1068 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1069 DWORD *color_d =
1070 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1071 DPRINTF(" / %02lx %02lx %02lx %02lx",
1072 (*color_d >> 16) & 0xFF,
1073 (*color_d >> 8) & 0xFF,
1074 (*color_d >> 0) & 0xFF,
1075 (*color_d >> 24) & 0xFF);
1077 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1078 DWORD *color_s =
1079 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1080 DPRINTF(" / %02lx %02lx %02lx %02lx",
1081 (*color_s >> 16) & 0xFF,
1082 (*color_s >> 8) & 0xFF,
1083 (*color_s >> 0) & 0xFF,
1084 (*color_s >> 24) & 0xFF);
1086 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1087 D3DVALUE *tex_coord =
1088 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1089 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1090 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1092 DPRINTF("\n");
1095 } else {
1096 ERR(" matrix weighting not handled yet....\n");
1099 glEnd();
1101 /* Whatever the case, disable the color material stuff */
1102 glDisable(GL_COLOR_MATERIAL);
1104 LEAVE_GL();
1105 TRACE("End\n");
1108 HRESULT WINAPI
1109 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1110 D3DPRIMITIVETYPE d3dptPrimitiveType,
1111 DWORD d3dvtVertexType,
1112 LPVOID lpvVertices,
1113 DWORD dwVertexCount,
1114 DWORD dwFlags)
1116 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1117 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1119 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1120 if (TRACE_ON(ddraw)) {
1121 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1124 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1125 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1127 return DD_OK;
1130 HRESULT WINAPI
1131 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1132 D3DPRIMITIVETYPE d3dptPrimitiveType,
1133 DWORD d3dvtVertexType,
1134 LPVOID lpvVertices,
1135 DWORD dwVertexCount,
1136 LPWORD dwIndices,
1137 DWORD dwIndexCount,
1138 DWORD dwFlags)
1140 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1141 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1143 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1144 if (TRACE_ON(ddraw)) {
1145 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1148 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1149 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1151 return DD_OK;
1154 HRESULT WINAPI
1155 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1156 D3DPRIMITIVETYPE d3dptPrimitiveType,
1157 DWORD dwVertexType,
1158 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1159 DWORD dwVertexCount,
1160 DWORD dwFlags)
1162 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1164 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1165 if (TRACE_ON(ddraw)) {
1166 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1168 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1170 return DD_OK;
1173 HRESULT WINAPI
1174 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1175 D3DPRIMITIVETYPE d3dptPrimitiveType,
1176 DWORD dwVertexType,
1177 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1178 DWORD dwVertexCount,
1179 LPWORD lpIndex,
1180 DWORD dwIndexCount,
1181 DWORD dwFlags)
1183 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1185 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1186 if (TRACE_ON(ddraw)) {
1187 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1190 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1192 return DD_OK;
1195 HRESULT WINAPI
1196 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1197 D3DPRIMITIVETYPE d3dptPrimitiveType,
1198 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1199 DWORD dwStartVertex,
1200 DWORD dwNumVertices,
1201 DWORD dwFlags)
1203 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1204 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1205 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1207 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1208 if (TRACE_ON(ddraw)) {
1209 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1212 if (vb_impl->processed == TRUE) {
1213 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1214 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1216 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1217 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1218 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1220 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1221 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1223 } else {
1224 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1225 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1228 return DD_OK;
1231 HRESULT WINAPI
1232 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1233 D3DPRIMITIVETYPE d3dptPrimitiveType,
1234 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1235 DWORD dwStartVertex,
1236 DWORD dwNumVertices,
1237 LPWORD lpwIndices,
1238 DWORD dwIndexCount,
1239 DWORD dwFlags)
1241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1242 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1243 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1245 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1246 if (TRACE_ON(ddraw)) {
1247 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1250 if (vb_impl->processed == TRUE) {
1251 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1252 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1254 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1255 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1256 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1258 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1259 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1261 } else {
1262 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1263 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1266 return DD_OK;
1269 HRESULT WINAPI
1270 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1271 DWORD dwStage,
1272 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1273 DWORD dwState)
1275 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1276 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1277 GLenum gl_state;
1279 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1281 if (TRACE_ON(ddraw)) {
1282 TRACE(" Stage type is : ");
1283 switch (d3dTexStageStateType) {
1284 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1285 GEN_CASE(D3DTSS_COLOROP);
1286 GEN_CASE(D3DTSS_COLORARG1);
1287 GEN_CASE(D3DTSS_COLORARG2);
1288 GEN_CASE(D3DTSS_ALPHAOP);
1289 GEN_CASE(D3DTSS_ALPHAARG1);
1290 GEN_CASE(D3DTSS_ALPHAARG2);
1291 GEN_CASE(D3DTSS_BUMPENVMAT00);
1292 GEN_CASE(D3DTSS_BUMPENVMAT01);
1293 GEN_CASE(D3DTSS_BUMPENVMAT10);
1294 GEN_CASE(D3DTSS_BUMPENVMAT11);
1295 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1296 GEN_CASE(D3DTSS_ADDRESS);
1297 GEN_CASE(D3DTSS_ADDRESSU);
1298 GEN_CASE(D3DTSS_ADDRESSV);
1299 GEN_CASE(D3DTSS_BORDERCOLOR);
1300 GEN_CASE(D3DTSS_MAGFILTER);
1301 GEN_CASE(D3DTSS_MINFILTER);
1302 GEN_CASE(D3DTSS_MIPFILTER);
1303 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1304 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1305 GEN_CASE(D3DTSS_MAXANISOTROPY);
1306 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1307 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1308 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1309 #undef GEN_CASE
1310 default: DPRINTF("UNKNOWN !!!");
1312 DPRINTF(" => ");
1315 switch (d3dTexStageStateType) {
1316 case D3DTSS_MINFILTER:
1317 switch ((D3DTEXTUREMINFILTER) dwState) {
1318 case D3DTFN_POINT:
1319 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1320 gl_state = GL_NEAREST;
1321 break;
1322 case D3DTFN_LINEAR:
1323 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1324 gl_state = GL_LINEAR;
1325 break;
1326 default:
1327 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1328 gl_state = GL_LINEAR;
1329 break;
1331 glThis->render_state.min = gl_state;
1332 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1333 break;
1335 case D3DTSS_MAGFILTER:
1336 switch ((D3DTEXTUREMAGFILTER) dwState) {
1337 case D3DTFG_POINT:
1338 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1339 gl_state = GL_NEAREST;
1340 break;
1341 case D3DTFG_LINEAR:
1342 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1343 gl_state = GL_LINEAR;
1344 break;
1345 default:
1346 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1347 gl_state = GL_LINEAR;
1348 break;
1350 glThis->render_state.mag = gl_state;
1351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1352 break;
1354 case D3DTSS_ADDRESS:
1355 case D3DTSS_ADDRESSU:
1356 case D3DTSS_ADDRESSV: {
1357 GLenum arg = GL_REPEAT; /* Default value */
1358 switch ((D3DTEXTUREADDRESS) dwState) {
1359 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1360 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1361 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1362 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1364 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1365 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1367 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1368 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1369 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1370 } break;
1372 default:
1373 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1376 This->state_block.texture_stage_state[dwStage][d3dTexStageStateType-1] = dwState;
1378 return DD_OK;
1381 HRESULT WINAPI
1382 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1383 DWORD dwStage,
1384 LPDIRECTDRAWSURFACE7 lpTexture2)
1386 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1387 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1389 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1391 if (This->current_texture[dwStage] != NULL) {
1392 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7));
1395 ENTER_GL();
1396 if (lpTexture2 == NULL) {
1397 This->current_texture[dwStage] = NULL;
1399 TRACE(" disabling 2D texturing.\n");
1400 glBindTexture(GL_TEXTURE_2D, 0);
1401 glDisable(GL_TEXTURE_2D);
1402 } else {
1403 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1405 This->current_texture[dwStage] = tex_impl;
1406 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1408 glEnable(GL_TEXTURE_2D);
1409 gltex_upload_texture(tex_impl);
1411 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glThis->render_state.mag);
1412 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glThis->render_state.min);
1414 LEAVE_GL();
1416 return DD_OK;
1419 HRESULT WINAPI
1420 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1421 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1423 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1424 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1426 fill_opengl_caps_7(lpD3DHELDevDesc);
1428 TRACE(" returning caps : no dump function yet.\n");
1430 return DD_OK;
1433 HRESULT WINAPI
1434 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1435 LPD3DMATERIAL7 lpMat)
1437 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1438 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1440 if (TRACE_ON(ddraw)) {
1441 TRACE(" material is : \n");
1442 dump_D3DMATERIAL7(lpMat);
1445 This->current_material = *lpMat;
1447 glMaterialfv(GL_FRONT_AND_BACK,
1448 GL_DIFFUSE,
1449 (float *) &(This->current_material.u.diffuse));
1450 glMaterialfv(GL_FRONT_AND_BACK,
1451 GL_AMBIENT,
1452 (float *) &(This->current_material.u1.ambient));
1453 glMaterialfv(GL_FRONT_AND_BACK,
1454 GL_SPECULAR,
1455 (float *) &(This->current_material.u2.specular));
1456 glMaterialfv(GL_FRONT_AND_BACK,
1457 GL_EMISSION,
1458 (float *) &(This->current_material.u3.emissive));
1459 glMaterialf(GL_FRONT_AND_BACK,
1460 GL_SHININESS,
1461 This->current_material.u4.power); /* Not sure about this... */
1463 return DD_OK;
1467 HRESULT WINAPI
1468 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1469 DWORD dwLightIndex,
1470 LPD3DLIGHT7 lpLight)
1472 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1473 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1475 if (TRACE_ON(ddraw)) {
1476 TRACE(" setting light : \n");
1477 dump_D3DLIGHT7(lpLight);
1480 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1481 This->set_lights |= 0x00000001 << dwLightIndex;
1482 This->light_parameters[dwLightIndex] = *lpLight;
1484 switch (lpLight->dltType) {
1485 case D3DLIGHT_DIRECTIONAL: {
1486 float direction[4];
1487 float cut_off = 180.0;
1489 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1490 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1491 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1492 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1494 direction[0] = lpLight->dvDirection.u1.x;
1495 direction[1] = lpLight->dvDirection.u2.y;
1496 direction[2] = lpLight->dvDirection.u3.z;
1497 direction[3] = 0.0;
1498 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1499 } break;
1501 case D3DLIGHT_POINT: {
1502 float position[4];
1503 float cut_off = 180.0;
1505 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1506 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1507 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1508 position[0] = lpLight->dvPosition.u1.x;
1509 position[1] = lpLight->dvPosition.u2.y;
1510 position[2] = lpLight->dvPosition.u3.z;
1511 position[3] = 1.0;
1512 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1513 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1514 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1515 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1516 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1517 } break;
1519 case D3DLIGHT_SPOT: {
1520 float direction[4];
1521 float position[4];
1522 float cut_off = 90.0 * (lpLight->dvPhi / M_PI);
1524 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1525 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1526 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
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_SPOT_DIRECTION, (float *) direction);
1533 position[0] = lpLight->dvPosition.u1.x;
1534 position[1] = lpLight->dvPosition.u2.y;
1535 position[2] = lpLight->dvPosition.u3.z;
1536 position[3] = 1.0;
1537 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1538 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1539 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1540 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1541 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1542 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_EXPONENT, &(lpLight->dvFalloff));
1543 if ((lpLight->dvTheta != 0.0) || (lpLight->dvTheta != lpLight->dvPhi)) {
1544 WARN("dvTheta not fully supported yet !\n");
1546 } break;
1548 default: WARN(" light type not handled yet...\n");
1551 return DD_OK;
1554 HRESULT WINAPI
1555 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1556 DWORD dwLightIndex,
1557 BOOL bEnable)
1559 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1560 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1562 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1564 if (bEnable) {
1565 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1566 /* Set the default parameters.. */
1567 TRACE(" setting default light parameters...\n");
1568 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1570 glEnable(GL_LIGHT0 + dwLightIndex);
1571 } else {
1572 glDisable(GL_LIGHT0 + dwLightIndex);
1575 return DD_OK;
1578 HRESULT WINAPI
1579 GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, CONST D3DVALUE* pPlaneEquation)
1581 ICOM_THIS(IDirect3DDeviceImpl,iface);
1582 GLdouble plane[4];
1584 TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
1586 if (dwIndex>=This->max_clipping_planes) {
1587 return DDERR_INVALIDPARAMS;
1590 TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] );
1592 memcpy( This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4]));
1593 plane[0] = pPlaneEquation[0];
1594 plane[1] = pPlaneEquation[1];
1595 plane[2] = pPlaneEquation[2];
1596 plane[3] = pPlaneEquation[3];
1598 /* XXX: is here also code needed to handle the transformation of the world? */
1599 glClipPlane( GL_CLIP_PLANE0+dwIndex, (const GLdouble*)(&plane) );
1601 return D3D_OK;
1604 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1605 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1606 #else
1607 # define XCAST(fun) (void*)
1608 #endif
1610 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1612 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1613 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1614 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1615 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1616 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1617 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1618 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1619 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1620 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1621 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1622 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1623 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1624 XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1625 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1626 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1627 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1628 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1629 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1630 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1631 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1632 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1633 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1634 XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1635 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1636 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1637 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1638 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1639 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1640 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1641 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1642 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1643 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1644 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1645 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1646 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1647 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1648 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1649 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1650 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1651 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1652 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1653 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1654 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1655 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1656 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1657 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1658 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1659 XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane,
1660 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1661 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1664 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1665 #undef XCAST
1666 #endif
1669 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1670 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1671 #else
1672 # define XCAST(fun) (void*)
1673 #endif
1675 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1677 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1678 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1679 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1680 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1681 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1682 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1683 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1684 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1685 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1686 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1687 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1688 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1689 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1690 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1691 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1692 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1693 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1694 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1695 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1696 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1697 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1698 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1699 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1700 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1701 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1702 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1703 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1704 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1705 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1706 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1707 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1708 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1709 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1710 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1711 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1712 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1713 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1714 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1715 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1716 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1717 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1718 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1719 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1722 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1723 #undef XCAST
1724 #endif
1727 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1728 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1729 #else
1730 # define XCAST(fun) (void*)
1731 #endif
1733 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1735 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1736 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1737 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1738 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1739 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1740 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
1741 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1742 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1743 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1744 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1745 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1746 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1747 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1748 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1749 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1750 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1751 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1752 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1753 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1754 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1755 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1756 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1757 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1758 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1759 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1760 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1761 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1762 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1763 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1764 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1765 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1766 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1767 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1768 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1771 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1772 #undef XCAST
1773 #endif
1776 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1777 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1778 #else
1779 # define XCAST(fun) (void*)
1780 #endif
1782 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1784 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1785 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1786 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1787 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1788 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1789 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1790 XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
1791 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1792 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1793 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1794 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1795 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1796 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1797 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1798 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1799 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1800 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1801 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1802 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1803 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1804 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1805 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1806 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1809 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1810 #undef XCAST
1811 #endif
1813 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1814 DWORD dwCount,
1815 LPD3DRECT lpRects,
1816 DWORD dwFlags,
1817 DWORD dwColor,
1818 D3DVALUE dvZ,
1819 DWORD dwStencil)
1821 GLboolean ztest;
1822 GLfloat old_z_clear_value;
1823 GLbitfield bitfield = 0;
1824 GLint old_stencil_clear_value;
1825 GLfloat old_color_clear_value[4];
1827 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1828 if (TRACE_ON(ddraw)) {
1829 if (dwCount > 0) {
1830 int i;
1831 TRACE(" rectangles : \n");
1832 for (i = 0; i < dwCount; i++) {
1833 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1838 if (dwCount > 1) {
1839 WARN(" Warning, this function only for now clears the whole screen...\n");
1842 /* Clears the screen */
1843 ENTER_GL();
1844 if (dwFlags & D3DCLEAR_ZBUFFER) {
1845 bitfield |= GL_DEPTH_BUFFER_BIT;
1846 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1847 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1848 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1849 glClearDepth(dvZ);
1850 TRACE(" depth value : %f\n", dvZ);
1852 if (dwFlags & D3DCLEAR_STENCIL) {
1853 bitfield |= GL_STENCIL_BUFFER_BIT;
1854 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1855 glClearStencil(dwStencil);
1856 TRACE(" stencil value : %ld\n", dwStencil);
1858 if (dwFlags & D3DCLEAR_TARGET) {
1859 bitfield |= GL_COLOR_BUFFER_BIT;
1860 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1861 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1862 ((dwColor >> 8) & 0xFF) / 255.0,
1863 ((dwColor >> 0) & 0xFF) / 255.0,
1864 ((dwColor >> 24) & 0xFF) / 255.0);
1865 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1868 glClear(bitfield);
1870 if (dwFlags & D3DCLEAR_ZBUFFER) {
1871 glDepthMask(ztest);
1872 glClearDepth(old_z_clear_value);
1874 if (dwFlags & D3DCLEAR_STENCIL) {
1875 bitfield |= GL_STENCIL_BUFFER_BIT;
1876 glClearStencil(old_stencil_clear_value);
1878 if (dwFlags & D3DCLEAR_TARGET) {
1879 bitfield |= GL_COLOR_BUFFER_BIT;
1880 glClearColor(old_color_clear_value[0],
1881 old_color_clear_value[1],
1882 old_color_clear_value[2],
1883 old_color_clear_value[3]);
1886 LEAVE_GL();
1888 return DD_OK;
1891 HRESULT
1892 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1893 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1894 DWORD dwFlags, LPDDBLTFX lpbltfx)
1896 if (dwFlags & DDBLT_COLORFILL) {
1897 /* This is easy to handle for the D3D Device... */
1898 DWORD color = lpbltfx->u5.dwFillColor;
1899 TRACE(" executing D3D Device override.\n");
1900 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1901 return DD_OK;
1903 return DDERR_INVALIDPARAMS;
1906 HRESULT
1907 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1908 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1909 LPRECT rsrc, DWORD trans)
1911 return DDERR_INVALIDPARAMS;
1914 void
1915 d3ddevice_set_ortho(IDirect3DDeviceImpl *This)
1917 GLfloat height, width;
1918 GLfloat trans_mat[16];
1920 width = This->surface->surface_desc.dwWidth;
1921 height = This->surface->surface_desc.dwHeight;
1923 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
1924 to OpenGL screen coordinates (ie the upper left corner is not the same).
1925 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
1926 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
1927 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
1928 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
1929 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
1930 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
1932 glMatrixMode(GL_MODELVIEW);
1933 glLoadIdentity();
1934 glMatrixMode(GL_PROJECTION);
1935 glLoadMatrixf(trans_mat);
1938 void
1939 d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
1940 D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
1942 if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
1943 glMatrixMode(GL_MODELVIEW);
1944 glLoadMatrixf((float *) view_mat);
1945 glMultMatrixf((float *) world_mat);
1947 if ((matrices & PROJMAT_CHANGED) != 0) {
1948 glMatrixMode(GL_PROJECTION);
1949 glLoadMatrixf((float *) proj_mat);
1953 void
1954 d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
1956 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1957 if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
1958 /* This will force an update of the transform state at the next drawing. */
1959 glThis->transform_state = GL_TRANSFORM_NONE;
1963 /* TODO for both these functions :
1964 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1965 by other OpenGL code in D3D
1966 - handle the case where no 'Begin / EndScene' was done between two locks
1967 - handle the rectangles in the unlock too
1968 - handle pitch correctly...
1970 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1972 /* First, check if we need to do anything */
1973 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1974 GLenum buffer_type;
1975 GLenum prev_read;
1976 RECT loc_rect;
1978 ENTER_GL();
1980 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1981 glFlush();
1983 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1984 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1985 /* Application wants to lock the front buffer */
1986 glReadBuffer(GL_FRONT);
1987 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1988 /* Application wants to lock the back buffer */
1989 glReadBuffer(GL_BACK);
1990 } else {
1991 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1994 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1995 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1996 } else {
1997 WARN(" unsupported pixel format.\n");
1998 LEAVE_GL();
1999 return;
2001 if (pRect == NULL) {
2002 loc_rect.top = 0;
2003 loc_rect.left = 0;
2004 loc_rect.bottom = This->surface_desc.dwHeight;
2005 loc_rect.right = This->surface_desc.dwWidth;
2006 } else {
2007 loc_rect = *pRect;
2009 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
2010 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
2011 + loc_rect.top * This->surface_desc.u1.lPitch
2012 + loc_rect.left * GET_BPP(This->surface_desc)));
2013 glReadBuffer(prev_read);
2014 LEAVE_GL();
2018 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
2020 /* First, check if we need to do anything */
2021 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
2022 GLenum buffer_type;
2023 GLenum prev_draw;
2025 ENTER_GL();
2027 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
2029 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
2030 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2031 /* Application wants to lock the front buffer */
2032 glDrawBuffer(GL_FRONT);
2033 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2034 /* Application wants to lock the back buffer */
2035 glDrawBuffer(GL_BACK);
2036 } else {
2037 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
2040 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2041 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2042 } else {
2043 WARN(" unsupported pixel format.\n");
2044 LEAVE_GL();
2045 return;
2047 glRasterPos2f(0.0, 0.0);
2048 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
2049 GL_RGB, buffer_type, This->surface_desc.lpSurface);
2050 glDrawBuffer(prev_draw);
2052 LEAVE_GL();
2056 HRESULT
2057 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
2059 IDirect3DDeviceImpl *object;
2060 IDirect3DDeviceGLImpl *gl_object;
2061 IDirectDrawSurfaceImpl *surf;
2062 HDC device_context;
2063 XVisualInfo *vis;
2064 int num;
2065 XVisualInfo template;
2066 GLenum buffer = GL_FRONT;
2067 int light;
2068 GLint max_clipping_planes = 0;
2070 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
2071 if (object == NULL) return DDERR_OUTOFMEMORY;
2073 gl_object = (IDirect3DDeviceGLImpl *) object;
2075 object->ref = 1;
2076 object->d3d = d3d;
2077 object->surface = surface;
2078 object->set_context = set_context;
2079 object->clear = d3ddevice_clear;
2080 object->set_matrices = d3ddevice_set_matrices;
2081 object->matrices_updated = d3ddevice_matrices_updated;
2083 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
2085 device_context = GetDC(surface->ddraw_owner->window);
2086 gl_object->display = get_display(device_context);
2087 gl_object->drawable = get_drawable(device_context);
2088 ReleaseDC(surface->ddraw_owner->window,device_context);
2090 ENTER_GL();
2091 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2092 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2093 if (vis == NULL) {
2094 HeapFree(GetProcessHeap(), 0, object);
2095 ERR("No visual found !\n");
2096 LEAVE_GL();
2097 return DDERR_INVALIDPARAMS;
2098 } else {
2099 TRACE(" visual found\n");
2102 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2103 NULL, GL_TRUE);
2105 if (gl_object->gl_context == NULL) {
2106 HeapFree(GetProcessHeap(), 0, object);
2107 ERR("Error in context creation !\n");
2108 LEAVE_GL();
2109 return DDERR_INVALIDPARAMS;
2110 } else {
2111 TRACE(" context created (%p)\n", gl_object->gl_context);
2114 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2115 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2116 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2117 surf->aux_ctx = (LPVOID) gl_object->display;
2118 surf->aux_data = (LPVOID) gl_object->drawable;
2119 surf->aux_flip = opengl_flip;
2120 buffer = GL_BACK;
2121 break;
2124 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2125 if (surf == NULL) {
2126 TRACE(" no double buffering : drawing on the front buffer\n");
2127 buffer = GL_FRONT;
2130 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2131 for (; surf != NULL; surf = surf->next_attached) {
2132 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2133 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2134 /* Override the Lock / Unlock function for all these surfaces */
2135 surf->lock_update = d3ddevice_lock_update;
2136 surf->unlock_update = d3ddevice_unlock_update;
2137 /* And install also the blt / bltfast overrides */
2138 surf->aux_blt = d3ddevice_blt;
2139 surf->aux_bltfast = d3ddevice_bltfast;
2141 surf->d3ddevice = object;
2144 /* FIXME: These 4 statements are kept for compatibility but should be removed as soon
2145 as they are correctly handled */
2146 gl_object->render_state.fog_on = FALSE;
2147 gl_object->render_state.stencil_enable = FALSE;
2148 gl_object->render_state.lighting_enable = FALSE;
2149 gl_object->render_state.specular_enable = FALSE;
2151 /* Set the various light parameters */
2152 for (light = 0; light < MAX_LIGHTS; light++) {
2153 /* Only set the fields that are not zero-created */
2154 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2155 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2156 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2157 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2158 object->light_parameters[light].dvDirection.u3.z = 1.0;
2161 /* Allocate memory for the matrices */
2162 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2163 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2164 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2165 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2166 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2167 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2169 /* allocate the clipping planes */
2170 glGetIntegerv(GL_MAX_CLIP_PLANES,&max_clipping_planes);
2171 if (max_clipping_planes>32) {
2172 object->max_clipping_planes=32;
2173 } else {
2174 object->max_clipping_planes = max_clipping_planes;
2176 TRACE(" capable of %d clipping planes\n", (int)object->max_clipping_planes );
2177 object->clipping_planes = (d3d7clippingplane*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane));
2179 /* Initialisation */
2180 TRACE(" setting current context\n");
2181 LEAVE_GL();
2182 object->set_context(object);
2183 ENTER_GL();
2184 TRACE(" current context set\n");
2186 glClearColor(0.0, 0.0, 0.0, 0.0);
2187 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2188 glDrawBuffer(buffer);
2189 glReadBuffer(buffer);
2190 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2191 LEAVE_GL();
2193 /* fill_device_capabilities(d3d->ddraw); */
2195 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2196 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2197 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2198 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2200 *obj = object;
2202 TRACE(" creating implementation at %p.\n", *obj);
2204 /* And finally warn D3D that this device is now present */
2205 object->d3d->added_device(object->d3d, object);
2207 /* FIXME: Should handle other versions than just 7 */
2208 InitDefaultStateBlock(&object->state_block,7);
2209 /* Apply default render state values */
2210 apply_render_state(gl_object, &object->state_block);
2211 /* FIXME: do something similar for ligh_state and texture_stage_state */
2213 return DD_OK;