2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the MESA implementation of all the D3D devices that
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
33 #include "wine/debug.h"
35 #include "mesa_private.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 = {
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,
57 const float id_mat[16] = {
64 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
65 D3DPRIMITIVETYPE d3dptPrimitiveType,
66 DWORD d3dvtVertexType,
67 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
74 /* retrieve the X display to use on a given DC */
75 inline static Display *get_display( HDC hdc )
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;
87 /* retrieve the X drawable to use on a given DC */
88 inline static Drawable get_drawable( HDC hdc )
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;
100 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
102 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
104 glXSwapBuffers((Display*)display,(Drawable)drawable);
110 /*******************************************************************************
111 * OpenGL static functions
113 static void set_context(IDirect3DDeviceImpl* This)
115 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
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);
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)
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;
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;
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);
266 TRACE("Color table extension not found.\n");
274 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
276 D3DDEVICEDESC dref, d1, d2;
279 fill_opengl_caps(&dref);
281 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
284 ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
285 if (ret_value != D3DENUMRET_OK)
288 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
291 ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
292 if (ret_value != D3DENUMRET_OK)
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);
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)) {
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);
331 glXDestroyContext(glThis->display, glThis->gl_context);
333 HeapFree(GetProcessHeap(), 0, This->clipping_planes);
335 HeapFree(GetProcessHeap(), 0, This);
342 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
343 LPD3DDEVICEDESC lpD3DHWDevDesc,
344 LPD3DDEVICEDESC lpD3DHELDevDesc)
346 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
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");
366 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
367 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
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;
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;
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");
486 d3ddevice_find(IDirect3DImpl *d3d,
487 LPD3DFINDDEVICESEARCH lpD3DDFS,
488 LPD3DFINDDEVICERESULT lplpD3DDevice)
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");
519 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
520 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
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);
529 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
530 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
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);
539 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
540 D3DRENDERSTATETYPE dwRenderStateType,
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);
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);
570 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
571 D3DLIGHTSTATETYPE dwLightStateType,
574 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
576 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
578 if (!dwLightStateType && (dwLightStateType > D3DLIGHTSTATE_COLORVERTEX))
579 TRACE("Unexpected Light State Type\n");
580 return DDERR_INVALIDPARAMS;
582 if (dwLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) {
583 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
590 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
592 } else if (dwLightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) {
593 switch (dwLightState) {
595 ERR("DDCOLOR_MONO should not happend!\n");
598 /* We are already in this mode */
601 ERR("Unknown color model!\n");
605 D3DRENDERSTATETYPE rs;
606 switch (dwLightStateType) {
608 case D3DLIGHTSTATE_AMBIENT: /* 2 */
609 rs = D3DRENDERSTATE_AMBIENT;
611 case D3DLIGHTSTATE_FOGMODE: /* 4 */
612 rs = D3DRENDERSTATE_FOGVERTEXMODE;
614 case D3DLIGHTSTATE_FOGSTART: /* 5 */
615 rs = D3DRENDERSTATE_FOGSTART;
617 case D3DLIGHTSTATE_FOGEND: /* 6 */
618 rs = D3DRENDERSTATE_FOGEND;
620 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
621 rs = D3DRENDERSTATE_FOGDENSITY;
623 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
624 rs = D3DRENDERSTATE_COLORVERTEX;
630 IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
637 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
640 case D3DPT_POINTLIST:
641 TRACE("Start POINTS\n");
646 TRACE("Start LINES\n");
650 case D3DPT_LINESTRIP:
651 TRACE("Start LINE_STRIP\n");
652 glBegin(GL_LINE_STRIP);
655 case D3DPT_TRIANGLELIST:
656 TRACE("Start TRIANGLES\n");
657 glBegin(GL_TRIANGLES);
660 case D3DPT_TRIANGLESTRIP:
661 TRACE("Start TRIANGLE_STRIP\n");
662 glBegin(GL_TRIANGLE_STRIP);
665 case D3DPT_TRIANGLEFAN:
666 TRACE("Start TRIANGLE_FAN\n");
667 glBegin(GL_TRIANGLE_FAN);
671 TRACE("Unhandled primitive\n");
676 /* This function calculate the Z coordinate from Zproj */
677 static float ZfromZproj(IDirect3DDeviceImpl *This, D3DVALUE Zproj)
680 /* Assume that X = Y = 0 and W = 1 */
681 a = This->proj_mat->_33;
682 b = This->proj_mat->_34;
683 c = This->proj_mat->_43;
684 d = This->proj_mat->_44;
685 /* We have in homogenous coordinates Z' = a * Z + c and W' = b * Z + d
686 * So in non homogenous coordinates we have Zproj = (a * Z + b) / (c * Z + d)
687 * And finally Z = (d * Zproj - c) / (a - b * Zproj)
689 return (d*Zproj - c) / (a - b*Zproj);
692 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
693 BOOLEAN vertex_transformed,
694 BOOLEAN vertex_lit) {
695 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
697 /* Puts GL in the correct lighting / transformation mode */
698 if ((vertex_transformed == FALSE) &&
699 (glThis->transform_state != GL_TRANSFORM_NORMAL)) {
700 /* Need to put the correct transformation again if we go from Transformed
701 vertices to non-transformed ones.
703 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
704 This->world_mat, This->view_mat, This->proj_mat);
705 glThis->transform_state = GL_TRANSFORM_NORMAL;
707 } else if ((vertex_transformed == TRUE) &&
708 (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
709 /* Set our orthographic projection */
710 glThis->transform_state = GL_TRANSFORM_ORTHO;
711 d3ddevice_set_ortho(This);
713 if (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE) {glHint(GL_FOG_HINT,GL_NICEST);
714 if (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1] != D3DFOG_NONE) {
715 switch (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1]) {
716 case D3DFOG_LINEAR: glFogi(GL_FOG_MODE,GL_LINEAR); break;
717 case D3DFOG_EXP: glFogi(GL_FOG_MODE,GL_EXP); break;
718 case D3DFOG_EXP2: glFogi(GL_FOG_MODE,GL_EXP2); break;
720 glFogf(GL_FOG_START,ZfromZproj(This,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]));
721 glFogf(GL_FOG_END,ZfromZproj(This,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]));
723 } else if ( (This->state_block.render_state[D3DRENDERSTATE_FOGVERTEXMODE - 1] != D3DFOG_NONE) &&
724 (vertex_lit == FALSE) && (vertex_transformed == FALSE) ) {
725 /* D3DFOG_EXP and D3DFOG_EXP2 are treated as D3DFOG_LINEAR */
726 glFogi(GL_FOG_MODE,GL_LINEAR);
727 glFogf(GL_FOG_START,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]);
728 glFogf(GL_FOG_END,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]);
736 /* Handle the 'no-normal' case */
737 if (vertex_lit == TRUE)
738 glDisable(GL_LIGHTING);
739 else if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)
740 glEnable(GL_LIGHTING);
742 /* Handle the code for pre-vertex material properties */
743 if (vertex_transformed == FALSE) {
744 if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) {
745 if ((This->state_block.render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
746 (This->state_block.render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
747 (This->state_block.render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) ||
748 (This->state_block.render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] != D3DMCS_MATERIAL)) {
749 glEnable(GL_COLOR_MATERIAL);
756 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
757 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
759 D3DDRAWPRIMITIVESTRIDEDDATA strided;
763 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
764 strided.position.dwStride = sizeof(D3DVERTEX);
765 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
766 strided.normal.dwStride = sizeof(D3DVERTEX);
767 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
768 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
769 draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
772 case D3DVT_LVERTEX: {
773 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
774 strided.position.dwStride = sizeof(D3DLVERTEX);
775 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
776 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
777 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
778 strided.specular.dwStride = sizeof(D3DLVERTEX);
779 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
780 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
781 draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
784 case D3DVT_TLVERTEX: {
785 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
786 strided.position.dwStride = sizeof(D3DTLVERTEX);
787 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
788 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
789 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
790 strided.specular.dwStride = sizeof(D3DTLVERTEX);
791 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
792 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
793 draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
797 FIXME("Unhandled vertex type\n");
803 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
804 D3DPRIMITIVETYPE d3dptPrimitiveType,
805 D3DVERTEXTYPE d3dvtVertexType,
810 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
812 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
813 if (TRACE_ON(ddraw)) {
814 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
817 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
823 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
824 D3DPRIMITIVETYPE d3dptPrimitiveType,
825 D3DVERTEXTYPE d3dvtVertexType,
832 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
833 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
834 if (TRACE_ON(ddraw)) {
835 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
838 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
844 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
845 LPD3DEXECUTEBUFFERDESC lpDesc,
846 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
849 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
850 IDirect3DExecuteBufferImpl *ret;
853 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
855 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
856 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
858 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
863 /* These are the various handler used in the generic path */
864 inline static void handle_xyz(D3DVALUE *coords) {
867 inline static void handle_xyzrhw(D3DVALUE *coords) {
868 if (coords[3] < 1e-8)
871 GLfloat w = 1.0 / coords[3];
873 glVertex4f(coords[0] * w,
879 inline static void handle_normal(D3DVALUE *coords) {
883 inline static void handle_diffuse_base(STATEBLOCK *sb, DWORD *color) {
884 if ((sb->render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] == TRUE) ||
885 (sb->render_state[D3DRENDERSTATE_ALPHABLENDENABLE - 1] == TRUE)) {
886 glColor4ub((*color >> 16) & 0xFF,
887 (*color >> 8) & 0xFF,
888 (*color >> 0) & 0xFF,
889 (*color >> 24) & 0xFF);
891 glColor3ub((*color >> 16) & 0xFF,
892 (*color >> 8) & 0xFF,
893 (*color >> 0) & 0xFF);
897 inline static void handle_specular_base(STATEBLOCK *sb, DWORD *color) {
898 glColor4ub((*color >> 16) & 0xFF,
899 (*color >> 8) & 0xFF,
900 (*color >> 0) & 0xFF,
901 (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */
904 inline static void handle_diffuse(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
905 if ((lighted == FALSE) &&
906 (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)) {
907 if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
908 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
909 handle_diffuse_base(sb, color);
911 if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
912 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
913 handle_diffuse_base(sb, color);
915 if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR1) &&
916 (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
917 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
918 handle_diffuse_base(sb, color);
920 if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR1) {
921 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
922 handle_diffuse_base(sb, color);
925 handle_diffuse_base(sb, color);
929 inline static void handle_specular(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) {
930 if ((lighted == FALSE) &&
931 (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE)) {
932 if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
933 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
934 handle_specular_base(sb, color);
936 if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
937 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
938 handle_specular_base(sb, color);
940 if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR2) &&
941 (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE)) {
942 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
943 handle_specular_base(sb, color);
945 if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR2) {
946 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
947 handle_specular_base(sb, color);
950 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
953 inline static void handle_diffuse_and_specular(STATEBLOCK *sb, DWORD *color_d, DWORD *color_s, BOOLEAN lighted) {
954 if (lighted == TRUE) {
955 if (sb->render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE) {
956 /* Special case where the specular value is used to do fogging. TODO */
958 if (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] == TRUE) {
959 /* Standard specular value in transformed mode. TODO */
961 handle_diffuse_base(sb, color_d);
963 if (sb->render_state[D3DRENDERSTATE_LIGHTING - 1] == TRUE) {
964 handle_diffuse(sb, color_d, FALSE);
965 handle_specular(sb, color_s, FALSE);
967 /* In that case, only put the diffuse color... */
968 handle_diffuse_base(sb, color_d);
973 inline static void handle_texture(D3DVALUE *coords) {
974 glTexCoord2fv(coords);
976 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
977 /* For the moment, draw only the first texture.. */
978 if (tex_index == 0) glTexCoord2fv(coords);
981 static void draw_primitive_strided(IDirect3DDeviceImpl *This,
982 D3DPRIMITIVETYPE d3dptPrimitiveType,
983 DWORD d3dvtVertexType,
984 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
991 BOOLEAN vertex_lighted = (d3dvtVertexType & D3DFVF_NORMAL) == 0;
993 if (TRACE_ON(ddraw)) {
994 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
998 draw_primitive_handle_GL_state(This,
999 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
1001 draw_primitive_start_GL(d3dptPrimitiveType);
1003 /* Some fast paths first before the generic case.... */
1004 if (d3dvtVertexType == D3DFVF_VERTEX) {
1007 for (index = 0; index < dwIndexCount; index++) {
1008 int i = (dwIndices == NULL) ? index : dwIndices[index];
1010 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1011 D3DVALUE *tex_coord =
1012 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1013 D3DVALUE *position =
1014 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1016 handle_normal(normal);
1017 handle_texture(tex_coord);
1018 handle_xyz(position);
1020 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
1021 position[0], position[1], position[2],
1022 normal[0], normal[1], normal[2],
1023 tex_coord[0], tex_coord[1]);
1025 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
1028 for (index = 0; index < dwIndexCount; index++) {
1029 int i = (dwIndices == NULL) ? index : dwIndices[index];
1031 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1033 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1034 D3DVALUE *tex_coord =
1035 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1036 D3DVALUE *position =
1037 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1039 handle_diffuse_and_specular(&(This->state_block), color_d, color_s, TRUE);
1040 handle_texture(tex_coord);
1041 handle_xyzrhw(position);
1043 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1044 position[0], position[1], position[2], position[3],
1045 (*color_d >> 16) & 0xFF,
1046 (*color_d >> 8) & 0xFF,
1047 (*color_d >> 0) & 0xFF,
1048 (*color_d >> 24) & 0xFF,
1049 (*color_s >> 16) & 0xFF,
1050 (*color_s >> 8) & 0xFF,
1051 (*color_s >> 0) & 0xFF,
1052 (*color_s >> 24) & 0xFF,
1053 tex_coord[0], tex_coord[1]);
1055 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1056 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1057 /* This is the 'slow path' but that should support all possible vertex formats out there...
1058 Note that people should write a fast path for all vertex formats out there...
1061 for (index = 0; index < dwIndexCount; index++) {
1062 int i = (dwIndices == NULL) ? index : dwIndices[index];
1064 if (d3dvtVertexType & D3DFVF_NORMAL) {
1066 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1067 handle_normal(normal);
1069 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1071 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1073 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1074 handle_diffuse_and_specular(&(This->state_block), color_d, color_s, vertex_lighted);
1076 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1078 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1079 handle_specular(&(This->state_block), color_s, vertex_lighted);
1080 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1082 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1083 handle_diffuse(&(This->state_block), color_d, vertex_lighted);
1087 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1088 /* Special case for single texture... */
1089 D3DVALUE *tex_coord =
1090 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1091 handle_texture(tex_coord);
1094 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1095 D3DVALUE *tex_coord =
1096 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1097 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1098 handle_textures(tex_coord, tex_index);
1101 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1102 D3DVALUE *position =
1103 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1104 handle_xyz(position);
1105 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1106 D3DVALUE *position =
1107 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1108 handle_xyzrhw(position);
1111 if (TRACE_ON(ddraw)) {
1114 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1115 D3DVALUE *position =
1116 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1117 TRACE(" %f %f %f", position[0], position[1], position[2]);
1118 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1119 D3DVALUE *position =
1120 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1121 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1123 if (d3dvtVertexType & D3DFVF_NORMAL) {
1125 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1126 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1128 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1130 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1131 DPRINTF(" / %02lx %02lx %02lx %02lx",
1132 (*color_d >> 16) & 0xFF,
1133 (*color_d >> 8) & 0xFF,
1134 (*color_d >> 0) & 0xFF,
1135 (*color_d >> 24) & 0xFF);
1137 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1139 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1140 DPRINTF(" / %02lx %02lx %02lx %02lx",
1141 (*color_s >> 16) & 0xFF,
1142 (*color_s >> 8) & 0xFF,
1143 (*color_s >> 0) & 0xFF,
1144 (*color_s >> 24) & 0xFF);
1146 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1147 D3DVALUE *tex_coord =
1148 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1149 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1150 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1156 ERR(" matrix weighting not handled yet....\n");
1161 /* Whatever the case, disable the color material stuff */
1162 glDisable(GL_COLOR_MATERIAL);
1169 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1170 D3DPRIMITIVETYPE d3dptPrimitiveType,
1171 DWORD d3dvtVertexType,
1173 DWORD dwVertexCount,
1176 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1177 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1179 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1180 if (TRACE_ON(ddraw)) {
1181 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1184 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1185 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1191 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1192 D3DPRIMITIVETYPE d3dptPrimitiveType,
1193 DWORD d3dvtVertexType,
1195 DWORD dwVertexCount,
1200 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1201 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1203 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1204 if (TRACE_ON(ddraw)) {
1205 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1208 convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided);
1209 draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1215 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1216 D3DPRIMITIVETYPE d3dptPrimitiveType,
1218 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1219 DWORD dwVertexCount,
1222 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1224 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1225 if (TRACE_ON(ddraw)) {
1226 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1228 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1234 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1235 D3DPRIMITIVETYPE d3dptPrimitiveType,
1237 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1238 DWORD dwVertexCount,
1243 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1245 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1246 if (TRACE_ON(ddraw)) {
1247 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1250 draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1256 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1257 D3DPRIMITIVETYPE d3dptPrimitiveType,
1258 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1259 DWORD dwStartVertex,
1260 DWORD dwNumVertices,
1263 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1264 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1265 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1267 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1268 if (TRACE_ON(ddraw)) {
1269 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1272 if (vb_impl->processed == TRUE) {
1273 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1274 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1276 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1277 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1278 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1280 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1281 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1284 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1285 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1292 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1293 D3DPRIMITIVETYPE d3dptPrimitiveType,
1294 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1295 DWORD dwStartVertex,
1296 DWORD dwNumVertices,
1301 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1302 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1303 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1305 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1306 if (TRACE_ON(ddraw)) {
1307 TRACE(" - flags : "); dump_DPFLAGS(dwFlags);
1310 if (vb_impl->processed == TRUE) {
1311 IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl;
1312 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1314 glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER;
1315 This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED,
1316 &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat));
1318 convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided);
1319 draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1322 convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided);
1323 draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1330 convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwState)
1336 gl_state = GL_NEAREST;
1339 gl_state = GL_LINEAR;
1342 gl_state = GL_LINEAR;
1349 convert_mag_filter_to_GL(D3DTEXTUREMAGFILTER dwState)
1355 gl_state = GL_NEAREST;
1358 gl_state = GL_LINEAR;
1361 gl_state = GL_LINEAR;
1368 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1370 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1373 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1375 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1377 if (dwStage > 0) return DD_OK; /* We nothing in this case for now */
1379 if (TRACE_ON(ddraw)) {
1380 TRACE(" Stage type is : ");
1381 switch (d3dTexStageStateType) {
1382 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1383 GEN_CASE(D3DTSS_COLOROP);
1384 GEN_CASE(D3DTSS_COLORARG1);
1385 GEN_CASE(D3DTSS_COLORARG2);
1386 GEN_CASE(D3DTSS_ALPHAOP);
1387 GEN_CASE(D3DTSS_ALPHAARG1);
1388 GEN_CASE(D3DTSS_ALPHAARG2);
1389 GEN_CASE(D3DTSS_BUMPENVMAT00);
1390 GEN_CASE(D3DTSS_BUMPENVMAT01);
1391 GEN_CASE(D3DTSS_BUMPENVMAT10);
1392 GEN_CASE(D3DTSS_BUMPENVMAT11);
1393 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1394 GEN_CASE(D3DTSS_ADDRESS);
1395 GEN_CASE(D3DTSS_ADDRESSU);
1396 GEN_CASE(D3DTSS_ADDRESSV);
1397 GEN_CASE(D3DTSS_BORDERCOLOR);
1398 GEN_CASE(D3DTSS_MAGFILTER);
1399 GEN_CASE(D3DTSS_MINFILTER);
1400 GEN_CASE(D3DTSS_MIPFILTER);
1401 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1402 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1403 GEN_CASE(D3DTSS_MAXANISOTROPY);
1404 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1405 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1406 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1408 default: DPRINTF("UNKNOWN !!!");
1413 switch (d3dTexStageStateType) {
1414 case D3DTSS_MINFILTER:
1415 if (TRACE_ON(ddraw)) {
1416 switch ((D3DTEXTUREMINFILTER) dwState) {
1417 case D3DTFN_POINT: DPRINTF("D3DTFN_POINT\n"); break;
1418 case D3DTFN_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
1419 default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
1422 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert_min_filter_to_GL(dwState));
1425 case D3DTSS_MAGFILTER:
1426 if (TRACE_ON(ddraw)) {
1427 switch ((D3DTEXTUREMAGFILTER) dwState) {
1428 case D3DTFG_POINT: DPRINTF("D3DTFN_POINT\n"); break;
1429 case D3DTFG_LINEAR: DPRINTF("D3DTFN_LINEAR\n"); break;
1430 default: DPRINTF(" state unhandled (%ld).\n", dwState); break;
1433 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert_mag_filter_to_GL(dwState));
1436 case D3DTSS_ADDRESS:
1437 case D3DTSS_ADDRESSU:
1438 case D3DTSS_ADDRESSV: {
1439 GLenum arg = GL_REPEAT; /* Default value */
1440 switch ((D3DTEXTUREADDRESS) dwState) {
1441 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1442 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1443 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1444 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1446 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1447 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1448 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1449 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1450 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1451 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1455 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1458 This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState;
1459 /* Some special cases when one state modifies more than one... */
1460 if (d3dTexStageStateType == D3DTSS_ADDRESS) {
1461 This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState;
1462 This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState;
1469 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1471 LPDIRECTDRAWSURFACE7 lpTexture2)
1473 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1475 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1477 if (dwStage > 0) return DD_OK;
1479 if (This->current_texture[dwStage] != NULL) {
1480 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7));
1484 if (lpTexture2 == NULL) {
1485 This->current_texture[dwStage] = NULL;
1487 TRACE(" disabling 2D texturing.\n");
1488 glBindTexture(GL_TEXTURE_2D, 0);
1489 glDisable(GL_TEXTURE_2D);
1491 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1493 This->current_texture[dwStage] = tex_impl;
1494 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1496 glEnable(GL_TEXTURE_2D);
1497 gltex_upload_texture(tex_impl);
1499 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1500 convert_mag_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MAGFILTER - 1]));
1501 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1502 convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1]));
1510 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1511 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1513 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1514 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1516 fill_opengl_caps_7(lpD3DHELDevDesc);
1518 TRACE(" returning caps : no dump function yet.\n");
1524 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1525 LPD3DMATERIAL7 lpMat)
1527 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1528 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1530 if (TRACE_ON(ddraw)) {
1531 TRACE(" material is : \n");
1532 dump_D3DMATERIAL7(lpMat);
1535 This->current_material = *lpMat;
1537 glMaterialfv(GL_FRONT_AND_BACK,
1539 (float *) &(This->current_material.u.diffuse));
1540 glMaterialfv(GL_FRONT_AND_BACK,
1542 (float *) &(This->current_material.u1.ambient));
1543 glMaterialfv(GL_FRONT_AND_BACK,
1545 (float *) &(This->current_material.u2.specular));
1546 glMaterialfv(GL_FRONT_AND_BACK,
1548 (float *) &(This->current_material.u3.emissive));
1549 glMaterialf(GL_FRONT_AND_BACK,
1551 This->current_material.u4.power); /* Not sure about this... */
1558 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1560 LPD3DLIGHT7 lpLight)
1562 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1563 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1565 if (TRACE_ON(ddraw)) {
1566 TRACE(" setting light : \n");
1567 dump_D3DLIGHT7(lpLight);
1570 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1571 This->set_lights |= 0x00000001 << dwLightIndex;
1572 This->light_parameters[dwLightIndex] = *lpLight;
1574 switch (lpLight->dltType) {
1575 case D3DLIGHT_DIRECTIONAL: {
1577 float cut_off = 180.0;
1579 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1580 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1581 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1582 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1584 direction[0] = lpLight->dvDirection.u1.x;
1585 direction[1] = lpLight->dvDirection.u2.y;
1586 direction[2] = lpLight->dvDirection.u3.z;
1588 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1591 case D3DLIGHT_POINT: {
1593 float cut_off = 180.0;
1595 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1596 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1597 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1598 position[0] = lpLight->dvPosition.u1.x;
1599 position[1] = lpLight->dvPosition.u2.y;
1600 position[2] = lpLight->dvPosition.u3.z;
1602 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1603 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1604 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1605 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1606 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1609 case D3DLIGHT_SPOT: {
1612 float cut_off = 90.0 * (lpLight->dvPhi / M_PI);
1614 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1615 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1616 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1618 direction[0] = lpLight->dvDirection.u1.x;
1619 direction[1] = lpLight->dvDirection.u2.y;
1620 direction[2] = lpLight->dvDirection.u3.z;
1622 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_DIRECTION, (float *) direction);
1623 position[0] = lpLight->dvPosition.u1.x;
1624 position[1] = lpLight->dvPosition.u2.y;
1625 position[2] = lpLight->dvPosition.u3.z;
1627 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) position);
1628 glLightfv(GL_LIGHT0 + dwLightIndex, GL_CONSTANT_ATTENUATION, &(lpLight->dvAttenuation0));
1629 glLightfv(GL_LIGHT0 + dwLightIndex, GL_LINEAR_ATTENUATION, &(lpLight->dvAttenuation1));
1630 glLightfv(GL_LIGHT0 + dwLightIndex, GL_QUADRATIC_ATTENUATION, &(lpLight->dvAttenuation2));
1631 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_CUTOFF, &cut_off);
1632 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPOT_EXPONENT, &(lpLight->dvFalloff));
1633 if ((lpLight->dvTheta != 0.0) || (lpLight->dvTheta != lpLight->dvPhi)) {
1634 WARN("dvTheta not fully supported yet !\n");
1638 default: WARN(" light type not handled yet...\n");
1645 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1649 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1650 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1652 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1655 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1656 /* Set the default parameters.. */
1657 TRACE(" setting default light parameters...\n");
1658 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1660 glEnable(GL_LIGHT0 + dwLightIndex);
1662 glDisable(GL_LIGHT0 + dwLightIndex);
1669 GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, CONST D3DVALUE* pPlaneEquation)
1671 ICOM_THIS(IDirect3DDeviceImpl,iface);
1674 TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation);
1676 if (dwIndex>=This->max_clipping_planes) {
1677 return DDERR_INVALIDPARAMS;
1680 TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] );
1682 memcpy( This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4]));
1683 plane[0] = pPlaneEquation[0];
1684 plane[1] = pPlaneEquation[1];
1685 plane[2] = pPlaneEquation[2];
1686 plane[3] = pPlaneEquation[3];
1688 /* XXX: is here also code needed to handle the transformation of the world? */
1689 glClipPlane( GL_CLIP_PLANE0+dwIndex, (const GLdouble*)(&plane) );
1694 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1695 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1697 # define XCAST(fun) (void*)
1700 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1702 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1703 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1704 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1705 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1706 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1707 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1708 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1709 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1710 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1711 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1712 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1713 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1714 XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1715 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1716 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1717 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1718 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1719 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1720 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1721 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1722 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1723 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1724 XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1725 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1726 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1727 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1728 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1729 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1730 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1731 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1732 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1733 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1734 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1735 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1736 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1737 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1738 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1739 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1740 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1741 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1742 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1743 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1744 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1745 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1746 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1747 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1748 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1749 XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane,
1750 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1751 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1754 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1759 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1760 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1762 # define XCAST(fun) (void*)
1765 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1767 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1768 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1769 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1770 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1771 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1772 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1773 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1774 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1775 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1776 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1777 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1778 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1779 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1780 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1781 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1782 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1783 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1784 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1785 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1786 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1787 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1788 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1789 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1790 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1791 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1792 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1793 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1794 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1795 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1796 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1797 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1798 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1799 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1800 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1801 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1802 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1803 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1804 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1805 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1806 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1807 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1808 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1809 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1812 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1817 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1818 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1820 # define XCAST(fun) (void*)
1823 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1825 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1826 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1827 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1828 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1829 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1830 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles,
1831 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1832 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1833 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1834 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1835 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1836 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1837 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1838 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1839 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1840 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1841 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1842 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1843 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1844 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1845 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1846 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1847 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1848 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1849 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1850 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1851 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1852 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1853 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1854 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1855 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1856 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1857 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1858 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1861 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1866 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1867 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1869 # define XCAST(fun) (void*)
1872 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1874 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1875 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1876 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1877 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1878 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1879 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1880 XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
1881 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1882 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1883 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1884 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1885 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1886 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1887 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1888 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1889 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1890 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1891 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1892 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1893 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1894 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1895 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1896 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1899 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1903 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1912 GLfloat old_z_clear_value;
1913 GLbitfield bitfield = 0;
1914 GLint old_stencil_clear_value;
1915 GLfloat old_color_clear_value[4];
1917 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1918 if (TRACE_ON(ddraw)) {
1921 TRACE(" rectangles : \n");
1922 for (i = 0; i < dwCount; i++) {
1923 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1929 WARN(" Warning, this function only for now clears the whole screen...\n");
1932 /* Clears the screen */
1934 if (dwFlags & D3DCLEAR_ZBUFFER) {
1935 bitfield |= GL_DEPTH_BUFFER_BIT;
1936 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1937 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1938 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1940 TRACE(" depth value : %f\n", dvZ);
1942 if (dwFlags & D3DCLEAR_STENCIL) {
1943 bitfield |= GL_STENCIL_BUFFER_BIT;
1944 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1945 glClearStencil(dwStencil);
1946 TRACE(" stencil value : %ld\n", dwStencil);
1948 if (dwFlags & D3DCLEAR_TARGET) {
1949 bitfield |= GL_COLOR_BUFFER_BIT;
1950 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1951 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1952 ((dwColor >> 8) & 0xFF) / 255.0,
1953 ((dwColor >> 0) & 0xFF) / 255.0,
1954 ((dwColor >> 24) & 0xFF) / 255.0);
1955 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1960 if (dwFlags & D3DCLEAR_ZBUFFER) {
1962 glClearDepth(old_z_clear_value);
1964 if (dwFlags & D3DCLEAR_STENCIL) {
1965 bitfield |= GL_STENCIL_BUFFER_BIT;
1966 glClearStencil(old_stencil_clear_value);
1968 if (dwFlags & D3DCLEAR_TARGET) {
1969 bitfield |= GL_COLOR_BUFFER_BIT;
1970 glClearColor(old_color_clear_value[0],
1971 old_color_clear_value[1],
1972 old_color_clear_value[2],
1973 old_color_clear_value[3]);
1982 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1983 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1984 DWORD dwFlags, LPDDBLTFX lpbltfx)
1986 if (dwFlags & DDBLT_COLORFILL) {
1987 /* This is easy to handle for the D3D Device... */
1988 DWORD color = lpbltfx->u5.dwFillColor;
1989 TRACE(" executing D3D Device override.\n");
1990 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1993 return DDERR_INVALIDPARAMS;
1997 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1998 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1999 LPRECT rsrc, DWORD trans)
2001 return DDERR_INVALIDPARAMS;
2005 d3ddevice_set_ortho(IDirect3DDeviceImpl *This)
2007 GLfloat height, width;
2008 GLfloat trans_mat[16];
2010 width = This->surface->surface_desc.dwWidth;
2011 height = This->surface->surface_desc.dwHeight;
2013 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
2014 to OpenGL screen coordinates (ie the upper left corner is not the same).
2015 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
2016 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
2017 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
2018 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
2019 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
2020 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
2022 glMatrixMode(GL_MODELVIEW);
2024 glMatrixMode(GL_PROJECTION);
2025 glLoadMatrixf(trans_mat);
2029 d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices,
2030 D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat)
2032 if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) {
2033 glMatrixMode(GL_MODELVIEW);
2034 glLoadMatrixf((float *) view_mat);
2035 glMultMatrixf((float *) world_mat);
2037 if ((matrices & PROJMAT_CHANGED) != 0) {
2038 glMatrixMode(GL_PROJECTION);
2039 glLoadMatrixf((float *) proj_mat);
2044 d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices)
2046 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
2047 if (glThis->transform_state == GL_TRANSFORM_NORMAL) {
2048 /* This will force an update of the transform state at the next drawing. */
2049 glThis->transform_state = GL_TRANSFORM_NONE;
2053 /* TODO for both these functions :
2054 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
2055 by other OpenGL code in D3D
2056 - handle the case where no 'Begin / EndScene' was done between two locks
2057 - handle the rectangles in the unlock too
2058 - handle pitch correctly...
2060 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
2062 /* First, check if we need to do anything */
2063 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
2070 glGetIntegerv(GL_READ_BUFFER, &prev_read);
2073 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
2074 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2075 /* Application wants to lock the front buffer */
2076 glReadBuffer(GL_FRONT);
2077 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2078 /* Application wants to lock the back buffer */
2079 glReadBuffer(GL_BACK);
2081 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
2084 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2085 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2087 WARN(" unsupported pixel format.\n");
2091 if (pRect == NULL) {
2094 loc_rect.bottom = This->surface_desc.dwHeight;
2095 loc_rect.right = This->surface_desc.dwWidth;
2099 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
2100 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
2101 + loc_rect.top * This->surface_desc.u1.lPitch
2102 + loc_rect.left * GET_BPP(This->surface_desc)));
2103 glReadBuffer(prev_read);
2108 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
2110 /* First, check if we need to do anything */
2111 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
2117 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
2119 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
2120 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
2121 /* Application wants to lock the front buffer */
2122 glDrawBuffer(GL_FRONT);
2123 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
2124 /* Application wants to lock the back buffer */
2125 glDrawBuffer(GL_BACK);
2127 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
2130 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
2131 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
2133 WARN(" unsupported pixel format.\n");
2137 glRasterPos2f(0.0, 0.0);
2138 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
2139 GL_RGB, buffer_type, This->surface_desc.lpSurface);
2140 glDrawBuffer(prev_draw);
2147 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
2149 IDirect3DDeviceImpl *object;
2150 IDirect3DDeviceGLImpl *gl_object;
2151 IDirectDrawSurfaceImpl *surf;
2155 XVisualInfo template;
2156 GLenum buffer = GL_FRONT;
2158 GLint max_clipping_planes = 0;
2160 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
2161 if (object == NULL) return DDERR_OUTOFMEMORY;
2163 gl_object = (IDirect3DDeviceGLImpl *) object;
2167 object->surface = surface;
2168 object->set_context = set_context;
2169 object->clear = d3ddevice_clear;
2170 object->set_matrices = d3ddevice_set_matrices;
2171 object->matrices_updated = d3ddevice_matrices_updated;
2173 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
2175 device_context = GetDC(surface->ddraw_owner->window);
2176 gl_object->display = get_display(device_context);
2177 gl_object->drawable = get_drawable(device_context);
2178 ReleaseDC(surface->ddraw_owner->window,device_context);
2181 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2182 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2184 HeapFree(GetProcessHeap(), 0, object);
2185 ERR("No visual found !\n");
2187 return DDERR_INVALIDPARAMS;
2189 TRACE(" visual found\n");
2192 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2195 if (gl_object->gl_context == NULL) {
2196 HeapFree(GetProcessHeap(), 0, object);
2197 ERR("Error in context creation !\n");
2199 return DDERR_INVALIDPARAMS;
2201 TRACE(" context created (%p)\n", gl_object->gl_context);
2204 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2205 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2206 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2207 surf->aux_ctx = (LPVOID) gl_object->display;
2208 surf->aux_data = (LPVOID) gl_object->drawable;
2209 surf->aux_flip = opengl_flip;
2214 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2216 TRACE(" no double buffering : drawing on the front buffer\n");
2220 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2221 for (; surf != NULL; surf = surf->next_attached) {
2222 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2223 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2224 /* Override the Lock / Unlock function for all these surfaces */
2225 surf->lock_update = d3ddevice_lock_update;
2226 surf->unlock_update = d3ddevice_unlock_update;
2227 /* And install also the blt / bltfast overrides */
2228 surf->aux_blt = d3ddevice_blt;
2229 surf->aux_bltfast = d3ddevice_bltfast;
2231 surf->d3ddevice = object;
2234 /* Set the various light parameters */
2235 for (light = 0; light < MAX_LIGHTS; light++) {
2236 /* Only set the fields that are not zero-created */
2237 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2238 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2239 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2240 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2241 object->light_parameters[light].dvDirection.u3.z = 1.0;
2244 /* Allocate memory for the matrices */
2245 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2246 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2247 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2248 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2249 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2250 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2252 /* allocate the clipping planes */
2253 glGetIntegerv(GL_MAX_CLIP_PLANES,&max_clipping_planes);
2254 if (max_clipping_planes>32) {
2255 object->max_clipping_planes=32;
2257 object->max_clipping_planes = max_clipping_planes;
2259 TRACE(" capable of %d clipping planes\n", (int)object->max_clipping_planes );
2260 object->clipping_planes = (d3d7clippingplane*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane));
2262 /* Initialisation */
2263 TRACE(" setting current context\n");
2265 object->set_context(object);
2267 TRACE(" current context set\n");
2269 glClearColor(0.0, 0.0, 0.0, 0.0);
2270 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2271 glDrawBuffer(buffer);
2272 glReadBuffer(buffer);
2273 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2276 /* fill_device_capabilities(d3d->ddraw); */
2278 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2279 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2280 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2281 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2285 TRACE(" creating implementation at %p.\n", *obj);
2287 /* And finally warn D3D that this device is now present */
2288 object->d3d->added_device(object->d3d, object);
2290 /* FIXME: Should handle other versions than just 7 */
2291 InitDefaultStateBlock(&object->state_block, 7);
2292 /* Apply default render state values */
2293 apply_render_state(object, &object->state_block);
2294 /* FIXME: do something similar for ligh_state and texture_stage_state */