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
31 #include "wine/debug.h"
33 #include "mesa_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
40 /* They are non-static as they are used by Direct3D in the creation function */
41 const GUID IID_D3DDEVICE_OpenGL = {
45 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
48 #ifndef HAVE_GLEXT_PROTOTYPES
49 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
50 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
51 GLsizei width, GLenum format, GLenum type,
55 static const float id_mat[16] = {
62 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
63 D3DPRIMITIVETYPE d3dptPrimitiveType,
64 DWORD d3dvtVertexType,
65 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
72 /* retrieve the X display to use on a given DC */
73 inline static Display *get_display( HDC hdc )
76 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
78 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
79 sizeof(display), (LPSTR)&display )) display = NULL;
85 /* retrieve the X drawable to use on a given DC */
86 inline static Drawable get_drawable( HDC hdc )
89 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
91 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
92 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
98 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
100 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
102 glXSwapBuffers((Display*)display,(Drawable)drawable);
108 /*******************************************************************************
109 * OpenGL static functions
111 static void set_context(IDirect3DDeviceImpl* This)
113 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
116 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
117 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
118 ERR("Error in setting current context (context %p drawable %ld)!\n",
119 glThis->gl_context, glThis->drawable);
124 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
126 pc->dwSize = sizeof(*pc);
127 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
128 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
129 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
130 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
131 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
132 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
133 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
134 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
135 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
136 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
137 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
138 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
139 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
140 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
141 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
142 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
143 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
144 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
145 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
146 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
147 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
148 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
149 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
150 pc->dwStippleWidth = 32;
151 pc->dwStippleHeight = 32;
154 static void fill_opengl_caps(D3DDEVICEDESC *d1)
156 /* GLint maxlight; */
158 d1->dwSize = sizeof(*d1);
159 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
160 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
161 d1->dcmColorModel = D3DCOLOR_RGB;
162 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
163 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
164 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
165 /* D3D 7 capabilities */
166 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
167 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
168 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
169 d1->bClipping = TRUE;
170 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
171 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
172 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
173 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
174 fill_opengl_primcaps(&(d1->dpcLineCaps));
175 fill_opengl_primcaps(&(d1->dpcTriCaps));
176 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
177 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
178 d1->dwMaxBufferSize = 0;
179 d1->dwMaxVertexCount = 65536;
180 d1->dwMinTextureWidth = 1;
181 d1->dwMinTextureHeight = 1;
182 d1->dwMaxTextureWidth = 1024;
183 d1->dwMaxTextureHeight = 1024;
184 d1->dwMinStippleWidth = 1;
185 d1->dwMinStippleHeight = 1;
186 d1->dwMaxStippleWidth = 32;
187 d1->dwMaxStippleHeight = 32;
188 d1->dwMaxTextureRepeat = 16;
189 d1->dwMaxTextureAspectRatio = 1024;
190 d1->dwMaxAnisotropy = 0;
191 d1->dvGuardBandLeft = 0.0;
192 d1->dvGuardBandRight = 0.0;
193 d1->dvGuardBandTop = 0.0;
194 d1->dvGuardBandBottom = 0.0;
195 d1->dvExtentsAdjust = 0.0;
196 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
197 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
198 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
199 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
200 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
201 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
204 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
208 /* Copy first D3D1/2/3 capabilities */
209 fill_opengl_caps(&d1);
211 /* And fill the D3D7 one with it */
212 d->dwDevCaps = d1.dwDevCaps;
213 d->dpcLineCaps = d1.dpcLineCaps;
214 d->dpcTriCaps = d1.dpcTriCaps;
215 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
216 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
217 d->dwMinTextureWidth = d1.dwMinTextureWidth;
218 d->dwMinTextureHeight = d1.dwMinTextureHeight;
219 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
220 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
221 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
222 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
223 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
224 d->dvGuardBandLeft = d1.dvGuardBandLeft;
225 d->dvGuardBandTop = d1.dvGuardBandTop;
226 d->dvGuardBandRight = d1.dvGuardBandRight;
227 d->dvGuardBandBottom = d1.dvGuardBandBottom;
228 d->dvExtentsAdjust = d1.dvExtentsAdjust;
229 d->dwStencilCaps = d1.dwStencilCaps;
230 d->dwFVFCaps = d1.dwFVFCaps;
231 d->dwTextureOpCaps = d1.dwTextureOpCaps;
232 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
233 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
234 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
235 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
236 d->deviceGUID = IID_IDirect3DTnLHalDevice;
237 d->wMaxUserClipPlanes = 1;
238 d->wMaxVertexBlendMatrices = 0;
239 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
240 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
247 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
248 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
250 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
251 const char *ext_string;
252 Mesa_DeviceCapabilities *devcap;
254 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
255 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
258 ext_string = glGetString(GL_EXTENSIONS);
259 /* Query for the ColorTable Extension */
260 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
261 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
262 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
264 TRACE("Color table extension not found.\n");
272 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
274 D3DDEVICEDESC d1, d2;
276 fill_opengl_caps(&d1);
279 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
280 return cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
283 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
285 D3DDEVICEDESC7 ddesc;
287 fill_opengl_caps_7(&ddesc);
289 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
291 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
295 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
297 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
298 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
300 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
301 if (!--(This->ref)) {
302 /* Release texture associated with the device */
303 if (This->current_texture[0] != NULL)
304 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
306 /* And warn the D3D object that this device is no longer active... */
307 This->d3d->removed_device(This->d3d, This);
309 HeapFree(GetProcessHeap(), 0, This->world_mat);
310 HeapFree(GetProcessHeap(), 0, This->view_mat);
311 HeapFree(GetProcessHeap(), 0, This->proj_mat);
314 glXDestroyContext(glThis->display, glThis->gl_context);
317 HeapFree(GetProcessHeap(), 0, This);
324 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
325 LPD3DDEVICEDESC lpD3DHWDevDesc,
326 LPD3DDEVICEDESC lpD3DHELDevDesc)
328 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
332 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
334 fill_opengl_caps(&desc);
335 dwSize = lpD3DHWDevDesc->dwSize;
336 memset(lpD3DHWDevDesc, 0, dwSize);
337 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
339 dwSize = lpD3DHELDevDesc->dwSize;
340 memset(lpD3DHELDevDesc, 0, dwSize);
341 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
343 TRACE(" returning caps : (no dump function yet)\n");
348 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
349 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
353 LPDDPIXELFORMAT pformat;
355 /* Do the texture enumeration */
356 sdesc.dwSize = sizeof(DDSURFACEDESC);
357 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
358 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
359 pformat = &(sdesc.ddpfPixelFormat);
360 pformat->dwSize = sizeof(DDPIXELFORMAT);
361 pformat->dwFourCC = 0;
363 TRACE("Enumerating GL_RGBA unpacked (32)\n");
364 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
365 pformat->u1.dwRGBBitCount = 32;
366 pformat->u2.dwRBitMask = 0xFF000000;
367 pformat->u3.dwGBitMask = 0x00FF0000;
368 pformat->u4.dwBBitMask = 0x0000FF00;
369 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
370 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
371 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
373 TRACE("Enumerating GL_RGB unpacked (24)\n");
374 pformat->dwFlags = DDPF_RGB;
375 pformat->u1.dwRGBBitCount = 24;
376 pformat->u2.dwRBitMask = 0x00FF0000;
377 pformat->u3.dwGBitMask = 0x0000FF00;
378 pformat->u4.dwBBitMask = 0x000000FF;
379 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
380 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
381 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
383 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
384 pformat->dwFlags = DDPF_RGB;
385 pformat->u1.dwRGBBitCount = 16;
386 pformat->u2.dwRBitMask = 0x0000F800;
387 pformat->u3.dwGBitMask = 0x000007E0;
388 pformat->u4.dwBBitMask = 0x0000001F;
389 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
390 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
391 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
393 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
394 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
395 pformat->u1.dwRGBBitCount = 16;
396 pformat->u2.dwRBitMask = 0x0000F800;
397 pformat->u3.dwGBitMask = 0x000007C0;
398 pformat->u4.dwBBitMask = 0x0000003E;
399 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
400 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
401 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
403 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
404 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
405 pformat->u1.dwRGBBitCount = 16;
406 pformat->u2.dwRBitMask = 0x0000F000;
407 pformat->u3.dwGBitMask = 0x00000F00;
408 pformat->u4.dwBBitMask = 0x000000F0;
409 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
410 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
411 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
413 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (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 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
434 pformat->dwFlags = DDPF_RGB;
435 pformat->u1.dwRGBBitCount = 8;
436 pformat->u2.dwRBitMask = 0x000000E0;
437 pformat->u3.dwGBitMask = 0x0000001C;
438 pformat->u4.dwBBitMask = 0x00000003;
439 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
440 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
441 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
443 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
444 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
445 pformat->u1.dwRGBBitCount = 16;
446 pformat->u2.dwRBitMask = 0x00007C00;
447 pformat->u3.dwGBitMask = 0x000003E0;
448 pformat->u4.dwBBitMask = 0x0000001F;
449 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
450 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
451 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
453 TRACE("Enumerating Paletted (8)\n");
454 pformat->dwFlags = DDPF_PALETTEINDEXED8;
455 pformat->u1.dwRGBBitCount = 8;
456 pformat->u2.dwRBitMask = 0x00000000;
457 pformat->u3.dwGBitMask = 0x00000000;
458 pformat->u4.dwBBitMask = 0x00000000;
459 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
460 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
461 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
463 TRACE("End of enumeration\n");
469 d3ddevice_find(IDirect3DImpl *d3d,
470 LPD3DFINDDEVICESEARCH lpD3DDFS,
471 LPD3DFINDDEVICERESULT lplpD3DDevice)
475 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
476 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
477 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
478 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
480 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
481 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
482 if ((IsEqualGUID( &IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
483 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0)) {
484 TRACE(" no match for this GUID.\n");
485 return DDERR_INVALIDPARAMS;
489 /* Now return our own GUID */
490 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
491 fill_opengl_caps(&desc);
492 lplpD3DDevice->ddHwDesc = desc;
493 lplpD3DDevice->ddSwDesc = desc;
495 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
501 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
502 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
505 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
506 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
507 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
511 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
512 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
515 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
516 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
517 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
521 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
522 D3DRENDERSTATETYPE dwRenderStateType,
525 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
526 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
527 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
529 /* Call the render state functions */
530 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
536 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
537 D3DLIGHTSTATETYPE dwLightStateType,
540 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
541 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
543 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
545 switch (dwLightStateType) {
546 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
547 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
554 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
558 case D3DLIGHTSTATE_AMBIENT: /* 2 */
559 /* Call the render_state function... */
560 set_render_state(D3DRENDERSTATE_AMBIENT, dwLightState, &(glThis->render_state));
563 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
573 TRACE("Unexpected Light State Type\n");
574 return DDERR_INVALIDPARAMS;
581 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
582 D3DTRANSFORMSTATETYPE dtstTransformStateType,
583 LPD3DMATRIX lpD3DMatrix)
585 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
586 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
588 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
592 /* Using a trial and failure approach, I found that the order of
593 Direct3D transformations that works best is :
595 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
597 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
598 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
600 If anyone has a good explanation of the three different matrices in
601 the SDK online documentation, feel free to point it to me. For example,
602 which matrices transform lights ? In OpenGL only the PROJECTION matrix
603 transform the lights, not the MODELVIEW. Using the matrix names, I
604 supposed that PROJECTION and VIEW (all 'camera' related names) do
605 transform lights, but WORLD do not. It may be wrong though... */
607 /* After reading through both OpenGL and Direct3D documentations, I
608 thought that D3D matrices were written in 'line major mode' transposed
609 from OpenGL's 'column major mode'. But I found out that a simple memcpy
610 works fine to transfer one matrix format to the other (it did not work
611 when transposing)....
614 1) are the documentations wrong
615 2) does the matrix work even if they are not read correctly
616 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
617 loading using glLoadMatrix ?
619 Anyway, I always use 'conv_mat' to transfer the matrices from one format
620 to the other so that if I ever find out that I need to transpose them, I
621 will able to do it quickly, only by changing the macro conv_mat. */
623 switch (dtstTransformStateType) {
624 case D3DTRANSFORMSTATE_WORLD: {
625 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
626 conv_mat(lpD3DMatrix, This->world_mat);
627 if (glThis->last_vertices_transformed == FALSE) {
628 glMatrixMode(GL_MODELVIEW);
629 glLoadMatrixf((float *) This->view_mat);
630 glMultMatrixf((float *) This->world_mat);
634 case D3DTRANSFORMSTATE_VIEW: {
635 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
636 conv_mat(lpD3DMatrix, This->view_mat);
637 if (glThis->last_vertices_transformed == FALSE) {
638 glMatrixMode(GL_MODELVIEW);
639 glLoadMatrixf((float *) This->view_mat);
640 glMultMatrixf((float *) This->world_mat);
644 case D3DTRANSFORMSTATE_PROJECTION: {
645 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
646 conv_mat(lpD3DMatrix, This->proj_mat);
647 if (glThis->last_vertices_transformed == FALSE) {
648 glMatrixMode(GL_PROJECTION);
649 glLoadMatrixf((float *) This->proj_mat);
654 ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
662 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
665 case D3DPT_POINTLIST:
666 TRACE("Start POINTS\n");
671 TRACE("Start LINES\n");
675 case D3DPT_LINESTRIP:
676 TRACE("Start LINE_STRIP\n");
677 glBegin(GL_LINE_STRIP);
680 case D3DPT_TRIANGLELIST:
681 TRACE("Start TRIANGLES\n");
682 glBegin(GL_TRIANGLES);
685 case D3DPT_TRIANGLESTRIP:
686 TRACE("Start TRIANGLE_STRIP\n");
687 glBegin(GL_TRIANGLE_STRIP);
690 case D3DPT_TRIANGLEFAN:
691 TRACE("Start TRIANGLE_FAN\n");
692 glBegin(GL_TRIANGLE_FAN);
696 TRACE("Unhandled primitive\n");
701 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
702 BOOLEAN vertex_transformed,
703 BOOLEAN vertex_lit) {
704 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
706 /* Puts GL in the correct lighting / transformation mode */
707 if ((vertex_transformed == FALSE) &&
708 (glThis->last_vertices_transformed == TRUE)) {
709 /* Need to put the correct transformation again if we go from Transformed
710 vertices to non-transformed ones.
712 glMatrixMode(GL_MODELVIEW);
713 glLoadMatrixf((float *) This->view_mat);
714 glMultMatrixf((float *) This->world_mat);
715 glMatrixMode(GL_PROJECTION);
716 glLoadMatrixf((float *) This->proj_mat);
718 if (glThis->render_state.fog_on == TRUE) glEnable(GL_FOG);
719 } else if ((vertex_transformed == TRUE) &&
720 (glThis->last_vertices_transformed == FALSE)) {
721 GLfloat height, width;
722 GLfloat trans_mat[16];
724 width = glThis->parent.surface->surface_desc.dwWidth;
725 height = glThis->parent.surface->surface_desc.dwHeight;
727 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
728 to OpenGL screen coordinates (ie the upper left corner is not the same).
729 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
730 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
731 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
732 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
733 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
734 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
736 glMatrixMode(GL_MODELVIEW);
738 glMatrixMode(GL_PROJECTION);
739 glLoadMatrixf(trans_mat);
741 /* Remove also fogging... */
745 if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) {
746 glEnable(GL_LIGHTING);
747 } else if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == TRUE)) {
748 glDisable(GL_LIGHTING);
751 /* And save the current state */
752 glThis->last_vertices_transformed = vertex_transformed;
753 glThis->last_vertices_lit = vertex_lit;
757 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
758 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
760 D3DDRAWPRIMITIVESTRIDEDDATA strided;
764 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
765 strided.position.dwStride = sizeof(D3DVERTEX);
766 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
767 strided.normal.dwStride = sizeof(D3DVERTEX);
768 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
769 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
770 draw_primitive_strided_7(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
773 case D3DVT_LVERTEX: {
774 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
775 strided.position.dwStride = sizeof(D3DLVERTEX);
776 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
777 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
778 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
779 strided.specular.dwStride = sizeof(D3DLVERTEX);
780 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
781 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
782 draw_primitive_strided_7(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
785 case D3DVT_TLVERTEX: {
786 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
787 strided.position.dwStride = sizeof(D3DTLVERTEX);
788 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
789 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
790 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
791 strided.specular.dwStride = sizeof(D3DTLVERTEX);
792 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
793 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
794 draw_primitive_strided_7(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
798 FIXME("Unhandled vertex type\n");
804 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
805 D3DPRIMITIVETYPE d3dptPrimitiveType,
806 D3DVERTEXTYPE d3dvtVertexType,
811 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
812 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
815 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
822 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
823 D3DPRIMITIVETYPE d3dptPrimitiveType,
824 D3DVERTEXTYPE d3dvtVertexType,
831 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
832 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
835 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
842 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
843 LPD3DEXECUTEBUFFERDESC lpDesc,
844 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
847 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
848 IDirect3DExecuteBufferImpl *ret;
851 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
853 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
854 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
856 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
861 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
866 if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
867 if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
868 if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
869 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
870 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
871 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
872 default: TRACE(" matrix weighting not handled yet...\n");
874 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
875 elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
877 if (elements) *elements = elts;
882 void dump_flexible_vertex(DWORD d3dvtVertexType)
884 static const flag_info flags[] = {
886 FE(D3DFVF_RESERVED1),
890 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
891 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
892 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
893 GEN_CASE(D3DFVF_XYZ);
894 GEN_CASE(D3DFVF_XYZRHW);
895 GEN_CASE(D3DFVF_XYZB1);
896 GEN_CASE(D3DFVF_XYZB2);
897 GEN_CASE(D3DFVF_XYZB3);
898 GEN_CASE(D3DFVF_XYZB4);
899 GEN_CASE(D3DFVF_XYZB5);
901 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
902 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
903 GEN_CASE(D3DFVF_TEX0);
904 GEN_CASE(D3DFVF_TEX1);
905 GEN_CASE(D3DFVF_TEX2);
906 GEN_CASE(D3DFVF_TEX3);
907 GEN_CASE(D3DFVF_TEX4);
908 GEN_CASE(D3DFVF_TEX5);
909 GEN_CASE(D3DFVF_TEX6);
910 GEN_CASE(D3DFVF_TEX7);
911 GEN_CASE(D3DFVF_TEX8);
917 /* These are the various handler used in the generic path */
918 inline static void handle_xyz(D3DVALUE *coords) {
921 inline static void handle_xyzrhw(D3DVALUE *coords) {
922 if (coords[3] < 1e-8)
925 GLfloat w = 1.0 / coords[3];
927 glVertex4f(coords[0] * w,
933 inline static void handle_normal(D3DVALUE *coords) {
936 inline static void handle_specular(DWORD *color) {
937 /* Specular not handled yet properly... */
939 inline static void handle_diffuse(DWORD *color) {
940 glColor4ub((*color >> 16) & 0xFF,
941 (*color >> 8) & 0xFF,
942 (*color >> 0) & 0xFF,
943 (*color >> 24) & 0xFF);
945 inline static void handle_diffuse_and_specular(DWORD *color_d, DWORD *color_s) {
946 handle_diffuse(color_d);
948 inline static void handle_diffuse_no_alpha(DWORD *color) {
949 glColor3ub((*color >> 16) & 0xFF,
950 (*color >> 8) & 0xFF,
951 (*color >> 0) & 0xFF);
953 inline static void handle_diffuse_and_specular_no_alpha(DWORD *color_d, DWORD *color_s) {
954 handle_diffuse_no_alpha(color_d);
956 inline static void handle_texture(D3DVALUE *coords) {
957 glTexCoord2fv(coords);
959 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
960 /* For the moment, draw only the first texture.. */
961 if (tex_index == 0) glTexCoord2fv(coords);
964 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
965 D3DPRIMITIVETYPE d3dptPrimitiveType,
966 DWORD d3dvtVertexType,
967 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
974 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
975 if (TRACE_ON(ddraw)) {
976 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
980 draw_primitive_handle_GL_state(This,
981 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
982 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
983 draw_primitive_start_GL(d3dptPrimitiveType);
985 /* Some fast paths first before the generic case.... */
986 if (d3dvtVertexType == D3DFVF_VERTEX) {
989 for (index = 0; index < dwIndexCount; index++) {
990 int i = (dwIndices == NULL) ? index : dwIndices[index];
992 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
993 D3DVALUE *tex_coord =
994 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
996 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
998 handle_normal(normal);
999 handle_texture(tex_coord);
1000 handle_xyz(position);
1002 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
1003 position[0], position[1], position[2],
1004 normal[0], normal[1], normal[2],
1005 tex_coord[0], tex_coord[1]);
1007 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
1010 for (index = 0; index < dwIndexCount; index++) {
1011 int i = (dwIndices == NULL) ? index : dwIndices[index];
1013 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1015 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1016 D3DVALUE *tex_coord =
1017 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1018 D3DVALUE *position =
1019 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1021 if (glThis->render_state.alpha_blend_enable == TRUE)
1022 handle_diffuse_and_specular(color_d, color_s);
1024 handle_diffuse_and_specular_no_alpha(color_d, color_s);
1025 handle_texture(tex_coord);
1026 handle_xyzrhw(position);
1028 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1029 position[0], position[1], position[2], position[3],
1030 (*color_d >> 16) & 0xFF,
1031 (*color_d >> 8) & 0xFF,
1032 (*color_d >> 0) & 0xFF,
1033 (*color_d >> 24) & 0xFF,
1034 (*color_s >> 16) & 0xFF,
1035 (*color_s >> 8) & 0xFF,
1036 (*color_s >> 0) & 0xFF,
1037 (*color_s >> 24) & 0xFF,
1038 tex_coord[0], tex_coord[1]);
1040 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1041 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1042 /* This is the 'slow path' but that should support all possible vertex formats out there...
1043 Note that people should write a fast path for all vertex formats out there...
1046 for (index = 0; index < dwIndexCount; index++) {
1047 int i = (dwIndices == NULL) ? index : dwIndices[index];
1049 if (d3dvtVertexType & D3DFVF_NORMAL) {
1051 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1052 handle_normal(normal);
1054 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1056 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1058 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1059 if (glThis->render_state.alpha_blend_enable == TRUE)
1060 handle_diffuse_and_specular(color_d, color_s);
1062 handle_diffuse_and_specular_no_alpha(color_d, color_s);
1064 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1066 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1067 handle_specular(color_s);
1068 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1070 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1071 if (glThis->render_state.alpha_blend_enable == TRUE)
1072 handle_diffuse(color_d);
1074 handle_diffuse_no_alpha(color_d);
1078 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1079 /* Special case for single texture... */
1080 D3DVALUE *tex_coord =
1081 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1082 handle_texture(tex_coord);
1085 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1086 D3DVALUE *tex_coord =
1087 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1088 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1089 handle_textures(tex_coord, tex_index);
1092 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1093 D3DVALUE *position =
1094 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1095 handle_xyz(position);
1096 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1097 D3DVALUE *position =
1098 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1099 handle_xyzrhw(position);
1102 if (TRACE_ON(ddraw)) {
1105 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1106 D3DVALUE *position =
1107 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1108 TRACE(" %f %f %f", position[0], position[1], position[2]);
1109 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1110 D3DVALUE *position =
1111 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1112 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1114 if (d3dvtVertexType & D3DFVF_NORMAL) {
1116 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1117 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1119 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1121 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1122 DPRINTF(" / %02lx %02lx %02lx %02lx",
1123 (*color_d >> 16) & 0xFF,
1124 (*color_d >> 8) & 0xFF,
1125 (*color_d >> 0) & 0xFF,
1126 (*color_d >> 24) & 0xFF);
1128 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1130 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1131 DPRINTF(" / %02lx %02lx %02lx %02lx",
1132 (*color_s >> 16) & 0xFF,
1133 (*color_s >> 8) & 0xFF,
1134 (*color_s >> 0) & 0xFF,
1135 (*color_s >> 24) & 0xFF);
1137 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1138 D3DVALUE *tex_coord =
1139 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1140 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1141 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1147 ERR(" matrix weighting not handled yet....\n");
1155 static void draw_primitive_7(IDirect3DDeviceImpl *This,
1156 D3DPRIMITIVETYPE d3dptPrimitiveType,
1157 DWORD d3dvtVertexType,
1159 DWORD dwStartVertex,
1160 DWORD dwVertexCount,
1165 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1166 int current_offset = 0;
1169 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1170 strided.position.lpvData = lpvVertices;
1171 current_offset += 3 * sizeof(D3DVALUE);
1173 strided.position.lpvData = lpvVertices;
1174 current_offset += 4 * sizeof(D3DVALUE);
1176 if (d3dvtVertexType & D3DFVF_NORMAL) {
1177 strided.normal.lpvData = ((char *) lpvVertices) + current_offset;
1178 current_offset += 3 * sizeof(D3DVALUE);
1180 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1181 strided.diffuse.lpvData = ((char *) lpvVertices) + current_offset;
1182 current_offset += sizeof(DWORD);
1184 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1185 strided.specular.lpvData = ((char *) lpvVertices) + current_offset;
1186 current_offset += sizeof(DWORD);
1188 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1189 strided.textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset;
1190 current_offset += 2 * sizeof(D3DVALUE);
1192 strided.position.dwStride = current_offset;
1193 strided.normal.dwStride = current_offset;
1194 strided.diffuse.dwStride = current_offset;
1195 strided.specular.dwStride = current_offset;
1196 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
1197 strided.textureCoords[tex_index].dwStride = current_offset;
1199 draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwStartVertex, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1203 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1204 D3DPRIMITIVETYPE d3dptPrimitiveType,
1205 DWORD d3dvtVertexType,
1207 DWORD dwVertexCount,
1210 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1211 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1213 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1219 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1220 D3DPRIMITIVETYPE d3dptPrimitiveType,
1221 DWORD d3dvtVertexType,
1223 DWORD dwVertexCount,
1228 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1229 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1231 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1237 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1238 D3DPRIMITIVETYPE d3dptPrimitiveType,
1240 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1241 DWORD dwVertexCount,
1244 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1245 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1246 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1251 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1252 D3DPRIMITIVETYPE d3dptPrimitiveType,
1254 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1255 DWORD dwVertexCount,
1260 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1261 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1262 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1267 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1268 D3DPRIMITIVETYPE d3dptPrimitiveType,
1269 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1270 DWORD dwStartVertex,
1271 DWORD dwNumVertices,
1274 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1275 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1277 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1279 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1285 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1286 D3DPRIMITIVETYPE d3dptPrimitiveType,
1287 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1288 DWORD dwStartVertex,
1289 DWORD dwNumVertices,
1294 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1295 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1297 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1299 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1305 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1307 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1310 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1311 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1314 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1316 if (TRACE_ON(ddraw)) {
1317 TRACE(" Stage type is : ");
1318 switch (d3dTexStageStateType) {
1319 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1320 GEN_CASE(D3DTSS_COLOROP);
1321 GEN_CASE(D3DTSS_COLORARG1);
1322 GEN_CASE(D3DTSS_COLORARG2);
1323 GEN_CASE(D3DTSS_ALPHAOP);
1324 GEN_CASE(D3DTSS_ALPHAARG1);
1325 GEN_CASE(D3DTSS_ALPHAARG2);
1326 GEN_CASE(D3DTSS_BUMPENVMAT00);
1327 GEN_CASE(D3DTSS_BUMPENVMAT01);
1328 GEN_CASE(D3DTSS_BUMPENVMAT10);
1329 GEN_CASE(D3DTSS_BUMPENVMAT11);
1330 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1331 GEN_CASE(D3DTSS_ADDRESS);
1332 GEN_CASE(D3DTSS_ADDRESSU);
1333 GEN_CASE(D3DTSS_ADDRESSV);
1334 GEN_CASE(D3DTSS_BORDERCOLOR);
1335 GEN_CASE(D3DTSS_MAGFILTER);
1336 GEN_CASE(D3DTSS_MINFILTER);
1337 GEN_CASE(D3DTSS_MIPFILTER);
1338 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1339 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1340 GEN_CASE(D3DTSS_MAXANISOTROPY);
1341 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1342 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1343 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1345 default: DPRINTF("UNKNOWN !!!");
1350 switch (d3dTexStageStateType) {
1351 case D3DTSS_MINFILTER:
1352 switch ((D3DTEXTUREMINFILTER) dwState) {
1354 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1355 gl_state = GL_NEAREST;
1358 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1359 gl_state = GL_LINEAR;
1362 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1363 gl_state = GL_LINEAR;
1366 glThis->render_state.min = gl_state;
1367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1370 case D3DTSS_MAGFILTER:
1371 switch ((D3DTEXTUREMAGFILTER) dwState) {
1373 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1374 gl_state = GL_NEAREST;
1377 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1378 gl_state = GL_LINEAR;
1381 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1382 gl_state = GL_LINEAR;
1385 glThis->render_state.mag = gl_state;
1386 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1389 case D3DTSS_ADDRESS:
1390 case D3DTSS_ADDRESSU:
1391 case D3DTSS_ADDRESSV: {
1392 GLenum arg = GL_REPEAT; /* Default value */
1393 switch ((D3DTEXTUREADDRESS) dwState) {
1394 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1395 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1396 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1397 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1399 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1400 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1401 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1402 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1403 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1408 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1415 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1417 LPDIRECTDRAWSURFACE7 lpTexture2)
1419 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1420 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1422 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1424 if (This->current_texture[dwStage] != NULL) {
1425 /* Seems that this is not right... Need to test in real Windows
1426 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1430 if (lpTexture2 == NULL) {
1431 TRACE(" disabling 2D texturing.\n");
1432 glBindTexture(GL_TEXTURE_2D, 0);
1433 glDisable(GL_TEXTURE_2D);
1435 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1436 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
1438 This->current_texture[dwStage] = tex_impl;
1439 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1441 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1443 glEnable(GL_TEXTURE_2D);
1444 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1445 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glThis->render_state.mag);
1446 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glThis->render_state.min);
1454 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1455 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1457 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1458 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1460 fill_opengl_caps_7(lpD3DHELDevDesc);
1462 TRACE(" returning caps : no dump function yet.\n");
1468 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface,
1469 LPD3DMATERIAL7 lpMat)
1471 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1472 TRACE("(%p/%p)->(%p)\n", This, iface, lpMat);
1474 if (TRACE_ON(ddraw)) {
1475 TRACE(" material is : \n");
1476 dump_D3DMATERIAL7(lpMat);
1479 This->current_material = *lpMat;
1481 glMaterialfv(GL_FRONT,
1483 (float *) &(This->current_material.u.diffuse));
1484 glMaterialfv(GL_FRONT,
1486 (float *) &(This->current_material.u1.ambient));
1487 glMaterialfv(GL_FRONT,
1489 (float *) &(This->current_material.u2.specular));
1490 glMaterialfv(GL_FRONT,
1492 (float *) &(This->current_material.u3.emissive));
1493 glMaterialf(GL_FRONT,
1495 This->current_material.u4.power); /* Not sure about this... */
1502 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface,
1504 LPD3DLIGHT7 lpLight)
1506 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1507 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight);
1509 if (TRACE_ON(ddraw)) {
1510 TRACE(" setting light : \n");
1511 dump_D3DLIGHT7(lpLight);
1514 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1515 This->set_lights |= 0x00000001 << dwLightIndex;
1516 This->light_parameters[dwLightIndex] = *lpLight;
1518 switch (lpLight->dltType) {
1519 case D3DLIGHT_DIRECTIONAL: { /* 3 */
1522 glLightfv(GL_LIGHT0 + dwLightIndex, GL_AMBIENT, (float *) &(lpLight->dcvAmbient));
1523 glLightfv(GL_LIGHT0 + dwLightIndex, GL_DIFFUSE, (float *) &(lpLight->dcvDiffuse));
1524 glLightfv(GL_LIGHT0 + dwLightIndex, GL_SPECULAR, (float *) &(lpLight->dcvSpecular));
1526 direction[0] = lpLight->dvDirection.u1.x;
1527 direction[1] = lpLight->dvDirection.u2.y;
1528 direction[2] = lpLight->dvDirection.u3.z;
1529 direction[3] = 0.0; /* This is a directional light */
1531 glLightfv(GL_LIGHT0 + dwLightIndex, GL_POSITION, (float *) direction);
1534 default: WARN(" light type not handled yet...\n");
1541 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface,
1545 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1546 TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable);
1548 if (dwLightIndex > MAX_LIGHTS) return DDERR_INVALIDPARAMS;
1551 if (((0x00000001 << dwLightIndex) & This->set_lights) == 0) {
1552 /* Set the default parameters.. */
1553 TRACE(" setting default light parameters...\n");
1554 GL_IDirect3DDeviceImpl_7_SetLight(iface, dwLightIndex, &(This->light_parameters[dwLightIndex]));
1556 glEnable(GL_LIGHT0 + dwLightIndex);
1558 glDisable(GL_LIGHT0 + dwLightIndex);
1564 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1565 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1567 # define XCAST(fun) (void*)
1570 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1572 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1573 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1574 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1575 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1576 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1577 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1578 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1579 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1580 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1581 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1582 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1583 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1584 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1585 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1586 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1587 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1588 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1589 XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial,
1590 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1591 XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight,
1592 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1593 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1594 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1595 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1596 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1597 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1598 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1599 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1600 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1601 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1602 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1603 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1604 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1605 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1606 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1607 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1608 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1609 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1610 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1611 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1612 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1613 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1614 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1615 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1616 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1617 XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable,
1618 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1619 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1620 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1621 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1624 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1629 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1630 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1632 # define XCAST(fun) (void*)
1635 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1637 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1638 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1639 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1640 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1641 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1642 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1643 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1644 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1645 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1646 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1647 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1648 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1649 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1650 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1651 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1652 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1653 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1654 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1655 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1656 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1657 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1658 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1659 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1660 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1661 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1662 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1663 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1664 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1665 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1666 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1667 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1668 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1669 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1670 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1671 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1672 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1673 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1674 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1675 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1676 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1677 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1678 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1679 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1682 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1687 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1688 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1690 # define XCAST(fun) (void*)
1693 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1695 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1696 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1697 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1698 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1699 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1700 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
1701 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1702 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1703 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1704 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1705 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1706 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1707 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1708 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1709 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1710 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1711 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1712 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1713 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1714 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1715 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1716 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1717 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1718 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1719 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1720 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1721 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1722 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1723 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1724 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1725 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1726 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1727 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1728 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1731 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1736 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1737 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1739 # define XCAST(fun) (void*)
1742 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1744 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1745 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1746 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1747 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1748 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1749 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1750 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
1751 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1752 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1753 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1754 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1755 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1756 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1757 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1758 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1759 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1760 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1761 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1762 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1763 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1764 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1765 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1766 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1769 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1773 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1782 GLfloat old_z_clear_value;
1783 GLbitfield bitfield = 0;
1784 GLint old_stencil_clear_value;
1785 GLfloat old_color_clear_value[4];
1787 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1788 if (TRACE_ON(ddraw)) {
1791 TRACE(" rectangles : \n");
1792 for (i = 0; i < dwCount; i++) {
1793 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1799 WARN(" Warning, this function only for now clears the whole screen...\n");
1802 /* Clears the screen */
1804 if (dwFlags & D3DCLEAR_ZBUFFER) {
1805 bitfield |= GL_DEPTH_BUFFER_BIT;
1806 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1807 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1808 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1810 TRACE(" depth value : %f\n", dvZ);
1812 if (dwFlags & D3DCLEAR_STENCIL) {
1813 bitfield |= GL_STENCIL_BUFFER_BIT;
1814 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1815 glClearStencil(dwStencil);
1816 TRACE(" stencil value : %ld\n", dwStencil);
1818 if (dwFlags & D3DCLEAR_TARGET) {
1819 bitfield |= GL_COLOR_BUFFER_BIT;
1820 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1821 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1822 ((dwColor >> 8) & 0xFF) / 255.0,
1823 ((dwColor >> 0) & 0xFF) / 255.0,
1824 ((dwColor >> 24) & 0xFF) / 255.0);
1825 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1830 if (dwFlags & D3DCLEAR_ZBUFFER) {
1832 glClearDepth(old_z_clear_value);
1834 if (dwFlags & D3DCLEAR_STENCIL) {
1835 bitfield |= GL_STENCIL_BUFFER_BIT;
1836 glClearStencil(old_stencil_clear_value);
1838 if (dwFlags & D3DCLEAR_TARGET) {
1839 bitfield |= GL_COLOR_BUFFER_BIT;
1840 glClearColor(old_color_clear_value[0],
1841 old_color_clear_value[1],
1842 old_color_clear_value[2],
1843 old_color_clear_value[3]);
1852 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1853 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1854 DWORD dwFlags, LPDDBLTFX lpbltfx)
1856 if (dwFlags & DDBLT_COLORFILL) {
1857 /* This is easy to handle for the D3D Device... */
1858 DWORD color = lpbltfx->u5.dwFillColor;
1859 TRACE(" executing D3D Device override.\n");
1860 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1863 return DDERR_INVALIDPARAMS;
1867 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1868 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1869 LPRECT rsrc, DWORD trans)
1871 return DDERR_INVALIDPARAMS;
1875 /* TODO for both these functions :
1876 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1877 by other OpenGL code in D3D
1878 - handle the case where no 'Begin / EndScene' was done between two locks
1879 - handle the rectangles in the unlock too
1880 - handle pitch correctly...
1882 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1884 /* First, check if we need to do anything */
1885 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1892 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1895 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1896 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1897 /* Application wants to lock the front buffer */
1898 glReadBuffer(GL_FRONT);
1899 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1900 /* Application wants to lock the back buffer */
1901 glReadBuffer(GL_BACK);
1903 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1906 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1907 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1909 WARN(" unsupported pixel format.\n");
1913 if (pRect == NULL) {
1916 loc_rect.bottom = This->surface_desc.dwHeight;
1917 loc_rect.right = This->surface_desc.dwWidth;
1921 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1922 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1923 + loc_rect.top * This->surface_desc.u1.lPitch
1924 + loc_rect.left * GET_BPP(This->surface_desc)));
1925 glReadBuffer(prev_read);
1930 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1932 /* First, check if we need to do anything */
1933 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1939 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1941 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1942 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1943 /* Application wants to lock the front buffer */
1944 glDrawBuffer(GL_FRONT);
1945 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1946 /* Application wants to lock the back buffer */
1947 glDrawBuffer(GL_BACK);
1949 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
1952 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1953 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1955 WARN(" unsupported pixel format.\n");
1959 glRasterPos2f(0.0, 0.0);
1960 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
1961 GL_RGB, buffer_type, This->surface_desc.lpSurface);
1962 glDrawBuffer(prev_draw);
1969 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
1971 IDirect3DDeviceImpl *object;
1972 IDirect3DDeviceGLImpl *gl_object;
1973 IDirectDrawSurfaceImpl *surf;
1977 XVisualInfo template;
1981 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1982 if (object == NULL) return DDERR_OUTOFMEMORY;
1984 gl_object = (IDirect3DDeviceGLImpl *) object;
1988 object->surface = surface;
1989 object->set_context = set_context;
1990 object->clear = d3ddevice_clear;
1992 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1994 device_context = GetDC(surface->ddraw_owner->window);
1995 gl_object->display = get_display(device_context);
1996 gl_object->drawable = get_drawable(device_context);
1997 ReleaseDC(surface->ddraw_owner->window,device_context);
2000 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2001 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
2003 HeapFree(GetProcessHeap(), 0, object);
2004 ERR("No visual found !\n");
2006 return DDERR_INVALIDPARAMS;
2008 TRACE(" visual found\n");
2011 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
2014 if (gl_object->gl_context == NULL) {
2015 HeapFree(GetProcessHeap(), 0, object);
2016 ERR("Error in context creation !\n");
2018 return DDERR_INVALIDPARAMS;
2020 TRACE(" context created (%p)\n", gl_object->gl_context);
2023 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2024 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
2025 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
2026 surf->aux_ctx = (LPVOID) gl_object->display;
2027 surf->aux_data = (LPVOID) gl_object->drawable;
2028 surf->aux_flip = opengl_flip;
2033 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2035 TRACE(" no double buffering : drawing on the front buffer\n");
2039 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
2040 for (; surf != NULL; surf = surf->next_attached) {
2041 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
2042 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
2043 /* Override the Lock / Unlock function for all these surfaces */
2044 surf->lock_update = d3ddevice_lock_update;
2045 surf->unlock_update = d3ddevice_unlock_update;
2046 /* And install also the blt / bltfast overrides */
2047 surf->aux_blt = d3ddevice_blt;
2048 surf->aux_bltfast = d3ddevice_bltfast;
2050 surf->d3ddevice = object;
2053 gl_object->render_state.src = GL_ONE;
2054 gl_object->render_state.dst = GL_ZERO;
2055 gl_object->render_state.mag = GL_NEAREST;
2056 gl_object->render_state.min = GL_NEAREST;
2057 gl_object->render_state.alpha_ref = 0.0; /* No actual idea about the real default value... */
2058 gl_object->render_state.alpha_func = GL_ALWAYS; /* Here either but it seems logical */
2059 gl_object->render_state.alpha_blend_enable = FALSE;
2060 gl_object->render_state.fog_on = FALSE;
2061 gl_object->render_state.stencil_func = GL_ALWAYS;
2062 gl_object->render_state.stencil_mask = 0xFFFFFFFF;
2063 gl_object->render_state.stencil_ref = 0;
2064 gl_object->render_state.stencil_enable = FALSE;
2065 gl_object->render_state.stencil_fail = GL_KEEP;
2066 gl_object->render_state.stencil_zfail = GL_KEEP;
2067 gl_object->render_state.stencil_pass = GL_KEEP;
2068 gl_object->render_state.lighting_enable = FALSE;
2069 gl_object->render_state.specular_enable = FALSE;
2070 gl_object->render_state.color_diffuse = D3DMCS_COLOR1;
2071 gl_object->render_state.color_specular = D3DMCS_COLOR2;
2072 gl_object->render_state.color_ambient = D3DMCS_COLOR2;
2073 gl_object->render_state.color_emissive = D3DMCS_MATERIAL;
2075 /* Set the various light parameters */
2076 for (light = 0; light < MAX_LIGHTS; light++) {
2077 /* Only set the fields that are not zero-created */
2078 object->light_parameters[light].dltType = D3DLIGHT_DIRECTIONAL;
2079 object->light_parameters[light].dcvDiffuse.u1.r = 1.0;
2080 object->light_parameters[light].dcvDiffuse.u2.g = 1.0;
2081 object->light_parameters[light].dcvDiffuse.u3.b = 1.0;
2082 object->light_parameters[light].dvDirection.u3.z = 1.0;
2085 /* Allocate memory for the matrices */
2086 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2087 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2088 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
2089 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
2090 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
2091 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
2093 /* Initialisation */
2094 TRACE(" setting current context\n");
2096 object->set_context(object);
2098 TRACE(" current context set\n");
2099 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
2100 glClearColor(0.0, 0.0, 0.0, 0.0);
2101 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2102 glDrawBuffer(buffer);
2103 glReadBuffer(buffer);
2104 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2107 /* fill_device_capabilities(d3d->ddraw); */
2109 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
2110 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
2111 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
2112 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
2116 TRACE(" creating implementation at %p.\n", *obj);
2118 /* And finally warn D3D that this device is now present */
2119 object->d3d->added_device(object->d3d, object);