Support viewports the D3D7 way.
[wine/multimedia.git] / dlls / ddraw / d3ddevice / mesa.c
blob2ae9cbf792e7618742a30fc0baeda126c20af272
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 dwVertexCount,
67 LPWORD dwIndices,
68 DWORD dwIndexCount,
69 DWORD dwFlags) ;
71 /* retrieve the X display to use on a given DC */
72 inline static Display *get_display( HDC hdc )
74 Display *display;
75 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
77 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
78 sizeof(display), (LPSTR)&display )) display = NULL;
80 return display;
84 /* retrieve the X drawable to use on a given DC */
85 inline static Drawable get_drawable( HDC hdc )
87 Drawable drawable;
88 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
90 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
91 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
93 return drawable;
97 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
99 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
100 ENTER_GL();
101 glXSwapBuffers((Display*)display,(Drawable)drawable);
102 LEAVE_GL();
103 return TRUE;
107 /*******************************************************************************
108 * OpenGL static functions
110 static void set_context(IDirect3DDeviceImpl* This)
112 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
114 ENTER_GL();
115 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
116 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
117 ERR("Error in setting current context (context %p drawable %ld)!\n",
118 glThis->gl_context, glThis->drawable);
120 LEAVE_GL();
123 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
125 pc->dwSize = sizeof(*pc);
126 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
127 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
128 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
129 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
130 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
131 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
132 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
133 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
134 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
135 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
136 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
137 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
138 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
139 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
140 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
141 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
142 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
143 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
144 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
145 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
146 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
147 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
148 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
149 pc->dwStippleWidth = 32;
150 pc->dwStippleHeight = 32;
153 static void fill_opengl_caps(D3DDEVICEDESC *d1)
155 /* GLint maxlight; */
157 d1->dwSize = sizeof(*d1);
158 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
159 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
160 d1->dcmColorModel = D3DCOLOR_RGB;
161 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
162 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
163 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
164 /* D3D 7 capabilities */
165 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
166 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
167 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
168 d1->bClipping = TRUE;
169 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
170 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
171 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
172 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
173 fill_opengl_primcaps(&(d1->dpcLineCaps));
174 fill_opengl_primcaps(&(d1->dpcTriCaps));
175 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
176 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
177 d1->dwMaxBufferSize = 0;
178 d1->dwMaxVertexCount = 65536;
179 d1->dwMinTextureWidth = 1;
180 d1->dwMinTextureHeight = 1;
181 d1->dwMaxTextureWidth = 1024;
182 d1->dwMaxTextureHeight = 1024;
183 d1->dwMinStippleWidth = 1;
184 d1->dwMinStippleHeight = 1;
185 d1->dwMaxStippleWidth = 32;
186 d1->dwMaxStippleHeight = 32;
187 d1->dwMaxTextureRepeat = 16;
188 d1->dwMaxTextureAspectRatio = 1024;
189 d1->dwMaxAnisotropy = 0;
190 d1->dvGuardBandLeft = 0.0;
191 d1->dvGuardBandRight = 0.0;
192 d1->dvGuardBandTop = 0.0;
193 d1->dvGuardBandBottom = 0.0;
194 d1->dvExtentsAdjust = 0.0;
195 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
196 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
197 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
198 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
199 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
200 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
203 static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
205 D3DDEVICEDESC d1;
207 /* Copy first D3D1/2/3 capabilities */
208 fill_opengl_caps(&d1);
210 /* And fill the D3D7 one with it */
211 d->dwDevCaps = d1.dwDevCaps;
212 d->dpcLineCaps = d1.dpcLineCaps;
213 d->dpcTriCaps = d1.dpcTriCaps;
214 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
215 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
216 d->dwMinTextureWidth = d1.dwMinTextureWidth;
217 d->dwMinTextureHeight = d1.dwMinTextureHeight;
218 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
219 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
220 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
221 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
222 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
223 d->dvGuardBandLeft = d1.dvGuardBandLeft;
224 d->dvGuardBandTop = d1.dvGuardBandTop;
225 d->dvGuardBandRight = d1.dvGuardBandRight;
226 d->dvGuardBandBottom = d1.dvGuardBandBottom;
227 d->dvExtentsAdjust = d1.dvExtentsAdjust;
228 d->dwStencilCaps = d1.dwStencilCaps;
229 d->dwFVFCaps = d1.dwFVFCaps;
230 d->dwTextureOpCaps = d1.dwTextureOpCaps;
231 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
232 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
233 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
234 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
235 d->deviceGUID = IID_IDirect3DTnLHalDevice;
236 d->wMaxUserClipPlanes = 1;
237 d->wMaxVertexBlendMatrices = 0;
238 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
239 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
240 d->dwReserved1 = 0;
241 d->dwReserved2 = 0;
242 d->dwReserved3 = 0;
243 d->dwReserved4 = 0;
246 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
247 static void fill_device_capabilities(IDirectDrawImpl* ddraw)
249 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
250 const char *ext_string;
251 Mesa_DeviceCapabilities *devcap;
253 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
254 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
256 ENTER_GL();
257 ext_string = glGetString(GL_EXTENSIONS);
258 /* Query for the ColorTable Extension */
259 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
260 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
261 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
262 } else {
263 TRACE("Color table extension not found.\n");
265 LEAVE_GL();
267 #endif
271 HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
273 D3DDEVICEDESC d1, d2;
275 fill_opengl_caps(&d1);
276 d2 = d1;
278 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
279 return cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
282 HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
284 D3DDEVICEDESC7 ddesc;
286 fill_opengl_caps_7(&ddesc);
288 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
290 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
293 ULONG WINAPI
294 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
296 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
297 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
299 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
300 if (!--(This->ref)) {
301 /* Release texture associated with the device */
302 if (This->current_texture[0] != NULL)
303 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
305 if (glThis->handler) HeapFree(GetProcessHeap(), 0, This);
307 ENTER_GL();
308 glXDestroyContext(glThis->display, glThis->gl_context);
309 LEAVE_GL();
311 HeapFree(GetProcessHeap(), 0, This);
312 return 0;
314 return This->ref;
317 HRESULT WINAPI
318 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
319 LPD3DDEVICEDESC lpD3DHWDevDesc,
320 LPD3DDEVICEDESC lpD3DHELDevDesc)
322 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
323 D3DDEVICEDESC desc;
324 DWORD dwSize;
326 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
328 fill_opengl_caps(&desc);
329 dwSize = lpD3DHWDevDesc->dwSize;
330 memset(lpD3DHWDevDesc, 0, dwSize);
331 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
333 dwSize = lpD3DHELDevDesc->dwSize;
334 memset(lpD3DHELDevDesc, 0, dwSize);
335 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
337 TRACE(" returning caps : (no dump function yet)\n");
339 return DD_OK;
342 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
343 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
344 LPVOID context)
346 DDSURFACEDESC sdesc;
347 LPDDPIXELFORMAT pformat;
349 /* Do the texture enumeration */
350 sdesc.dwSize = sizeof(DDSURFACEDESC);
351 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
352 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
353 pformat = &(sdesc.ddpfPixelFormat);
354 pformat->dwSize = sizeof(DDPIXELFORMAT);
355 pformat->dwFourCC = 0;
357 TRACE("Enumerating GL_RGBA unpacked (32)\n");
358 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
359 pformat->u1.dwRGBBitCount = 32;
360 pformat->u2.dwRBitMask = 0xFF000000;
361 pformat->u3.dwGBitMask = 0x00FF0000;
362 pformat->u4.dwBBitMask = 0x0000FF00;
363 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
364 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
365 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
367 TRACE("Enumerating GL_RGB unpacked (24)\n");
368 pformat->dwFlags = DDPF_RGB;
369 pformat->u1.dwRGBBitCount = 24;
370 pformat->u2.dwRBitMask = 0x00FF0000;
371 pformat->u3.dwGBitMask = 0x0000FF00;
372 pformat->u4.dwBBitMask = 0x000000FF;
373 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
374 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
375 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
377 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
378 pformat->dwFlags = DDPF_RGB;
379 pformat->u1.dwRGBBitCount = 16;
380 pformat->u2.dwRBitMask = 0x0000F800;
381 pformat->u3.dwGBitMask = 0x000007E0;
382 pformat->u4.dwBBitMask = 0x0000001F;
383 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
384 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
385 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
387 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
388 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
389 pformat->u1.dwRGBBitCount = 16;
390 pformat->u2.dwRBitMask = 0x0000F800;
391 pformat->u3.dwGBitMask = 0x000007C0;
392 pformat->u4.dwBBitMask = 0x0000003E;
393 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
394 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
395 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
397 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
398 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
399 pformat->u1.dwRGBBitCount = 16;
400 pformat->u2.dwRBitMask = 0x0000F000;
401 pformat->u3.dwGBitMask = 0x00000F00;
402 pformat->u4.dwBBitMask = 0x000000F0;
403 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
404 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
405 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
407 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (16)\n");
408 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
409 pformat->u1.dwRGBBitCount = 16;
410 pformat->u2.dwRBitMask = 0x00007C00;
411 pformat->u3.dwGBitMask = 0x000003E0;
412 pformat->u4.dwBBitMask = 0x0000001F;
413 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
414 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
415 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
417 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
418 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
419 pformat->u1.dwRGBBitCount = 16;
420 pformat->u2.dwRBitMask = 0x00000F00;
421 pformat->u3.dwGBitMask = 0x000000F0;
422 pformat->u4.dwBBitMask = 0x0000000F;
423 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
424 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
425 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
427 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
428 pformat->dwFlags = DDPF_RGB;
429 pformat->u1.dwRGBBitCount = 8;
430 pformat->u2.dwRBitMask = 0x000000E0;
431 pformat->u3.dwGBitMask = 0x0000001C;
432 pformat->u4.dwBBitMask = 0x00000003;
433 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
434 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
435 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
437 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
438 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
439 pformat->u1.dwRGBBitCount = 16;
440 pformat->u2.dwRBitMask = 0x00007C00;
441 pformat->u3.dwGBitMask = 0x000003E0;
442 pformat->u4.dwBBitMask = 0x0000001F;
443 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
444 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
445 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
447 TRACE("Enumerating Paletted (8)\n");
448 pformat->dwFlags = DDPF_PALETTEINDEXED8;
449 pformat->u1.dwRGBBitCount = 8;
450 pformat->u2.dwRBitMask = 0x00000000;
451 pformat->u3.dwGBitMask = 0x00000000;
452 pformat->u4.dwBBitMask = 0x00000000;
453 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
454 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
455 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
457 TRACE("End of enumeration\n");
458 return DD_OK;
462 HRESULT
463 d3ddevice_find(IDirect3DImpl *d3d,
464 LPD3DFINDDEVICESEARCH lpD3DDFS,
465 LPD3DFINDDEVICERESULT lplpD3DDevice)
467 D3DDEVICEDESC desc;
469 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
470 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
471 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
472 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
474 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
475 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
476 if ((IsEqualGUID( &IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
477 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0)) {
478 TRACE(" no match for this GUID.\n");
479 return DDERR_INVALIDPARAMS;
483 /* Now return our own GUID */
484 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
485 fill_opengl_caps(&desc);
486 lplpD3DDevice->ddHwDesc = desc;
487 lplpD3DDevice->ddSwDesc = desc;
489 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
491 return D3D_OK;
494 HRESULT WINAPI
495 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
496 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
497 LPVOID lpArg)
499 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
500 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
501 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
504 HRESULT WINAPI
505 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
506 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
507 LPVOID lpArg)
509 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
510 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
511 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
514 HRESULT WINAPI
515 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
516 D3DRENDERSTATETYPE dwRenderStateType,
517 DWORD dwRenderState)
519 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
520 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
521 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
523 /* Call the render state functions */
524 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
526 return DD_OK;
529 HRESULT WINAPI
530 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
531 D3DLIGHTSTATETYPE dwLightStateType,
532 DWORD dwLightState)
534 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
535 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
537 switch (dwLightStateType) {
538 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
539 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
541 if (mat != NULL) {
542 ENTER_GL();
543 mat->activate(mat);
544 LEAVE_GL();
545 } else {
546 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
548 } break;
550 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
551 float light[4];
553 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
554 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
555 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
556 light[3] = 1.0;
557 ENTER_GL();
558 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
559 LEAVE_GL();
560 } break;
562 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
563 UNSUP(COLORMODEL);
564 UNSUP(FOGMODE);
565 UNSUP(FOGSTART);
566 UNSUP(FOGEND);
567 UNSUP(FOGDENSITY);
568 UNSUP(COLORVERTEX);
569 #undef UNSUP
571 default:
572 TRACE("Unexpected Light State Type\n");
573 return DDERR_INVALIDPARAMS;
576 return DD_OK;
579 HRESULT WINAPI
580 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
581 D3DTRANSFORMSTATETYPE dtstTransformStateType,
582 LPD3DMATRIX lpD3DMatrix)
584 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
585 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
587 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
589 ENTER_GL();
591 /* Using a trial and failure approach, I found that the order of
592 Direct3D transformations that works best is :
594 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
596 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
597 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
599 If anyone has a good explanation of the three different matrices in
600 the SDK online documentation, feel free to point it to me. For example,
601 which matrices transform lights ? In OpenGL only the PROJECTION matrix
602 transform the lights, not the MODELVIEW. Using the matrix names, I
603 supposed that PROJECTION and VIEW (all 'camera' related names) do
604 transform lights, but WORLD do not. It may be wrong though... */
606 /* After reading through both OpenGL and Direct3D documentations, I
607 thought that D3D matrices were written in 'line major mode' transposed
608 from OpenGL's 'column major mode'. But I found out that a simple memcpy
609 works fine to transfer one matrix format to the other (it did not work
610 when transposing)....
612 So :
613 1) are the documentations wrong
614 2) does the matrix work even if they are not read correctly
615 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
616 loading using glLoadMatrix ?
618 Anyway, I always use 'conv_mat' to transfer the matrices from one format
619 to the other so that if I ever find out that I need to transpose them, I
620 will able to do it quickly, only by changing the macro conv_mat. */
622 switch (dtstTransformStateType) {
623 case D3DTRANSFORMSTATE_WORLD: {
624 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
625 conv_mat(lpD3DMatrix, glThis->world_mat);
626 glMatrixMode(GL_MODELVIEW);
627 glLoadMatrixf((float *) glThis->view_mat);
628 glMultMatrixf((float *) glThis->world_mat);
629 } break;
631 case D3DTRANSFORMSTATE_VIEW: {
632 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
633 conv_mat(lpD3DMatrix, glThis->view_mat);
634 glMatrixMode(GL_MODELVIEW);
635 glLoadMatrixf((float *) glThis->view_mat);
636 glMultMatrixf((float *) glThis->world_mat);
637 } break;
639 case D3DTRANSFORMSTATE_PROJECTION: {
640 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
641 conv_mat(lpD3DMatrix, glThis->proj_mat);
642 glMatrixMode(GL_PROJECTION);
643 glLoadMatrixf((float *) glThis->proj_mat);
644 } break;
646 default:
647 ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType);
648 break;
650 LEAVE_GL();
652 return DD_OK;
655 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
657 switch (d3dpt) {
658 case D3DPT_POINTLIST:
659 TRACE("Start POINTS\n");
660 glBegin(GL_POINTS);
661 break;
663 case D3DPT_LINELIST:
664 TRACE("Start LINES\n");
665 glBegin(GL_LINES);
666 break;
668 case D3DPT_LINESTRIP:
669 TRACE("Start LINE_STRIP\n");
670 glBegin(GL_LINE_STRIP);
671 break;
673 case D3DPT_TRIANGLELIST:
674 TRACE("Start TRIANGLES\n");
675 glBegin(GL_TRIANGLES);
676 break;
678 case D3DPT_TRIANGLESTRIP:
679 TRACE("Start TRIANGLE_STRIP\n");
680 glBegin(GL_TRIANGLE_STRIP);
681 break;
683 case D3DPT_TRIANGLEFAN:
684 TRACE("Start TRIANGLE_FAN\n");
685 glBegin(GL_TRIANGLE_FAN);
686 break;
688 default:
689 TRACE("Unhandled primitive\n");
690 break;
694 static void draw_primitive_handle_GL_state(IDirect3DDeviceGLImpl *glThis,
695 BOOLEAN vertex_transformed,
696 BOOLEAN vertex_lit) {
697 /* Puts GL in the correct lighting / transformation mode */
698 if ((glThis->last_vertices_transformed == TRUE) && (vertex_transformed == FALSE)) {
699 /* Need to put the correct transformation again if we go from Transformed
700 vertices to non-transformed ones.
702 glMatrixMode(GL_MODELVIEW);
703 glLoadMatrixf((float *) glThis->view_mat);
704 glMultMatrixf((float *) glThis->world_mat);
705 glMatrixMode(GL_PROJECTION);
706 glLoadMatrixf((float *) glThis->proj_mat);
707 } else if ((glThis->last_vertices_transformed == FALSE) && (vertex_transformed == TRUE)) {
708 GLdouble height, width, minZ, maxZ, minX, minY;
710 glMatrixMode(GL_MODELVIEW);
711 glLoadIdentity();
712 glMatrixMode(GL_PROJECTION);
713 glLoadIdentity();
715 minX = (GLdouble) glThis->parent.active_viewport.dwX;
716 minY = (GLdouble) glThis->parent.active_viewport.dwY;
717 height = (GLdouble) glThis->parent.active_viewport.dwHeight;
718 width = (GLdouble) glThis->parent.active_viewport.dwWidth;
719 minZ = (GLdouble) glThis->parent.active_viewport.dvMinZ;
720 maxZ = (GLdouble) glThis->parent.active_viewport.dvMaxZ;
722 glOrtho(minX, width, height, minY, -minZ, -maxZ);
725 if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) {
726 glEnable(GL_LIGHTING);
727 } else if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == TRUE)) {
728 glDisable(GL_LIGHTING);
731 /* And save the current state */
732 glThis->last_vertices_transformed = vertex_transformed;
733 glThis->last_vertices_lit = vertex_lit;
737 inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
738 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
740 D3DDRAWPRIMITIVESTRIDEDDATA strided;
742 switch (d3dvt) {
743 case D3DVT_VERTEX: {
744 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
745 strided.position.dwStride = sizeof(D3DVERTEX);
746 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
747 strided.normal.dwStride = sizeof(D3DVERTEX);
748 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
749 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
750 draw_primitive_strided_7(This, d3dpt, D3DFVF_VERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */);
751 } break;
753 case D3DVT_LVERTEX: {
754 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
755 strided.position.dwStride = sizeof(D3DLVERTEX);
756 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
757 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
758 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
759 strided.specular.dwStride = sizeof(D3DLVERTEX);
760 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
761 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
762 draw_primitive_strided_7(This, d3dpt, D3DFVF_LVERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */);
763 } break;
765 case D3DVT_TLVERTEX: {
766 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
767 strided.position.dwStride = sizeof(D3DTLVERTEX);
768 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
769 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
770 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
771 strided.specular.dwStride = sizeof(D3DTLVERTEX);
772 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
773 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
774 draw_primitive_strided_7(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */);
775 } break;
777 default:
778 FIXME("Unhandled vertex type\n");
779 break;
783 HRESULT WINAPI
784 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
785 D3DPRIMITIVETYPE d3dptPrimitiveType,
786 D3DVERTEXTYPE d3dvtVertexType,
787 LPVOID lpvVertices,
788 DWORD dwVertexCount,
789 DWORD dwFlags)
791 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
792 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
794 ENTER_GL();
795 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
796 LEAVE_GL();
798 return DD_OK;
801 HRESULT WINAPI
802 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
803 D3DPRIMITIVETYPE d3dptPrimitiveType,
804 D3DVERTEXTYPE d3dvtVertexType,
805 LPVOID lpvVertices,
806 DWORD dwVertexCount,
807 LPWORD dwIndices,
808 DWORD dwIndexCount,
809 DWORD dwFlags)
811 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
812 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
814 ENTER_GL();
815 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
816 LEAVE_GL();
818 return DD_OK;
821 HRESULT WINAPI
822 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
823 LPD3DEXECUTEBUFFERDESC lpDesc,
824 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
825 IUnknown* pUnkOuter)
827 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
828 IDirect3DExecuteBufferImpl *ret;
829 HRESULT ret_value;
831 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
833 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
834 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
836 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
838 return ret_value;
841 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
843 DWORD size = 0;
844 DWORD elts = 0;
846 if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
847 if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
848 if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
849 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
850 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
851 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
852 default: TRACE(" matrix weighting not handled yet...\n");
854 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
855 elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
857 if (elements) *elements = elts;
859 return size;
862 void dump_flexible_vertex(DWORD d3dvtVertexType)
864 static const flag_info flags[] = {
865 FE(D3DFVF_NORMAL),
866 FE(D3DFVF_RESERVED1),
867 FE(D3DFVF_DIFFUSE),
868 FE(D3DFVF_SPECULAR)
870 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
871 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
872 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
873 GEN_CASE(D3DFVF_XYZ);
874 GEN_CASE(D3DFVF_XYZRHW);
875 GEN_CASE(D3DFVF_XYZB1);
876 GEN_CASE(D3DFVF_XYZB2);
877 GEN_CASE(D3DFVF_XYZB3);
878 GEN_CASE(D3DFVF_XYZB4);
879 GEN_CASE(D3DFVF_XYZB5);
881 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
882 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
883 GEN_CASE(D3DFVF_TEX0);
884 GEN_CASE(D3DFVF_TEX1);
885 GEN_CASE(D3DFVF_TEX2);
886 GEN_CASE(D3DFVF_TEX3);
887 GEN_CASE(D3DFVF_TEX4);
888 GEN_CASE(D3DFVF_TEX5);
889 GEN_CASE(D3DFVF_TEX6);
890 GEN_CASE(D3DFVF_TEX7);
891 GEN_CASE(D3DFVF_TEX8);
893 #undef GEN_CASE
894 DPRINTF("\n");
897 /* These are the various handler used in the generic path */
898 inline static void handle_xyz(D3DVALUE *coords) {
899 glVertex3fv(coords);
901 inline static void handle_xyzrhw(D3DVALUE *coords) {
902 if (coords[3] < 0.00001)
903 glVertex3f(coords[0], coords[1], coords[2]);
904 else
905 glVertex4f(coords[0] / coords[3],
906 coords[1] / coords[3],
907 coords[2] / coords[3],
908 1.0 / coords[3]);
910 inline static void handle_normal(D3DVALUE *coords) {
911 glNormal3fv(coords);
913 inline static void handle_specular(DWORD *color) {
914 /* Specular not handled yet properly... */
916 inline static void handle_diffuse(DWORD *color) {
917 glColor4ub((*color >> 16) & 0xFF,
918 (*color >> 8) & 0xFF,
919 (*color >> 0) & 0xFF,
920 (*color >> 24) & 0xFF);
922 inline static void handle_diffuse_and_specular(DWORD *color_d, DWORD *color_s) {
923 glColor4ub((*color_d >> 16) & 0xFF,
924 (*color_d >> 8) & 0xFF,
925 (*color_d >> 0) & 0xFF,
926 (*color_d >> 24) & 0xFF);
928 inline static void handle_texture(D3DVALUE *coords) {
929 glTexCoord2fv(coords);
931 inline static void handle_textures(D3DVALUE *coords, int tex_index) {
932 /* For the moment, draw only the first texture.. */
933 if (tex_index == 0) glTexCoord2fv(coords);
936 static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
937 D3DPRIMITIVETYPE d3dptPrimitiveType,
938 DWORD d3dvtVertexType,
939 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
940 DWORD dwVertexCount,
941 LPWORD dwIndices,
942 DWORD dwIndexCount,
943 DWORD dwFlags)
945 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
946 if (TRACE_ON(ddraw)) {
947 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
950 ENTER_GL();
951 draw_primitive_handle_GL_state(glThis,
952 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
953 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
954 draw_primitive_start_GL(d3dptPrimitiveType);
956 /* Some fast paths first before the generic case.... */
957 if (d3dvtVertexType == D3DFVF_VERTEX) {
958 int index;
960 for (index = 0; index < dwIndexCount; index++) {
961 int i = (dwIndices == NULL) ? index : dwIndices[index];
962 D3DVALUE *normal =
963 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
964 D3DVALUE *tex_coord =
965 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
966 D3DVALUE *position =
967 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
969 handle_normal(normal);
970 handle_texture(tex_coord);
971 handle_xyz(position);
973 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
974 position[0], position[1], position[2],
975 normal[0], normal[1], normal[2],
976 tex_coord[0], tex_coord[1]);
978 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
979 int index;
981 for (index = 0; index < dwIndexCount; index++) {
982 int i = (dwIndices == NULL) ? index : dwIndices[index];
983 DWORD *color_d =
984 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
985 DWORD *color_s =
986 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
987 D3DVALUE *tex_coord =
988 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
989 D3DVALUE *position =
990 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
992 handle_diffuse_and_specular(color_d, color_s);
993 handle_texture(tex_coord);
994 handle_xyzrhw(position);
996 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
997 position[0], position[1], position[2], position[3],
998 (*color_d >> 16) & 0xFF,
999 (*color_d >> 8) & 0xFF,
1000 (*color_d >> 0) & 0xFF,
1001 (*color_d >> 24) & 0xFF,
1002 (*color_s >> 16) & 0xFF,
1003 (*color_s >> 8) & 0xFF,
1004 (*color_s >> 0) & 0xFF,
1005 (*color_s >> 24) & 0xFF,
1006 tex_coord[0], tex_coord[1]);
1008 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1009 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1010 /* This is the 'slow path' but that should support all possible vertex formats out there...
1011 Note that people should write a fast path for all vertex formats out there...
1013 int index;
1014 for (index = 0; index < dwIndexCount; index++) {
1015 int i = (dwIndices == NULL) ? index : dwIndices[index];
1017 if (d3dvtVertexType & D3DFVF_NORMAL) {
1018 D3DVALUE *normal =
1019 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1020 handle_normal(normal);
1022 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1023 DWORD *color_d =
1024 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1025 DWORD *color_s =
1026 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1027 handle_diffuse_and_specular(color_d, color_s);
1028 } else {
1029 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1030 DWORD *color_s =
1031 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1032 handle_specular(color_s);
1033 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1034 DWORD *color_d =
1035 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1036 handle_diffuse(color_d);
1040 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1041 /* Special case for single texture... */
1042 D3DVALUE *tex_coord =
1043 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1044 handle_texture(tex_coord);
1045 } else {
1046 int tex_index;
1047 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1048 D3DVALUE *tex_coord =
1049 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1050 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1051 handle_textures(tex_coord, tex_index);
1054 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1055 D3DVALUE *position =
1056 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1057 handle_xyz(position);
1058 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1059 D3DVALUE *position =
1060 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1061 handle_xyzrhw(position);
1064 if (TRACE_ON(ddraw)) {
1065 int tex_index;
1067 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1068 D3DVALUE *position =
1069 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1070 TRACE(" %f %f %f", position[0], position[1], position[2]);
1071 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1072 D3DVALUE *position =
1073 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1074 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1076 if (d3dvtVertexType & D3DFVF_NORMAL) {
1077 D3DVALUE *normal =
1078 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1079 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1081 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1082 DWORD *color_d =
1083 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1084 DPRINTF(" / %02lx %02lx %02lx %02lx",
1085 (*color_d >> 16) & 0xFF,
1086 (*color_d >> 8) & 0xFF,
1087 (*color_d >> 0) & 0xFF,
1088 (*color_d >> 24) & 0xFF);
1090 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1091 DWORD *color_s =
1092 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1093 DPRINTF(" / %02lx %02lx %02lx %02lx",
1094 (*color_s >> 16) & 0xFF,
1095 (*color_s >> 8) & 0xFF,
1096 (*color_s >> 0) & 0xFF,
1097 (*color_s >> 24) & 0xFF);
1099 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1100 D3DVALUE *tex_coord =
1101 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1102 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1103 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1105 DPRINTF("\n");
1108 } else {
1109 ERR(" matrix weighting not handled yet....\n");
1112 glEnd();
1113 LEAVE_GL();
1114 TRACE("End\n");
1117 static void draw_primitive_7(IDirect3DDeviceImpl *This,
1118 D3DPRIMITIVETYPE d3dptPrimitiveType,
1119 DWORD d3dvtVertexType,
1120 LPVOID lpvVertices,
1121 DWORD dwVertexCount,
1122 LPWORD dwIndices,
1123 DWORD dwIndexCount,
1124 DWORD dwFlags)
1126 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1127 int current_offset = 0;
1128 int tex_index;
1130 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1131 strided.position.lpvData = lpvVertices;
1132 current_offset += 3 * sizeof(D3DVALUE);
1133 } else {
1134 strided.position.lpvData = lpvVertices;
1135 current_offset += 4 * sizeof(D3DVALUE);
1137 if (d3dvtVertexType & D3DFVF_NORMAL) {
1138 strided.normal.lpvData = ((char *) lpvVertices) + current_offset;
1139 current_offset += 3 * sizeof(D3DVALUE);
1141 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1142 strided.diffuse.lpvData = ((char *) lpvVertices) + current_offset;
1143 current_offset += sizeof(DWORD);
1145 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1146 strided.specular.lpvData = ((char *) lpvVertices) + current_offset;
1147 current_offset += sizeof(DWORD);
1149 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1150 strided.textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset;
1151 current_offset += 2*sizeof(D3DVALUE);
1153 strided.position.dwStride = current_offset;
1154 strided.normal.dwStride = current_offset;
1155 strided.diffuse.dwStride = current_offset;
1156 strided.specular.dwStride = current_offset;
1157 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
1158 strided.textureCoords[tex_index].dwStride = current_offset;
1160 draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1163 HRESULT WINAPI
1164 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1165 D3DPRIMITIVETYPE d3dptPrimitiveType,
1166 DWORD d3dvtVertexType,
1167 LPVOID lpvVertices,
1168 DWORD dwVertexCount,
1169 DWORD dwFlags)
1171 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1172 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1174 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, NULL, dwVertexCount, dwFlags);
1176 return DD_OK;
1179 HRESULT WINAPI
1180 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1181 D3DPRIMITIVETYPE d3dptPrimitiveType,
1182 DWORD d3dvtVertexType,
1183 LPVOID lpvVertices,
1184 DWORD dwVertexCount,
1185 LPWORD dwIndices,
1186 DWORD dwIndexCount,
1187 DWORD dwFlags)
1189 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1190 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1192 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1194 return DD_OK;
1197 HRESULT WINAPI
1198 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1199 D3DPRIMITIVETYPE d3dptPrimitiveType,
1200 DWORD dwVertexType,
1201 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1202 DWORD dwVertexCount,
1203 DWORD dwFlags)
1205 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1206 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
1207 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, NULL, dwVertexCount, dwFlags);
1208 return DD_OK;
1211 HRESULT WINAPI
1212 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1213 D3DPRIMITIVETYPE d3dptPrimitiveType,
1214 DWORD dwVertexType,
1215 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1216 DWORD dwVertexCount,
1217 LPWORD lpIndex,
1218 DWORD dwIndexCount,
1219 DWORD dwFlags)
1221 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1222 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1223 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1224 return DD_OK;
1227 HRESULT WINAPI
1228 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1229 DWORD dwStage,
1230 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1231 DWORD dwState)
1233 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1234 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1235 GLenum gl_state;
1237 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1239 if (TRACE_ON(ddraw)) {
1240 TRACE(" Stage type is : ");
1241 switch (d3dTexStageStateType) {
1242 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1243 GEN_CASE(D3DTSS_COLOROP);
1244 GEN_CASE(D3DTSS_COLORARG1);
1245 GEN_CASE(D3DTSS_COLORARG2);
1246 GEN_CASE(D3DTSS_ALPHAOP);
1247 GEN_CASE(D3DTSS_ALPHAARG1);
1248 GEN_CASE(D3DTSS_ALPHAARG2);
1249 GEN_CASE(D3DTSS_BUMPENVMAT00);
1250 GEN_CASE(D3DTSS_BUMPENVMAT01);
1251 GEN_CASE(D3DTSS_BUMPENVMAT10);
1252 GEN_CASE(D3DTSS_BUMPENVMAT11);
1253 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1254 GEN_CASE(D3DTSS_ADDRESS);
1255 GEN_CASE(D3DTSS_ADDRESSU);
1256 GEN_CASE(D3DTSS_ADDRESSV);
1257 GEN_CASE(D3DTSS_BORDERCOLOR);
1258 GEN_CASE(D3DTSS_MAGFILTER);
1259 GEN_CASE(D3DTSS_MINFILTER);
1260 GEN_CASE(D3DTSS_MIPFILTER);
1261 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1262 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1263 GEN_CASE(D3DTSS_MAXANISOTROPY);
1264 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1265 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1266 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1267 #undef GEN_CASE
1268 default: DPRINTF("UNKNOWN !!!");
1270 DPRINTF(" => ");
1273 switch (d3dTexStageStateType) {
1274 case D3DTSS_MINFILTER:
1275 switch ((D3DTEXTUREMINFILTER) dwState) {
1276 case D3DTFN_POINT:
1277 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1278 gl_state = GL_NEAREST;
1279 break;
1280 case D3DTFN_LINEAR:
1281 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1282 gl_state = GL_LINEAR;
1283 break;
1284 default:
1285 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1286 gl_state = GL_LINEAR;
1287 break;
1289 glThis->render_state.min = gl_state;
1290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1291 break;
1293 case D3DTSS_MAGFILTER:
1294 switch ((D3DTEXTUREMAGFILTER) dwState) {
1295 case D3DTFG_POINT:
1296 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1297 gl_state = GL_NEAREST;
1298 break;
1299 case D3DTFG_LINEAR:
1300 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1301 gl_state = GL_LINEAR;
1302 break;
1303 default:
1304 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1305 gl_state = GL_LINEAR;
1306 break;
1308 glThis->render_state.mag = gl_state;
1309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1310 break;
1312 default:
1313 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1316 return DD_OK;
1319 HRESULT WINAPI
1320 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1321 DWORD dwStage,
1322 LPDIRECTDRAWSURFACE7 lpTexture2)
1324 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1326 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1328 if (This->current_texture[dwStage] != NULL) {
1329 /* Seems that this is not right... Need to test in real Windows
1330 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1333 ENTER_GL();
1334 if (lpTexture2 == NULL) {
1335 TRACE(" disabling 2D texturing.\n");
1336 glBindTexture(GL_TEXTURE_2D, 0);
1337 glDisable(GL_TEXTURE_2D);
1338 } else {
1339 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
1340 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
1342 This->current_texture[dwStage] = tex_impl;
1343 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
1345 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1347 glEnable(GL_TEXTURE_2D);
1348 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1350 LEAVE_GL();
1352 return DD_OK;
1355 HRESULT WINAPI
1356 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1357 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1359 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1360 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1362 fill_opengl_caps_7(lpD3DHELDevDesc);
1364 TRACE(" returning caps : no dump function yet.\n");
1366 return DD_OK;
1369 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1370 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1371 #else
1372 # define XCAST(fun) (void*)
1373 #endif
1375 ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1377 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1378 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1379 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1380 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
1381 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
1382 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1383 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1384 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1385 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1386 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1387 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1388 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1389 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1390 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1391 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1392 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1393 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1394 XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
1395 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1396 XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
1397 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1398 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1399 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1400 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1401 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1402 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
1403 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1404 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
1405 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1406 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1407 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1408 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1409 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB,
1410 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
1411 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1412 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
1413 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
1414 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
1415 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
1416 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1417 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1418 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1419 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1420 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1421 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1422 XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
1423 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1424 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1425 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1426 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1429 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1430 #undef XCAST
1431 #endif
1434 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1435 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1436 #else
1437 # define XCAST(fun) (void*)
1438 #endif
1440 ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1442 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1443 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1444 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1445 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1446 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1447 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1448 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1449 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1450 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1451 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1452 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1453 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1454 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1455 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1456 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1457 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1458 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1459 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1460 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1461 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1462 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1463 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1464 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1465 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1466 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1467 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1468 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1469 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1470 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1471 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1472 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1473 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1474 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1475 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1476 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1477 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1478 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1479 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1480 XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
1481 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
1482 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1483 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1484 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1487 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1488 #undef XCAST
1489 #endif
1492 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1493 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1494 #else
1495 # define XCAST(fun) (void*)
1496 #endif
1498 ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1500 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1501 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1502 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1503 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1504 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1505 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
1506 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1507 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1508 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1509 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1510 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1511 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1512 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1513 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1514 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1515 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1516 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1517 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1518 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1519 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1520 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1521 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1522 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1523 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1524 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1525 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1526 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1527 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1528 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1529 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1530 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1531 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1532 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1533 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1536 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1537 #undef XCAST
1538 #endif
1541 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1542 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1543 #else
1544 # define XCAST(fun) (void*)
1545 #endif
1547 ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1549 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1550 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1551 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1552 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1553 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1554 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1555 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
1556 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1557 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1558 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1559 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1560 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1561 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1562 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1563 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1564 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1565 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1566 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1567 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1568 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1569 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1570 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1571 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1574 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1575 #undef XCAST
1576 #endif
1578 /* TODO for both these functions :
1579 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1580 by other OpenGL code in D3D
1581 - handle the case where no 'Begin / EndScene' was done between two locks
1582 - handle the rectangles in the unlock too
1583 - handle pitch correctly...
1585 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1587 /* First, check if we need to do anything */
1588 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1589 GLenum buffer_type;
1590 GLenum prev_read;
1591 RECT loc_rect;
1593 ENTER_GL();
1595 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1596 glFlush();
1598 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1599 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1600 /* Application wants to lock the front buffer */
1601 glReadBuffer(GL_FRONT);
1602 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1603 /* Application wants to lock the back buffer */
1604 glReadBuffer(GL_BACK);
1605 } else {
1606 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1609 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1610 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1611 } else {
1612 WARN(" unsupported pixel format.\n");
1613 LEAVE_GL();
1614 return;
1616 if (pRect == NULL) {
1617 loc_rect.top = 0;
1618 loc_rect.left = 0;
1619 loc_rect.bottom = This->surface_desc.dwHeight;
1620 loc_rect.right = This->surface_desc.dwWidth;
1621 } else {
1622 loc_rect = *pRect;
1624 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1625 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1626 + loc_rect.top * This->surface_desc.u1.lPitch
1627 + loc_rect.left * GET_BPP(This->surface_desc)));
1628 glReadBuffer(prev_read);
1629 LEAVE_GL();
1633 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1635 /* First, check if we need to do anything */
1636 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1637 GLenum buffer_type;
1638 GLenum prev_draw;
1640 ENTER_GL();
1642 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1644 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1645 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1646 /* Application wants to lock the front buffer */
1647 glDrawBuffer(GL_FRONT);
1648 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1649 /* Application wants to lock the back buffer */
1650 glDrawBuffer(GL_BACK);
1651 } else {
1652 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
1655 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1656 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1657 } else {
1658 WARN(" unsupported pixel format.\n");
1659 LEAVE_GL();
1660 return;
1662 glRasterPos2f(0.0, 0.0);
1663 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
1664 GL_RGB, buffer_type, This->surface_desc.lpSurface);
1665 glDrawBuffer(prev_draw);
1667 LEAVE_GL();
1671 HRESULT
1672 d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
1674 IDirect3DDeviceImpl *object;
1675 IDirect3DDeviceGLImpl *gl_object;
1676 IDirectDrawSurfaceImpl *surf;
1677 HDC device_context;
1678 XVisualInfo *vis;
1679 int num;
1680 XVisualInfo template;
1681 GLenum buffer;
1683 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1684 if (object == NULL) return DDERR_OUTOFMEMORY;
1686 gl_object = (IDirect3DDeviceGLImpl *) object;
1688 object->ref = 1;
1689 object->d3d = d3d;
1690 object->surface = surface;
1691 object->set_context = set_context;
1693 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1695 device_context = GetDC(surface->ddraw_owner->window);
1696 gl_object->display = get_display(device_context);
1697 gl_object->drawable = get_drawable(device_context);
1698 ReleaseDC(surface->ddraw_owner->window,device_context);
1700 ENTER_GL();
1701 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1702 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
1703 if (vis == NULL) {
1704 HeapFree(GetProcessHeap(), 0, object);
1705 ERR("No visual found !\n");
1706 LEAVE_GL();
1707 return DDERR_INVALIDPARAMS;
1708 } else {
1709 TRACE(" visual found\n");
1712 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
1713 NULL, GL_TRUE);
1715 if (gl_object->gl_context == NULL) {
1716 HeapFree(GetProcessHeap(), 0, object);
1717 ERR("Error in context creation !\n");
1718 LEAVE_GL();
1719 return DDERR_INVALIDPARAMS;
1720 } else {
1721 TRACE(" context created (%p)\n", gl_object->gl_context);
1724 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
1725 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
1726 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
1727 surf->aux_ctx = (LPVOID) gl_object->display;
1728 surf->aux_data = (LPVOID) gl_object->drawable;
1729 surf->aux_flip = opengl_flip;
1730 buffer = GL_BACK;
1731 break;
1734 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
1735 if (surf == NULL) {
1736 TRACE(" no double buffering : drawing on the front buffer\n");
1737 buffer = GL_FRONT;
1740 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
1741 for (; surf != NULL; surf = surf->next_attached) {
1742 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
1743 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
1744 /* Override the Lock / Unlock function for all these surfaces */
1745 surf->lock_update = d3ddevice_lock_update;
1746 surf->unlock_update = d3ddevice_unlock_update;
1748 surf->d3ddevice = object;
1751 gl_object->render_state.src = GL_ONE;
1752 gl_object->render_state.dst = GL_ZERO;
1753 gl_object->render_state.mag = GL_NEAREST;
1754 gl_object->render_state.min = GL_NEAREST;
1755 gl_object->render_state.alpha_ref = 0.0; /* No actual idea about the real default value... */
1756 gl_object->render_state.alpha_func = GL_ALWAYS; /* Here either but it seems logical */
1758 /* Allocate memory for the matrices */
1759 gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1760 gl_object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1761 gl_object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1763 memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float));
1764 memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float));
1765 memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float));
1767 /* Initialisation */
1768 TRACE(" setting current context\n");
1769 LEAVE_GL();
1770 object->set_context(object);
1771 ENTER_GL();
1772 TRACE(" current context set\n");
1773 glClearColor(0.0, 0.0, 0.0, 0.0);
1774 glColor3f(1.0, 1.0, 1.0);
1775 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1776 glDrawBuffer(buffer);
1777 glReadBuffer(buffer);
1778 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
1779 LEAVE_GL();
1781 /* fill_device_capabilities(d3d->ddraw); */
1783 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
1784 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
1785 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
1786 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
1788 *obj = object;
1790 TRACE(" creating implementation at %p.\n", *obj);
1792 return DD_OK;