- added some tracing in the fake ZBuffer methods
[wine/multimedia.git] / dlls / ddraw / d3ddevice / mesa.c
blob468e0c0d8a643083179ff811e14209dc04233ad1
1 /* Direct3D Device
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the MESA implementation of all the D3D devices that
5 * Wine supports.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
24 #include <string.h>
26 #include "windef.h"
27 #include "winerror.h"
28 #include "objbase.h"
29 #include "ddraw.h"
30 #include "d3d.h"
31 #include "wine/debug.h"
33 #include "mesa_private.h"
34 #include "main.h"
36 #include "x11drv.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
40 /* They are non-static as they are used by Direct3D in the creation function */
41 const GUID IID_D3DDEVICE_OpenGL = {
42 0x31416d44,
43 0x86ae,
44 0x11d2,
45 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
48 #ifndef HAVE_GLEXT_PROTOTYPES
49 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
50 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
51 GLsizei width, GLenum format, GLenum type,
52 const GLvoid *table);
53 #endif
55 static const float id_mat[16] = {
56 1.0, 0.0, 0.0, 0.0,
57 0.0, 1.0, 0.0, 0.0,
58 0.0, 0.0, 1.0, 0.0,
59 0.0, 0.0, 0.0, 1.0
62 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
63 D3DPRIMITIVETYPE d3dptPrimitiveType,
64 DWORD d3dvtVertexType,
65 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
66 DWORD dwStartVertex,
67 DWORD dwVertexCount,
68 LPWORD dwIndices,
69 DWORD dwIndexCount,
70 DWORD dwFlags) ;
72 /* retrieve the X display to use on a given DC */
73 inline static Display *get_display( HDC hdc )
75 Display *display;
76 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
78 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
79 sizeof(display), (LPSTR)&display )) display = NULL;
81 return display;
85 /* retrieve the X drawable to use on a given DC */
86 inline static Drawable get_drawable( HDC hdc )
88 Drawable drawable;
89 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
91 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
92 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
94 return drawable;
98 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
100 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
101 ENTER_GL();
102 glXSwapBuffers((Display*)display,(Drawable)drawable);
103 LEAVE_GL();
104 return TRUE;
108 /*******************************************************************************
109 * OpenGL static functions
111 static void set_context(IDirect3DDeviceImpl* This)
113 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
115 ENTER_GL();
116 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
117 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
118 ERR("Error in setting current context (context %p drawable %ld)!\n",
119 glThis->gl_context, glThis->drawable);
121 LEAVE_GL();
124 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
126 pc->dwSize = sizeof(*pc);
127 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
128 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
129 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
130 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
131 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
132 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
133 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
134 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
135 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
136 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
137 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
138 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
139 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
140 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
141 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
142 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
143 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
144 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
145 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
146 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
147 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
148 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
149 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
150 pc->dwStippleWidth = 32;
151 pc->dwStippleHeight = 32;
154 static void fill_opengl_caps(D3DDEVICEDESC *d1)
156 /* GLint maxlight; */
158 d1->dwSize = sizeof(*d1);
159 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
160 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
161 d1->dcmColorModel = D3DCOLOR_RGB;
162 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
163 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
164 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
165 /* D3D 7 capabilities */
166 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
167 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
168 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
169 d1->bClipping = TRUE;
170 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
171 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
172 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
173 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
174 fill_opengl_primcaps(&(d1->dpcLineCaps));
175 fill_opengl_primcaps(&(d1->dpcTriCaps));
176 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
177 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
178 d1->dwMaxBufferSize = 0;
179 d1->dwMaxVertexCount = 65536;
180 d1->dwMinTextureWidth = 1;
181 d1->dwMinTextureHeight = 1;
182 d1->dwMaxTextureWidth = 1024;
183 d1->dwMaxTextureHeight = 1024;
184 d1->dwMinStippleWidth = 1;
185 d1->dwMinStippleHeight = 1;
186 d1->dwMaxStippleWidth = 32;
187 d1->dwMaxStippleHeight = 32;
188 d1->dwMaxTextureRepeat = 16;
189 d1->dwMaxTextureAspectRatio = 1024;
190 d1->dwMaxAnisotropy = 0;
191 d1->dvGuardBandLeft = 0.0;
192 d1->dvGuardBandRight = 0.0;
193 d1->dvGuardBandTop = 0.0;
194 d1->dvGuardBandBottom = 0.0;
195 d1->dvExtentsAdjust = 0.0;
196 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
197 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
198 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
199 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
200 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
201 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
204 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
206 D3DDEVICEDESC d1;
208 /* Copy first D3D1/2/3 capabilities */
209 fill_opengl_caps(&d1);
211 /* And fill the D3D7 one with it */
212 d->dwDevCaps = d1.dwDevCaps;
213 d->dpcLineCaps = d1.dpcLineCaps;
214 d->dpcTriCaps = d1.dpcTriCaps;
215 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
216 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
217 d->dwMinTextureWidth = d1.dwMinTextureWidth;
218 d->dwMinTextureHeight = d1.dwMinTextureHeight;
219 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
220 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
221 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
222 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
223 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
224 d->dvGuardBandLeft = d1.dvGuardBandLeft;
225 d->dvGuardBandTop = d1.dvGuardBandTop;
226 d->dvGuardBandRight = d1.dvGuardBandRight;
227 d->dvGuardBandBottom = d1.dvGuardBandBottom;
228 d->dvExtentsAdjust = d1.dvExtentsAdjust;
229 d->dwStencilCaps = d1.dwStencilCaps;
230 d->dwFVFCaps = d1.dwFVFCaps;
231 d->dwTextureOpCaps = d1.dwTextureOpCaps;
232 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
233 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
234 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
235 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
236 d->deviceGUID = IID_IDirect3DTnLHalDevice;
237 d->wMaxUserClipPlanes = 1;
238 d->wMaxVertexBlendMatrices = 0;
239 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
240 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
241 d->dwReserved1 = 0;
242 d->dwReserved2 = 0;
243 d->dwReserved3 = 0;
244 d->dwReserved4 = 0;
247 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
248 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
250 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
251 const char *ext_string;
252 Mesa_DeviceCapabilities *devcap;
254 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
255 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
257 ENTER_GL();
258 ext_string = glGetString(GL_EXTENSIONS);
259 /* Query for the ColorTable Extension */
260 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
261 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
262 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
263 } else {
264 TRACE("Color table extension not found.\n");
266 LEAVE_GL();
268 #endif
272 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
274 D3DDEVICEDESC d1, d2;
276 fill_opengl_caps(&d1);
277 d2 = 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);
294 ULONG WINAPI
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);
313 ENTER_GL();
314 glXDestroyContext(glThis->display, glThis->gl_context);
315 LEAVE_GL();
317 HeapFree(GetProcessHeap(), 0, This);
318 return 0;
320 return This->ref;
323 HRESULT WINAPI
324 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
325 LPD3DDEVICEDESC lpD3DHWDevDesc,
326 LPD3DDEVICEDESC lpD3DHELDevDesc)
328 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
329 D3DDEVICEDESC desc;
330 DWORD dwSize;
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");
345 return DD_OK;
348 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
349 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
350 LPVOID context)
352 DDSURFACEDESC sdesc;
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");
464 return DD_OK;
468 HRESULT
469 d3ddevice_find(IDirect3DImpl *d3d,
470 LPD3DFINDDEVICESEARCH lpD3DDFS,
471 LPD3DFINDDEVICERESULT lplpD3DDevice)
473 D3DDEVICEDESC desc;
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");
497 return D3D_OK;
500 HRESULT WINAPI
501 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
502 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
503 LPVOID lpArg)
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);
510 HRESULT WINAPI
511 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
512 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
513 LPVOID lpArg)
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);
520 HRESULT WINAPI
521 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
522 D3DRENDERSTATETYPE dwRenderStateType,
523 DWORD dwRenderState)
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));
532 return DD_OK;
535 HRESULT WINAPI
536 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
537 D3DLIGHTSTATETYPE dwLightStateType,
538 DWORD dwLightState)
540 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
541 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
543 switch (dwLightStateType) {
544 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
545 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
547 if (mat != NULL) {
548 ENTER_GL();
549 mat->activate(mat);
550 LEAVE_GL();
551 } else {
552 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
554 } break;
556 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
557 float light[4];
559 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
560 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
561 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
562 light[3] = 1.0;
563 ENTER_GL();
564 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
565 LEAVE_GL();
566 } break;
568 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
569 UNSUP(COLORMODEL);
570 UNSUP(FOGMODE);
571 UNSUP(FOGSTART);
572 UNSUP(FOGEND);
573 UNSUP(FOGDENSITY);
574 UNSUP(COLORVERTEX);
575 #undef UNSUP
577 default:
578 TRACE("Unexpected Light State Type\n");
579 return DDERR_INVALIDPARAMS;
582 return DD_OK;
585 HRESULT WINAPI
586 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
587 D3DTRANSFORMSTATETYPE dtstTransformStateType,
588 LPD3DMATRIX lpD3DMatrix)
590 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
591 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
593 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
595 ENTER_GL();
597 /* Using a trial and failure approach, I found that the order of
598 Direct3D transformations that works best is :
600 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
602 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
603 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
605 If anyone has a good explanation of the three different matrices in
606 the SDK online documentation, feel free to point it to me. For example,
607 which matrices transform lights ? In OpenGL only the PROJECTION matrix
608 transform the lights, not the MODELVIEW. Using the matrix names, I
609 supposed that PROJECTION and VIEW (all 'camera' related names) do
610 transform lights, but WORLD do not. It may be wrong though... */
612 /* After reading through both OpenGL and Direct3D documentations, I
613 thought that D3D matrices were written in 'line major mode' transposed
614 from OpenGL's 'column major mode'. But I found out that a simple memcpy
615 works fine to transfer one matrix format to the other (it did not work
616 when transposing)....
618 So :
619 1) are the documentations wrong
620 2) does the matrix work even if they are not read correctly
621 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
622 loading using glLoadMatrix ?
624 Anyway, I always use 'conv_mat' to transfer the matrices from one format
625 to the other so that if I ever find out that I need to transpose them, I
626 will able to do it quickly, only by changing the macro conv_mat. */
628 switch (dtstTransformStateType) {
629 case D3DTRANSFORMSTATE_WORLD: {
630 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
631 conv_mat(lpD3DMatrix, This->world_mat);
632 if (glThis->last_vertices_transformed == FALSE) {
633 glMatrixMode(GL_MODELVIEW);
634 glLoadMatrixf((float *) This->view_mat);
635 glMultMatrixf((float *) This->world_mat);
637 } break;
639 case D3DTRANSFORMSTATE_VIEW: {
640 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
641 conv_mat(lpD3DMatrix, This->view_mat);
642 if (glThis->last_vertices_transformed == FALSE) {
643 glMatrixMode(GL_MODELVIEW);
644 glLoadMatrixf((float *) This->view_mat);
645 glMultMatrixf((float *) This->world_mat);
647 } break;
649 case D3DTRANSFORMSTATE_PROJECTION: {
650 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
651 conv_mat(lpD3DMatrix, This->proj_mat);
652 if (glThis->last_vertices_transformed == FALSE) {
653 glMatrixMode(GL_PROJECTION);
654 glLoadMatrixf((float *) This->proj_mat);
656 } break;
658 default:
659 ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
660 break;
662 LEAVE_GL();
664 return DD_OK;
667 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
669 switch (d3dpt) {
670 case D3DPT_POINTLIST:
671 TRACE("Start POINTS\n");
672 glBegin(GL_POINTS);
673 break;
675 case D3DPT_LINELIST:
676 TRACE("Start LINES\n");
677 glBegin(GL_LINES);
678 break;
680 case D3DPT_LINESTRIP:
681 TRACE("Start LINE_STRIP\n");
682 glBegin(GL_LINE_STRIP);
683 break;
685 case D3DPT_TRIANGLELIST:
686 TRACE("Start TRIANGLES\n");
687 glBegin(GL_TRIANGLES);
688 break;
690 case D3DPT_TRIANGLESTRIP:
691 TRACE("Start TRIANGLE_STRIP\n");
692 glBegin(GL_TRIANGLE_STRIP);
693 break;
695 case D3DPT_TRIANGLEFAN:
696 TRACE("Start TRIANGLE_FAN\n");
697 glBegin(GL_TRIANGLE_FAN);
698 break;
700 default:
701 TRACE("Unhandled primitive\n");
702 break;
706 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
707 BOOLEAN vertex_transformed,
708 BOOLEAN vertex_lit) {
709 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
711 /* Puts GL in the correct lighting / transformation mode */
712 if ((vertex_transformed == FALSE) &&
713 (glThis->last_vertices_transformed == TRUE)) {
714 /* Need to put the correct transformation again if we go from Transformed
715 vertices to non-transformed ones.
717 glMatrixMode(GL_MODELVIEW);
718 glLoadMatrixf((float *) This->view_mat);
719 glMultMatrixf((float *) This->world_mat);
720 glMatrixMode(GL_PROJECTION);
721 glLoadMatrixf((float *) This->proj_mat);
723 if (glThis->render_state.fog_on == TRUE) glEnable(GL_FOG);
724 } else if ((vertex_transformed == TRUE) &&
725 (glThis->last_vertices_transformed == FALSE)) {
726 GLfloat height, width;
727 GLfloat trans_mat[16];
729 width = glThis->parent.surface->surface_desc.dwWidth;
730 height = glThis->parent.surface->surface_desc.dwHeight;
732 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
733 to OpenGL screen coordinates (ie the upper left corner is not the same).
734 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
735 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
736 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
737 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
738 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
739 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
741 glMatrixMode(GL_MODELVIEW);
742 glLoadIdentity();
743 glMatrixMode(GL_PROJECTION);
744 glLoadMatrixf(trans_mat);
746 /* Remove also fogging... */
747 glDisable(GL_FOG);
750 if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) {
751 glEnable(GL_LIGHTING);
752 } else if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == TRUE)) {
753 glDisable(GL_LIGHTING);
756 /* And save the current state */
757 glThis->last_vertices_transformed = vertex_transformed;
758 glThis->last_vertices_lit = vertex_lit;
762 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
763 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
765 D3DDRAWPRIMITIVESTRIDEDDATA strided;
767 switch (d3dvt) {
768 case D3DVT_VERTEX: {
769 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
770 strided.position.dwStride = sizeof(D3DVERTEX);
771 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
772 strided.normal.dwStride = sizeof(D3DVERTEX);
773 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
774 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
775 draw_primitive_strided_7(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
776 } break;
778 case D3DVT_LVERTEX: {
779 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
780 strided.position.dwStride = sizeof(D3DLVERTEX);
781 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
782 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
783 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
784 strided.specular.dwStride = sizeof(D3DLVERTEX);
785 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
786 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
787 draw_primitive_strided_7(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
788 } break;
790 case D3DVT_TLVERTEX: {
791 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
792 strided.position.dwStride = sizeof(D3DTLVERTEX);
793 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
794 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
795 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
796 strided.specular.dwStride = sizeof(D3DTLVERTEX);
797 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
798 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
799 draw_primitive_strided_7(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
800 } break;
802 default:
803 FIXME("Unhandled vertex type\n");
804 break;
808 HRESULT WINAPI
809 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
810 D3DPRIMITIVETYPE d3dptPrimitiveType,
811 D3DVERTEXTYPE d3dvtVertexType,
812 LPVOID lpvVertices,
813 DWORD dwVertexCount,
814 DWORD dwFlags)
816 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
817 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
819 ENTER_GL();
820 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
821 LEAVE_GL();
823 return DD_OK;
826 HRESULT WINAPI
827 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
828 D3DPRIMITIVETYPE d3dptPrimitiveType,
829 D3DVERTEXTYPE d3dvtVertexType,
830 LPVOID lpvVertices,
831 DWORD dwVertexCount,
832 LPWORD dwIndices,
833 DWORD dwIndexCount,
834 DWORD dwFlags)
836 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
837 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
839 ENTER_GL();
840 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
841 LEAVE_GL();
843 return DD_OK;
846 HRESULT WINAPI
847 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
848 LPD3DEXECUTEBUFFERDESC lpDesc,
849 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
850 IUnknown* pUnkOuter)
852 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
853 IDirect3DExecuteBufferImpl *ret;
854 HRESULT ret_value;
856 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
858 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
859 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
861 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
863 return ret_value;
866 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
868 DWORD size = 0;
869 DWORD elts = 0;
871 if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
872 if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
873 if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
874 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
875 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
876 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
877 default: TRACE(" matrix weighting not handled yet...\n");
879 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
880 elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
882 if (elements) *elements = elts;
884 return size;
887 void dump_flexible_vertex(DWORD d3dvtVertexType)
889 static const flag_info flags[] = {
890 FE(D3DFVF_NORMAL),
891 FE(D3DFVF_RESERVED1),
892 FE(D3DFVF_DIFFUSE),
893 FE(D3DFVF_SPECULAR)
895 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
896 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
897 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
898 GEN_CASE(D3DFVF_XYZ);
899 GEN_CASE(D3DFVF_XYZRHW);
900 GEN_CASE(D3DFVF_XYZB1);
901 GEN_CASE(D3DFVF_XYZB2);
902 GEN_CASE(D3DFVF_XYZB3);
903 GEN_CASE(D3DFVF_XYZB4);
904 GEN_CASE(D3DFVF_XYZB5);
906 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
907 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
908 GEN_CASE(D3DFVF_TEX0);
909 GEN_CASE(D3DFVF_TEX1);
910 GEN_CASE(D3DFVF_TEX2);
911 GEN_CASE(D3DFVF_TEX3);
912 GEN_CASE(D3DFVF_TEX4);
913 GEN_CASE(D3DFVF_TEX5);
914 GEN_CASE(D3DFVF_TEX6);
915 GEN_CASE(D3DFVF_TEX7);
916 GEN_CASE(D3DFVF_TEX8);
918 #undef GEN_CASE
919 DPRINTF("\n");
922 /* These are the various handler used in the generic path */
923 inline static void handle_xyz(D3DVALUE *coords) {
924 glVertex3fv(coords);
926 inline static void handle_xyzrhw(D3DVALUE *coords) {
927 if (coords[3] < 1e-8)
928 glVertex3fv(coords);
929 else {
930 GLfloat w = 1.0 / coords[3];
932 glVertex4f(coords[0] * w,
933 coords[1] * w,
934 coords[2] * w,
938 inline static void handle_normal(D3DVALUE *coords) {
939 glNormal3fv(coords);
941 inline static void handle_specular(DWORD *color) {
942 /* Specular not handled yet properly... */
944 inline static void handle_diffuse(DWORD *color) {
945 glColor4ub((*color >> 16) & 0xFF,
946 (*color >> 8) & 0xFF,
947 (*color >> 0) & 0xFF,
948 (*color >> 24) & 0xFF);
950 inline static void handle_diffuse_and_specular(DWORD *color_d, DWORD *color_s) {
951 handle_diffuse(color_d);
953 inline static void handle_diffuse_no_alpha(DWORD *color) {
954 glColor3ub((*color >> 16) & 0xFF,
955 (*color >> 8) & 0xFF,
956 (*color >> 0) & 0xFF);
958 inline static void handle_diffuse_and_specular_no_alpha(DWORD *color_d, DWORD *color_s) {
959 handle_diffuse_no_alpha(color_d);
961 inline static void handle_texture(D3DVALUE *coords) {
962 glTexCoord2fv(coords);
964 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
965 /* For the moment, draw only the first texture.. */
966 if (tex_index == 0) glTexCoord2fv(coords);
969 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
970 D3DPRIMITIVETYPE d3dptPrimitiveType,
971 DWORD d3dvtVertexType,
972 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
973 DWORD dwStartVertex,
974 DWORD dwVertexCount,
975 LPWORD dwIndices,
976 DWORD dwIndexCount,
977 DWORD dwFlags)
979 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
980 if (TRACE_ON(ddraw)) {
981 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
984 ENTER_GL();
985 draw_primitive_handle_GL_state(This,
986 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
987 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
988 draw_primitive_start_GL(d3dptPrimitiveType);
990 /* Some fast paths first before the generic case.... */
991 if (d3dvtVertexType == D3DFVF_VERTEX) {
992 int index;
994 for (index = 0; index < dwIndexCount; index++) {
995 int i = (dwIndices == NULL) ? index : dwIndices[index];
996 D3DVALUE *normal =
997 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
998 D3DVALUE *tex_coord =
999 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1000 D3DVALUE *position =
1001 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1003 handle_normal(normal);
1004 handle_texture(tex_coord);
1005 handle_xyz(position);
1007 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
1008 position[0], position[1], position[2],
1009 normal[0], normal[1], normal[2],
1010 tex_coord[0], tex_coord[1]);
1012 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
1013 int index;
1015 for (index = 0; index < dwIndexCount; index++) {
1016 int i = (dwIndices == NULL) ? index : dwIndices[index];
1017 DWORD *color_d =
1018 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1019 DWORD *color_s =
1020 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1021 D3DVALUE *tex_coord =
1022 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1023 D3DVALUE *position =
1024 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1026 if (glThis->render_state.alpha_blend_enable == TRUE)
1027 handle_diffuse_and_specular(color_d, color_s);
1028 else
1029 handle_diffuse_and_specular_no_alpha(color_d, color_s);
1030 handle_texture(tex_coord);
1031 handle_xyzrhw(position);
1033 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1034 position[0], position[1], position[2], position[3],
1035 (*color_d >> 16) & 0xFF,
1036 (*color_d >> 8) & 0xFF,
1037 (*color_d >> 0) & 0xFF,
1038 (*color_d >> 24) & 0xFF,
1039 (*color_s >> 16) & 0xFF,
1040 (*color_s >> 8) & 0xFF,
1041 (*color_s >> 0) & 0xFF,
1042 (*color_s >> 24) & 0xFF,
1043 tex_coord[0], tex_coord[1]);
1045 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1046 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1047 /* This is the 'slow path' but that should support all possible vertex formats out there...
1048 Note that people should write a fast path for all vertex formats out there...
1050 int index;
1051 for (index = 0; index < dwIndexCount; index++) {
1052 int i = (dwIndices == NULL) ? index : dwIndices[index];
1054 if (d3dvtVertexType & D3DFVF_NORMAL) {
1055 D3DVALUE *normal =
1056 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1057 handle_normal(normal);
1059 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1060 DWORD *color_d =
1061 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1062 DWORD *color_s =
1063 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1064 if (glThis->render_state.alpha_blend_enable == TRUE)
1065 handle_diffuse_and_specular(color_d, color_s);
1066 else
1067 handle_diffuse_and_specular_no_alpha(color_d, color_s);
1068 } else {
1069 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1070 DWORD *color_s =
1071 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1072 handle_specular(color_s);
1073 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1074 DWORD *color_d =
1075 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1076 if (glThis->render_state.alpha_blend_enable == TRUE)
1077 handle_diffuse(color_d);
1078 else
1079 handle_diffuse_no_alpha(color_d);
1083 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1084 /* Special case for single texture... */
1085 D3DVALUE *tex_coord =
1086 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1087 handle_texture(tex_coord);
1088 } else {
1089 int tex_index;
1090 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1091 D3DVALUE *tex_coord =
1092 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1093 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1094 handle_textures(tex_coord, tex_index);
1097 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1098 D3DVALUE *position =
1099 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1100 handle_xyz(position);
1101 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1102 D3DVALUE *position =
1103 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1104 handle_xyzrhw(position);
1107 if (TRACE_ON(ddraw)) {
1108 int tex_index;
1110 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1111 D3DVALUE *position =
1112 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1113 TRACE(" %f %f %f", position[0], position[1], position[2]);
1114 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1115 D3DVALUE *position =
1116 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1117 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1119 if (d3dvtVertexType & D3DFVF_NORMAL) {
1120 D3DVALUE *normal =
1121 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1122 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1124 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1125 DWORD *color_d =
1126 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1127 DPRINTF(" / %02lx %02lx %02lx %02lx",
1128 (*color_d >> 16) & 0xFF,
1129 (*color_d >> 8) & 0xFF,
1130 (*color_d >> 0) & 0xFF,
1131 (*color_d >> 24) & 0xFF);
1133 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1134 DWORD *color_s =
1135 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1136 DPRINTF(" / %02lx %02lx %02lx %02lx",
1137 (*color_s >> 16) & 0xFF,
1138 (*color_s >> 8) & 0xFF,
1139 (*color_s >> 0) & 0xFF,
1140 (*color_s >> 24) & 0xFF);
1142 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1143 D3DVALUE *tex_coord =
1144 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1145 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1146 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1148 DPRINTF("\n");
1151 } else {
1152 ERR(" matrix weighting not handled yet....\n");
1155 glEnd();
1156 LEAVE_GL();
1157 TRACE("End\n");
1160 static void draw_primitive_7(IDirect3DDeviceImpl *This,
1161 D3DPRIMITIVETYPE d3dptPrimitiveType,
1162 DWORD d3dvtVertexType,
1163 LPVOID lpvVertices,
1164 DWORD dwStartVertex,
1165 DWORD dwVertexCount,
1166 LPWORD dwIndices,
1167 DWORD dwIndexCount,
1168 DWORD dwFlags)
1170 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1171 int current_offset = 0;
1172 int tex_index;
1174 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1175 strided.position.lpvData = lpvVertices;
1176 current_offset += 3 * sizeof(D3DVALUE);
1177 } else {
1178 strided.position.lpvData = lpvVertices;
1179 current_offset += 4 * sizeof(D3DVALUE);
1181 if (d3dvtVertexType & D3DFVF_NORMAL) {
1182 strided.normal.lpvData = ((char *) lpvVertices) + current_offset;
1183 current_offset += 3 * sizeof(D3DVALUE);
1185 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1186 strided.diffuse.lpvData = ((char *) lpvVertices) + current_offset;
1187 current_offset += sizeof(DWORD);
1189 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1190 strided.specular.lpvData = ((char *) lpvVertices) + current_offset;
1191 current_offset += sizeof(DWORD);
1193 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1194 strided.textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset;
1195 current_offset += 2 * sizeof(D3DVALUE);
1197 strided.position.dwStride = current_offset;
1198 strided.normal.dwStride = current_offset;
1199 strided.diffuse.dwStride = current_offset;
1200 strided.specular.dwStride = current_offset;
1201 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
1202 strided.textureCoords[tex_index].dwStride = current_offset;
1204 draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwStartVertex, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1207 HRESULT WINAPI
1208 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1209 D3DPRIMITIVETYPE d3dptPrimitiveType,
1210 DWORD d3dvtVertexType,
1211 LPVOID lpvVertices,
1212 DWORD dwVertexCount,
1213 DWORD dwFlags)
1215 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1216 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1218 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1220 return DD_OK;
1223 HRESULT WINAPI
1224 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1225 D3DPRIMITIVETYPE d3dptPrimitiveType,
1226 DWORD d3dvtVertexType,
1227 LPVOID lpvVertices,
1228 DWORD dwVertexCount,
1229 LPWORD dwIndices,
1230 DWORD dwIndexCount,
1231 DWORD dwFlags)
1233 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1234 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1236 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1238 return DD_OK;
1241 HRESULT WINAPI
1242 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1243 D3DPRIMITIVETYPE d3dptPrimitiveType,
1244 DWORD dwVertexType,
1245 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1246 DWORD dwVertexCount,
1247 DWORD dwFlags)
1249 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1250 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1251 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
1252 return DD_OK;
1255 HRESULT WINAPI
1256 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1257 D3DPRIMITIVETYPE d3dptPrimitiveType,
1258 DWORD dwVertexType,
1259 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1260 DWORD dwVertexCount,
1261 LPWORD lpIndex,
1262 DWORD dwIndexCount,
1263 DWORD dwFlags)
1265 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1266 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1267 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1268 return DD_OK;
1271 HRESULT WINAPI
1272 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1273 D3DPRIMITIVETYPE d3dptPrimitiveType,
1274 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1275 DWORD dwStartVertex,
1276 DWORD dwNumVertices,
1277 DWORD dwFlags)
1279 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1280 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1282 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1284 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1286 return DD_OK;
1289 HRESULT WINAPI
1290 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1291 D3DPRIMITIVETYPE d3dptPrimitiveType,
1292 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1293 DWORD dwStartVertex,
1294 DWORD dwNumVertices,
1295 LPWORD lpwIndices,
1296 DWORD dwIndexCount,
1297 DWORD dwFlags)
1299 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1300 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1302 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1304 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1306 return DD_OK;
1309 HRESULT WINAPI
1310 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1311 DWORD dwStage,
1312 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1313 DWORD dwState)
1315 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1316 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1317 GLenum gl_state;
1319 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1321 if (TRACE_ON(ddraw)) {
1322 TRACE(" Stage type is : ");
1323 switch (d3dTexStageStateType) {
1324 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1325 GEN_CASE(D3DTSS_COLOROP);
1326 GEN_CASE(D3DTSS_COLORARG1);
1327 GEN_CASE(D3DTSS_COLORARG2);
1328 GEN_CASE(D3DTSS_ALPHAOP);
1329 GEN_CASE(D3DTSS_ALPHAARG1);
1330 GEN_CASE(D3DTSS_ALPHAARG2);
1331 GEN_CASE(D3DTSS_BUMPENVMAT00);
1332 GEN_CASE(D3DTSS_BUMPENVMAT01);
1333 GEN_CASE(D3DTSS_BUMPENVMAT10);
1334 GEN_CASE(D3DTSS_BUMPENVMAT11);
1335 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1336 GEN_CASE(D3DTSS_ADDRESS);
1337 GEN_CASE(D3DTSS_ADDRESSU);
1338 GEN_CASE(D3DTSS_ADDRESSV);
1339 GEN_CASE(D3DTSS_BORDERCOLOR);
1340 GEN_CASE(D3DTSS_MAGFILTER);
1341 GEN_CASE(D3DTSS_MINFILTER);
1342 GEN_CASE(D3DTSS_MIPFILTER);
1343 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1344 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1345 GEN_CASE(D3DTSS_MAXANISOTROPY);
1346 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1347 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1348 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1349 #undef GEN_CASE
1350 default: DPRINTF("UNKNOWN !!!");
1352 DPRINTF(" => ");
1355 switch (d3dTexStageStateType) {
1356 case D3DTSS_MINFILTER:
1357 switch ((D3DTEXTUREMINFILTER) dwState) {
1358 case D3DTFN_POINT:
1359 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1360 gl_state = GL_NEAREST;
1361 break;
1362 case D3DTFN_LINEAR:
1363 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1364 gl_state = GL_LINEAR;
1365 break;
1366 default:
1367 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1368 gl_state = GL_LINEAR;
1369 break;
1371 glThis->render_state.min = gl_state;
1372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1373 break;
1375 case D3DTSS_MAGFILTER:
1376 switch ((D3DTEXTUREMAGFILTER) dwState) {
1377 case D3DTFG_POINT:
1378 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1379 gl_state = GL_NEAREST;
1380 break;
1381 case D3DTFG_LINEAR:
1382 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1383 gl_state = GL_LINEAR;
1384 break;
1385 default:
1386 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled (%ld).\n", dwState);
1387 gl_state = GL_LINEAR;
1388 break;
1390 glThis->render_state.mag = gl_state;
1391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1392 break;
1394 case D3DTSS_ADDRESS:
1395 case D3DTSS_ADDRESSU:
1396 case D3DTSS_ADDRESSV: {
1397 GLenum arg = GL_REPEAT; /* Default value */
1398 switch ((D3DTEXTUREADDRESS) dwState) {
1399 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1400 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1401 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1402 default: DPRINTF(" state unhandled (%ld).\n", dwState);
1404 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1405 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1406 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1407 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1408 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1410 } break;
1412 default:
1413 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1416 return DD_OK;
1419 HRESULT WINAPI
1420 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1421 DWORD dwStage,
1422 LPDIRECTDRAWSURFACE7 lpTexture2)
1424 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1426 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1428 if (This->current_texture[dwStage] != NULL) {
1429 /* Seems that this is not right... Need to test in real Windows
1430 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1433 ENTER_GL();
1434 if (lpTexture2 == NULL) {
1435 TRACE(" disabling 2D texturing.\n");
1436 glBindTexture(GL_TEXTURE_2D, 0);
1437 glDisable(GL_TEXTURE_2D);
1438 } else {
1439 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1440 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
1442 This->current_texture[dwStage] = tex_impl;
1443 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1445 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1447 glEnable(GL_TEXTURE_2D);
1448 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1450 LEAVE_GL();
1452 return DD_OK;
1455 HRESULT WINAPI
1456 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1457 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1459 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1460 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1462 fill_opengl_caps_7(lpD3DHELDevDesc);
1464 TRACE(" returning caps : no dump function yet.\n");
1466 return DD_OK;
1469 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1470 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1471 #else
1472 # define XCAST(fun) (void*)
1473 #endif
1475 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1477 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1478 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1479 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1480 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1481 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1482 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1483 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1484 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1485 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1486 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1487 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1488 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1489 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1490 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1491 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1492 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1493 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1494 XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
1495 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1496 XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
1497 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1498 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1499 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1500 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1501 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1502 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1503 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1504 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1505 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1506 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1507 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1508 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1509 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1510 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
1511 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1512 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture,
1513 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1514 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1515 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1516 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1517 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1518 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1519 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1520 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1521 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1522 XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
1523 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1524 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1525 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1526 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1529 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1530 #undef XCAST
1531 #endif
1534 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1535 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1536 #else
1537 # define XCAST(fun) (void*)
1538 #endif
1540 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1542 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1543 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1544 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1545 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1546 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1547 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1548 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1549 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1550 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1551 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1552 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1553 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1554 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1555 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1556 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1557 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1558 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1559 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1560 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1561 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1562 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1563 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1564 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1565 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1566 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1567 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1568 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1569 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1570 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1571 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1572 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1573 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1574 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1575 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1576 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1577 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1578 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1579 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1580 XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture,
1581 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1582 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1583 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1584 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1587 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1588 #undef XCAST
1589 #endif
1592 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1593 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1594 #else
1595 # define XCAST(fun) (void*)
1596 #endif
1598 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1600 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1601 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1602 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1603 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1604 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1605 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
1606 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1607 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1608 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1609 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1610 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1611 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1612 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1613 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1614 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1615 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1616 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1617 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1618 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1619 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1620 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1621 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1622 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1623 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1624 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1625 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1626 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1627 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1628 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1629 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1630 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1631 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1632 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1633 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1636 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1637 #undef XCAST
1638 #endif
1641 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1642 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1643 #else
1644 # define XCAST(fun) (void*)
1645 #endif
1647 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1649 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1650 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1651 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1652 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1653 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1654 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1655 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
1656 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1657 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1658 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1659 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1660 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1661 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1662 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1663 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1664 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1665 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1666 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1667 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1668 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1669 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1670 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1671 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1674 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1675 #undef XCAST
1676 #endif
1678 static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1679 DWORD dwCount,
1680 LPD3DRECT lpRects,
1681 DWORD dwFlags,
1682 DWORD dwColor,
1683 D3DVALUE dvZ,
1684 DWORD dwStencil)
1686 GLboolean ztest;
1687 GLfloat old_z_clear_value;
1688 GLbitfield bitfield = 0;
1689 GLint old_stencil_clear_value;
1690 GLfloat old_color_clear_value[4];
1692 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1693 if (TRACE_ON(ddraw)) {
1694 if (dwCount > 0) {
1695 int i;
1696 TRACE(" rectangles : \n");
1697 for (i = 0; i < dwCount; i++) {
1698 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1703 if (dwCount > 1) {
1704 WARN(" Warning, this function only for now clears the whole screen...\n");
1707 /* Clears the screen */
1708 ENTER_GL();
1709 if (dwFlags & D3DCLEAR_ZBUFFER) {
1710 bitfield |= GL_DEPTH_BUFFER_BIT;
1711 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1712 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1713 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1714 glClearDepth(dvZ);
1715 TRACE(" depth value : %f\n", dvZ);
1717 if (dwFlags & D3DCLEAR_STENCIL) {
1718 bitfield |= GL_STENCIL_BUFFER_BIT;
1719 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1720 glClearStencil(dwStencil);
1721 TRACE(" stencil value : %ld\n", dwStencil);
1723 if (dwFlags & D3DCLEAR_TARGET) {
1724 bitfield |= GL_COLOR_BUFFER_BIT;
1725 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1726 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1727 ((dwColor >> 8) & 0xFF) / 255.0,
1728 ((dwColor >> 0) & 0xFF) / 255.0,
1729 ((dwColor >> 24) & 0xFF) / 255.0);
1730 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1733 glClear(bitfield);
1735 if (dwFlags & D3DCLEAR_ZBUFFER) {
1736 glDepthMask(ztest);
1737 glClearDepth(old_z_clear_value);
1739 if (dwFlags & D3DCLEAR_STENCIL) {
1740 bitfield |= GL_STENCIL_BUFFER_BIT;
1741 glClearStencil(old_stencil_clear_value);
1743 if (dwFlags & D3DCLEAR_TARGET) {
1744 bitfield |= GL_COLOR_BUFFER_BIT;
1745 glClearColor(old_color_clear_value[0],
1746 old_color_clear_value[1],
1747 old_color_clear_value[2],
1748 old_color_clear_value[3]);
1751 LEAVE_GL();
1753 return DD_OK;
1756 HRESULT
1757 d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst,
1758 LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,
1759 DWORD dwFlags, LPDDBLTFX lpbltfx)
1761 if (dwFlags & DDBLT_COLORFILL) {
1762 /* This is easy to handle for the D3D Device... */
1763 DWORD color = lpbltfx->u5.dwFillColor;
1764 TRACE(" executing D3D Device override.\n");
1765 d3ddevice_clear(This->d3ddevice, 0, NULL, D3DCLEAR_TARGET, color, 0.0, 0x00000000);
1766 return DD_OK;
1768 return DDERR_INVALIDPARAMS;
1771 HRESULT
1772 d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx,
1773 DWORD dsty, LPDIRECTDRAWSURFACE7 src,
1774 LPRECT rsrc, DWORD trans)
1776 return DDERR_INVALIDPARAMS;
1780 /* TODO for both these functions :
1781 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1782 by other OpenGL code in D3D
1783 - handle the case where no 'Begin / EndScene' was done between two locks
1784 - handle the rectangles in the unlock too
1785 - handle pitch correctly...
1787 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1789 /* First, check if we need to do anything */
1790 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1791 GLenum buffer_type;
1792 GLenum prev_read;
1793 RECT loc_rect;
1795 ENTER_GL();
1797 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1798 glFlush();
1800 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1801 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1802 /* Application wants to lock the front buffer */
1803 glReadBuffer(GL_FRONT);
1804 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1805 /* Application wants to lock the back buffer */
1806 glReadBuffer(GL_BACK);
1807 } else {
1808 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1811 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1812 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1813 } else {
1814 WARN(" unsupported pixel format.\n");
1815 LEAVE_GL();
1816 return;
1818 if (pRect == NULL) {
1819 loc_rect.top = 0;
1820 loc_rect.left = 0;
1821 loc_rect.bottom = This->surface_desc.dwHeight;
1822 loc_rect.right = This->surface_desc.dwWidth;
1823 } else {
1824 loc_rect = *pRect;
1826 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1827 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1828 + loc_rect.top * This->surface_desc.u1.lPitch
1829 + loc_rect.left * GET_BPP(This->surface_desc)));
1830 glReadBuffer(prev_read);
1831 LEAVE_GL();
1835 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1837 /* First, check if we need to do anything */
1838 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1839 GLenum buffer_type;
1840 GLenum prev_draw;
1842 ENTER_GL();
1844 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1846 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1847 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1848 /* Application wants to lock the front buffer */
1849 glDrawBuffer(GL_FRONT);
1850 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1851 /* Application wants to lock the back buffer */
1852 glDrawBuffer(GL_BACK);
1853 } else {
1854 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
1857 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1858 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1859 } else {
1860 WARN(" unsupported pixel format.\n");
1861 LEAVE_GL();
1862 return;
1864 glRasterPos2f(0.0, 0.0);
1865 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
1866 GL_RGB, buffer_type, This->surface_desc.lpSurface);
1867 glDrawBuffer(prev_draw);
1869 LEAVE_GL();
1873 HRESULT
1874 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
1876 IDirect3DDeviceImpl *object;
1877 IDirect3DDeviceGLImpl *gl_object;
1878 IDirectDrawSurfaceImpl *surf;
1879 HDC device_context;
1880 XVisualInfo *vis;
1881 int num;
1882 XVisualInfo template;
1883 GLenum buffer;
1885 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1886 if (object == NULL) return DDERR_OUTOFMEMORY;
1888 gl_object = (IDirect3DDeviceGLImpl *) object;
1890 object->ref = 1;
1891 object->d3d = d3d;
1892 object->surface = surface;
1893 object->set_context = set_context;
1894 object->clear = d3ddevice_clear;
1896 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1898 device_context = GetDC(surface->ddraw_owner->window);
1899 gl_object->display = get_display(device_context);
1900 gl_object->drawable = get_drawable(device_context);
1901 ReleaseDC(surface->ddraw_owner->window,device_context);
1903 ENTER_GL();
1904 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1905 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
1906 if (vis == NULL) {
1907 HeapFree(GetProcessHeap(), 0, object);
1908 ERR("No visual found !\n");
1909 LEAVE_GL();
1910 return DDERR_INVALIDPARAMS;
1911 } else {
1912 TRACE(" visual found\n");
1915 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
1916 NULL, GL_TRUE);
1918 if (gl_object->gl_context == NULL) {
1919 HeapFree(GetProcessHeap(), 0, object);
1920 ERR("Error in context creation !\n");
1921 LEAVE_GL();
1922 return DDERR_INVALIDPARAMS;
1923 } else {
1924 TRACE(" context created (%p)\n", gl_object->gl_context);
1927 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
1928 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
1929 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
1930 surf->aux_ctx = (LPVOID) gl_object->display;
1931 surf->aux_data = (LPVOID) gl_object->drawable;
1932 surf->aux_flip = opengl_flip;
1933 buffer = GL_BACK;
1934 break;
1937 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
1938 if (surf == NULL) {
1939 TRACE(" no double buffering : drawing on the front buffer\n");
1940 buffer = GL_FRONT;
1943 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
1944 for (; surf != NULL; surf = surf->next_attached) {
1945 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
1946 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
1947 /* Override the Lock / Unlock function for all these surfaces */
1948 surf->lock_update = d3ddevice_lock_update;
1949 surf->unlock_update = d3ddevice_unlock_update;
1950 /* And install also the blt / bltfast overrides */
1951 surf->aux_blt = d3ddevice_blt;
1952 surf->aux_bltfast = d3ddevice_bltfast;
1954 surf->d3ddevice = object;
1957 gl_object->render_state.src = GL_ONE;
1958 gl_object->render_state.dst = GL_ZERO;
1959 gl_object->render_state.mag = GL_NEAREST;
1960 gl_object->render_state.min = GL_NEAREST;
1961 gl_object->render_state.alpha_ref = 0.0; /* No actual idea about the real default value... */
1962 gl_object->render_state.alpha_func = GL_ALWAYS; /* Here either but it seems logical */
1963 gl_object->render_state.alpha_blend_enable = FALSE;
1964 gl_object->render_state.fog_on = FALSE;
1966 /* Allocate memory for the matrices */
1967 object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1968 object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1969 object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1970 memcpy(object->world_mat, id_mat, 16 * sizeof(float));
1971 memcpy(object->view_mat , id_mat, 16 * sizeof(float));
1972 memcpy(object->proj_mat , id_mat, 16 * sizeof(float));
1974 /* Initialisation */
1975 TRACE(" setting current context\n");
1976 LEAVE_GL();
1977 object->set_context(object);
1978 ENTER_GL();
1979 TRACE(" current context set\n");
1980 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1981 glClearColor(0.0, 0.0, 0.0, 0.0);
1982 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1983 glDrawBuffer(buffer);
1984 glReadBuffer(buffer);
1985 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
1986 LEAVE_GL();
1988 /* fill_device_capabilities(d3d->ddraw); */
1990 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
1991 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
1992 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
1993 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
1995 *obj = object;
1997 TRACE(" creating implementation at %p.\n", *obj);
1999 /* And finally warn D3D that this device is now present */
2000 object->d3d->added_device(object->d3d, object);
2002 return DD_OK;