blob: 546022de45884ea7819b75e8ac1ef222642d97d9 [file] [log] [blame]
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001/* Direct3D Device
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00002 * Copyright (c) 1998 Lionel ULMER
Vincent Béron9a624912002-05-31 23:06:46 +00003 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00004 * This file contains the MESA implementation of all the D3D devices that
5 * Wine supports.
6 *
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.
11 *
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.
16 *
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
20 */
Marcus Meissner10ad97c2000-04-09 14:30:50 +000021
Marcus Meissner10ad97c2000-04-09 14:30:50 +000022#include "config.h"
Francois Gougete5ddd262001-10-14 16:18:52 +000023
24#include <string.h>
25
Marcus Meissner10ad97c2000-04-09 14:30:50 +000026#include "windef.h"
27#include "winerror.h"
Ove Kaaven1f5315c2002-12-05 20:33:07 +000028#include "objbase.h"
Marcus Meissner10ad97c2000-04-09 14:30:50 +000029#include "ddraw.h"
30#include "d3d.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000031#include "wine/debug.h"
Marcus Meissner10ad97c2000-04-09 14:30:50 +000032
33#include "mesa_private.h"
Lionel Ulmer43c3dc42002-11-21 21:04:16 +000034#include "main.h"
Marcus Meissner10ad97c2000-04-09 14:30:50 +000035
Christian Costa427b3332002-09-27 22:01:12 +000036#include "x11drv.h"
37
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000038WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000039
Lionel Ulmer43c3dc42002-11-21 21:04:16 +000040/* They are non-static as they are used by Direct3D in the creation function */
41const GUID IID_D3DDEVICE_OpenGL = {
42 0x31416d44,
43 0x86ae,
44 0x11d2,
45 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
46};
47
Lionel Ulmer1434d872000-07-23 14:23:31 +000048#ifndef HAVE_GLEXT_PROTOTYPES
49/* This is for non-OpenGL ABI compliant glext.h headers :-) */
50typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
51 GLsizei width, GLenum format, GLenum type,
52 const GLvoid *table);
53#endif
54
Lionel Ulmera8cc5f52000-07-16 14:40:35 +000055static const float id_mat[16] = {
Lionel Ulmer43c3dc42002-11-21 21:04:16 +000056 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
Lionel Ulmera8cc5f52000-07-16 14:40:35 +000060};
61
Christian Costa427b3332002-09-27 22:01:12 +000062/* retrieve the X display to use on a given DC */
63inline static Display *get_display( HDC hdc )
64{
65 Display *display;
66 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
67
68 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
69 sizeof(display), (LPSTR)&display )) display = NULL;
70
71 return display;
72}
73
74
75/* retrieve the X drawable to use on a given DC */
76inline static Drawable get_drawable( HDC hdc )
77{
78 Drawable drawable;
79 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
80
81 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
82 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
83
84 return drawable;
85}
86
Christian Costab47c14a2002-10-17 01:20:52 +000087
88static BOOL opengl_flip( LPVOID display, LPVOID drawable)
89{
90 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
91 ENTER_GL();
92 glXSwapBuffers((Display*)display,(Drawable)drawable);
93 LEAVE_GL();
94 return TRUE;
95}
96
97
Marcus Meissner10ad97c2000-04-09 14:30:50 +000098/*******************************************************************************
99 * OpenGL static functions
100 */
Christian Costa774c5f72002-11-24 22:14:40 +0000101static void set_context(IDirect3DDeviceImpl* This)
102{
103 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
104
Christian Costa427b3332002-09-27 22:01:12 +0000105 ENTER_GL();
Christian Costa774c5f72002-11-24 22:14:40 +0000106 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
107 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
Christian Costa427b3332002-09-27 22:01:12 +0000108 ERR("Error in setting current context (context %p drawable %ld)!\n",
Christian Costa774c5f72002-11-24 22:14:40 +0000109 glThis->gl_context, glThis->drawable);
Christian Costa427b3332002-09-27 22:01:12 +0000110 }
111 LEAVE_GL();
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000112}
113
114static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
115{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000116 pc->dwSize = sizeof(*pc);
117 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
118 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
119 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
120 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
121 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
122 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
123 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
124 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
125 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
126 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
127 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
128 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
129 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
130 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
131 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
132 pc->dwStippleWidth = 32;
133 pc->dwStippleHeight = 32;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000134}
135
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000136static void fill_opengl_caps(D3DDEVICEDESC *d1)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000137{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000138 /* GLint maxlight; */
Vincent Béron9a624912002-05-31 23:06:46 +0000139
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000140 d1->dwSize = sizeof(*d1);
141 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
142 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
143 d1->dcmColorModel = D3DCOLOR_RGB;
144 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
145 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000146 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000147 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
148 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
149 d1->bClipping = TRUE;
150 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
151 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
152 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
153 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
154 fill_opengl_primcaps(&(d1->dpcLineCaps));
155 fill_opengl_primcaps(&(d1->dpcTriCaps));
Lionel Ulmer5261f032002-12-02 21:39:34 +0000156 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000157 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000158 d1->dwMaxBufferSize = 0;
159 d1->dwMaxVertexCount = 65536;
160 d1->dwMinTextureWidth = 1;
161 d1->dwMinTextureHeight = 1;
162 d1->dwMaxTextureWidth = 1024;
163 d1->dwMaxTextureHeight = 1024;
164 d1->dwMinStippleWidth = 1;
165 d1->dwMinStippleHeight = 1;
166 d1->dwMaxStippleWidth = 32;
167 d1->dwMaxStippleHeight = 32;
Lionel Ulmerda0b4dc2002-11-30 01:49:08 +0000168 d1->dwMaxTextureRepeat = 16;
169 d1->dwMaxTextureAspectRatio = 1024;
170 d1->dwMaxAnisotropy = 0;
171 d1->dvGuardBandLeft = 0.0;
172 d1->dvGuardBandRight = 0.0;
173 d1->dvGuardBandTop = 0.0;
174 d1->dvGuardBandBottom = 0.0;
175 d1->dvExtentsAdjust = 0.0;
176 d1->dwStencilCaps = 0; /* TODO add proper caps according to what OpenGL can do */
177 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
178 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
179 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
180 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000181}
182
Lionel Ulmerf4b941e2002-11-30 19:21:42 +0000183static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
184{
185 D3DDEVICEDESC d1;
186
187 /* Copy first D3D1/2/3 capabilities */
188 fill_opengl_caps(&d1);
189
190 /* And fill the D3D7 one with it */
191 d->dwDevCaps = d1.dwDevCaps;
192 d->dpcLineCaps = d1.dpcLineCaps;
193 d->dpcTriCaps = d1.dpcTriCaps;
194 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
195 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
196 d->dwMinTextureWidth = d1.dwMinTextureWidth;
197 d->dwMinTextureHeight = d1.dwMinTextureHeight;
198 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
199 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
200 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
201 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
202 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
203 d->dvGuardBandLeft = d1.dvGuardBandLeft;
204 d->dvGuardBandTop = d1.dvGuardBandTop;
205 d->dvGuardBandRight = d1.dvGuardBandRight;
206 d->dvGuardBandBottom = d1.dvGuardBandBottom;
207 d->dvExtentsAdjust = d1.dvExtentsAdjust;
208 d->dwStencilCaps = d1.dwStencilCaps;
209 d->dwFVFCaps = d1.dwFVFCaps;
210 d->dwTextureOpCaps = d1.dwTextureOpCaps;
211 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
212 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
213 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
214 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
215 d->deviceGUID = IID_IDirect3DTnLHalDevice;
216 d->wMaxUserClipPlanes = 1;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000217 d->wMaxVertexBlendMatrices = 0;
Lionel Ulmerf4b941e2002-11-30 19:21:42 +0000218 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
219 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
220 d->dwReserved1 = 0;
221 d->dwReserved2 = 0;
222 d->dwReserved3 = 0;
223 d->dwReserved4 = 0;
224}
225
Lionel Ulmerda0b4dc2002-11-30 01:49:08 +0000226#if 0 /* TODO : fix this and add multitexturing and other needed stuff */
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000227static void fill_device_capabilities(IDirectDrawImpl* ddraw)
228{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000229 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
230 const char *ext_string;
231 Mesa_DeviceCapabilities *devcap;
Vincent Béron9a624912002-05-31 23:06:46 +0000232
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000233 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
234 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
Vincent Béron9a624912002-05-31 23:06:46 +0000235
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000236 ENTER_GL();
237 ext_string = glGetString(GL_EXTENSIONS);
238 /* Query for the ColorTable Extension */
239 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
240 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
241 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
242 } else {
243 TRACE("Color table extension not found.\n");
244 }
245 LEAVE_GL();
Lionel Ulmera8cc5f52000-07-16 14:40:35 +0000246}
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000247#endif
Lionel Ulmera8cc5f52000-07-16 14:40:35 +0000248
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000249
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000250
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000251HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000252{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000253 D3DDEVICEDESC d1, d2;
Christian Costa427b3332002-09-27 22:01:12 +0000254
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000255 fill_opengl_caps(&d1);
256 d2 = d1;
257
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000258 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
259 return cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000260}
261
Lionel Ulmerf4b941e2002-11-30 19:21:42 +0000262HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
263{
264 D3DDEVICEDESC7 ddesc;
265
266 fill_opengl_caps_7(&ddesc);
267
268 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
269
270 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
271}
272
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000273ULONG WINAPI
274GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
275{
276 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
277 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
278
279 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
280 if (!--(This->ref)) {
281 /* Release texture associated with the device */
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +0000282 if (This->current_texture[0] != NULL)
283 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000284
285 ENTER_GL();
286 glXDestroyContext(glThis->display, glThis->gl_context);
287 LEAVE_GL();
288
289 HeapFree(GetProcessHeap(), 0, This);
290 return 0;
291 }
292 return This->ref;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000293}
294
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000295HRESULT WINAPI
296GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
297 LPD3DDEVICEDESC lpD3DHWDevDesc,
298 LPD3DDEVICEDESC lpD3DHELDevDesc)
299{
300 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
301 D3DDEVICEDESC desc;
302 DWORD dwSize;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000303
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000304 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
Vincent Béron9a624912002-05-31 23:06:46 +0000305
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000306 fill_opengl_caps(&desc);
307 dwSize = lpD3DHWDevDesc->dwSize;
308 memset(lpD3DHWDevDesc, 0, dwSize);
309 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
310
311 dwSize = lpD3DHELDevDesc->dwSize;
312 memset(lpD3DHELDevDesc, 0, dwSize);
313 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
314
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000315 TRACE(" returning caps : (no dump function yet)\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000316
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000317 return DD_OK;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000318}
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000319
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000320static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
321 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
322 LPVOID context)
323{
324 DDSURFACEDESC sdesc;
325 LPDDPIXELFORMAT pformat;
326
327 /* Do the texture enumeration */
328 sdesc.dwSize = sizeof(DDSURFACEDESC);
329 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
330 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
331 pformat = &(sdesc.ddpfPixelFormat);
332 pformat->dwSize = sizeof(DDPIXELFORMAT);
333 pformat->dwFourCC = 0;
334
335 TRACE("Enumerating GL_RGBA unpacked (32)\n");
336 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
337 pformat->u1.dwRGBBitCount = 32;
338 pformat->u2.dwRBitMask = 0xFF000000;
339 pformat->u3.dwGBitMask = 0x00FF0000;
340 pformat->u4.dwBBitMask = 0x0000FF00;
341 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
342 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
343 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
344
345 TRACE("Enumerating GL_RGB unpacked (24)\n");
346 pformat->dwFlags = DDPF_RGB;
347 pformat->u1.dwRGBBitCount = 24;
348 pformat->u2.dwRBitMask = 0x00FF0000;
349 pformat->u3.dwGBitMask = 0x0000FF00;
350 pformat->u4.dwBBitMask = 0x000000FF;
351 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
352 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
353 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000354
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000355 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
356 pformat->dwFlags = DDPF_RGB;
357 pformat->u1.dwRGBBitCount = 16;
358 pformat->u2.dwRBitMask = 0x0000F800;
359 pformat->u3.dwGBitMask = 0x000007E0;
360 pformat->u4.dwBBitMask = 0x0000001F;
361 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
362 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
363 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000364
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000365 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
366 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
367 pformat->u1.dwRGBBitCount = 16;
368 pformat->u2.dwRBitMask = 0x0000F800;
369 pformat->u3.dwGBitMask = 0x000007C0;
370 pformat->u4.dwBBitMask = 0x0000003E;
371 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
372 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
373 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000374
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000375 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
376 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
377 pformat->u1.dwRGBBitCount = 16;
378 pformat->u2.dwRBitMask = 0x0000F000;
379 pformat->u3.dwGBitMask = 0x00000F00;
380 pformat->u4.dwBBitMask = 0x000000F0;
381 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
382 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
383 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000384
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000385 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
386 pformat->dwFlags = DDPF_RGB;
387 pformat->u1.dwRGBBitCount = 8;
388 pformat->u2.dwRBitMask = 0x000000E0;
389 pformat->u3.dwGBitMask = 0x0000001C;
390 pformat->u4.dwBBitMask = 0x00000003;
391 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
392 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
393 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000394
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000395 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
396 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
397 pformat->u1.dwRGBBitCount = 16;
398 pformat->u2.dwRBitMask = 0x00007C00;
399 pformat->u3.dwGBitMask = 0x000003E0;
400 pformat->u4.dwBBitMask = 0x0000001F;
401 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
402 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
403 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
404
405 TRACE("Enumerating Paletted (8)\n");
406 pformat->dwFlags = DDPF_PALETTEINDEXED8;
407 pformat->u1.dwRGBBitCount = 8;
408 pformat->u2.dwRBitMask = 0x00000000;
409 pformat->u3.dwGBitMask = 0x00000000;
410 pformat->u4.dwBBitMask = 0x00000000;
411 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
412 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
413 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
414
415 TRACE("End of enumeration\n");
Vincent Béron9a624912002-05-31 23:06:46 +0000416 return DD_OK;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000417}
Vincent Béron9a624912002-05-31 23:06:46 +0000418
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000419
420HRESULT
421d3ddevice_find(IDirect3DImpl *d3d,
422 LPD3DFINDDEVICESEARCH lpD3DDFS,
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000423 LPD3DFINDDEVICERESULT lplpD3DDevice)
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000424{
425 DWORD dwSize;
426 D3DDEVICEDESC desc;
427
428 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
429 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
430 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
431 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
432 }
433 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
434 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
435 if ((IsEqualGUID( &IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000436 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0)) {
437 TRACE(" no match for this GUID.\n");
438 return DDERR_INVALIDPARAMS;
439 }
440 }
441
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000442 /* Now return our own GUID */
443 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000444 fill_opengl_caps(&desc);
445 dwSize = lplpD3DDevice->ddHwDesc.dwSize;
446 memset(&(lplpD3DDevice->ddHwDesc), 0, dwSize);
447 memcpy(&(lplpD3DDevice->ddHwDesc), &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
448 dwSize = lplpD3DDevice->ddSwDesc.dwSize;
449 memset(&(lplpD3DDevice->ddSwDesc), 0, dwSize);
450 memcpy(&(lplpD3DDevice->ddSwDesc), &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
451
452 return D3D_OK;
453}
454
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000455HRESULT WINAPI
456GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
457 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
458 LPVOID lpArg)
459{
460 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
461 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
462 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
463}
464
465HRESULT WINAPI
466GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
467 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
468 LPVOID lpArg)
469{
470 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
471 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
472 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
473}
474
475HRESULT WINAPI
476GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
477 D3DRENDERSTATETYPE dwRenderStateType,
478 DWORD dwRenderState)
479{
480 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
481 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
482 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
483
484 /* Call the render state functions */
485 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
486
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000487 return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000488}
489
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000490HRESULT WINAPI
491GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
492 D3DLIGHTSTATETYPE dwLightStateType,
493 DWORD dwLightState)
494{
495 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
496 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
Vincent Béron9a624912002-05-31 23:06:46 +0000497
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000498 switch (dwLightStateType) {
499 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
500 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000501
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000502 if (mat != NULL) {
503 ENTER_GL();
504 mat->activate(mat);
505 LEAVE_GL();
506 } else {
507 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
508 }
509 } break;
Vincent Béron9a624912002-05-31 23:06:46 +0000510
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000511 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
512 float light[4];
Vincent Béron9a624912002-05-31 23:06:46 +0000513
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000514 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
515 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
516 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
517 light[3] = 1.0;
518 ENTER_GL();
519 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
520 LEAVE_GL();
521 } break;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000522
523#define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000524 UNSUP(COLORMODEL);
525 UNSUP(FOGMODE);
526 UNSUP(FOGSTART);
527 UNSUP(FOGEND);
528 UNSUP(FOGDENSITY);
Christian Costa2db04152002-12-02 21:11:47 +0000529 UNSUP(COLORVERTEX);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000530#undef UNSUP
Vincent Béron9a624912002-05-31 23:06:46 +0000531
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000532 default:
533 TRACE("Unexpected Light State Type\n");
534 return DDERR_INVALIDPARAMS;
535 }
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000536
Marcus Meissner3873f442000-04-10 13:45:17 +0000537 return DD_OK;
538}
539
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000540HRESULT WINAPI
541GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
542 D3DTRANSFORMSTATETYPE dtstTransformStateType,
543 LPD3DMATRIX lpD3DMatrix)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000544{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000545 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
546 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
Vincent Béron9a624912002-05-31 23:06:46 +0000547
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000548 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
Vincent Béron9a624912002-05-31 23:06:46 +0000549
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000550 ENTER_GL();
Vincent Béron9a624912002-05-31 23:06:46 +0000551
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000552 /* Using a trial and failure approach, I found that the order of
553 Direct3D transformations that works best is :
Vincent Béron9a624912002-05-31 23:06:46 +0000554
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000555 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
Vincent Béron9a624912002-05-31 23:06:46 +0000556
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000557 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
558 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
Vincent Béron9a624912002-05-31 23:06:46 +0000559
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000560 If anyone has a good explanation of the three different matrices in
561 the SDK online documentation, feel free to point it to me. For example,
562 which matrices transform lights ? In OpenGL only the PROJECTION matrix
563 transform the lights, not the MODELVIEW. Using the matrix names, I
564 supposed that PROJECTION and VIEW (all 'camera' related names) do
565 transform lights, but WORLD do not. It may be wrong though... */
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000566
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000567 /* After reading through both OpenGL and Direct3D documentations, I
568 thought that D3D matrices were written in 'line major mode' transposed
569 from OpenGL's 'column major mode'. But I found out that a simple memcpy
570 works fine to transfer one matrix format to the other (it did not work
571 when transposing)....
Vincent Béron9a624912002-05-31 23:06:46 +0000572
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000573 So :
574 1) are the documentations wrong
575 2) does the matrix work even if they are not read correctly
576 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
577 loading using glLoadMatrix ?
Vincent Béron9a624912002-05-31 23:06:46 +0000578
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000579 Anyway, I always use 'conv_mat' to transfer the matrices from one format
580 to the other so that if I ever find out that I need to transpose them, I
581 will able to do it quickly, only by changing the macro conv_mat. */
Vincent Béron9a624912002-05-31 23:06:46 +0000582
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000583 switch (dtstTransformStateType) {
584 case D3DTRANSFORMSTATE_WORLD: {
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000585 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000586 conv_mat(lpD3DMatrix, glThis->world_mat);
587 glMatrixMode(GL_MODELVIEW);
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000588 glLoadMatrixf((float *) glThis->view_mat);
589 glMultMatrixf((float *) glThis->world_mat);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000590 } break;
591
592 case D3DTRANSFORMSTATE_VIEW: {
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000593 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000594 conv_mat(lpD3DMatrix, glThis->view_mat);
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000595 glMatrixMode(GL_MODELVIEW);
596 glLoadMatrixf((float *) glThis->view_mat);
597 glMultMatrixf((float *) glThis->world_mat);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000598 } break;
599
600 case D3DTRANSFORMSTATE_PROJECTION: {
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000601 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000602 conv_mat(lpD3DMatrix, glThis->proj_mat);
603 glMatrixMode(GL_PROJECTION);
604 glLoadMatrixf((float *) glThis->proj_mat);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000605 } break;
606
607 default:
608 ERR("Unknown trasnform type %08x !!!\n", dtstTransformStateType);
609 break;
610 }
611 LEAVE_GL();
612
613 return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000614}
615
Lionel Ulmera6e50802002-11-30 19:19:00 +0000616static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000617{
618 switch (d3dpt) {
619 case D3DPT_POINTLIST:
620 TRACE("Start POINTS\n");
621 glBegin(GL_POINTS);
622 break;
623
624 case D3DPT_LINELIST:
625 TRACE("Start LINES\n");
626 glBegin(GL_LINES);
627 break;
628
629 case D3DPT_LINESTRIP:
630 TRACE("Start LINE_STRIP\n");
631 glBegin(GL_LINE_STRIP);
632 break;
633
634 case D3DPT_TRIANGLELIST:
635 TRACE("Start TRIANGLES\n");
636 glBegin(GL_TRIANGLES);
637 break;
638
639 case D3DPT_TRIANGLESTRIP:
640 TRACE("Start TRIANGLE_STRIP\n");
641 glBegin(GL_TRIANGLE_STRIP);
642 break;
643
644 case D3DPT_TRIANGLEFAN:
645 TRACE("Start TRIANGLE_FAN\n");
646 glBegin(GL_TRIANGLE_FAN);
647 break;
648
649 default:
650 TRACE("Unhandled primitive\n");
651 break;
652 }
653}
654
Lionel Ulmera6e50802002-11-30 19:19:00 +0000655static void draw_primitive_handle_GL_state(IDirect3DDeviceGLImpl *glThis,
656 BOOLEAN vertex_transformed,
657 BOOLEAN vertex_lit) {
658 /* Puts GL in the correct lighting / transformation mode */
659 if ((glThis->last_vertices_transformed == TRUE) && (vertex_transformed == FALSE)) {
660 /* Need to put the correct transformation again if we go from Transformed
661 vertices to non-transformed ones.
662 */
663 glMatrixMode(GL_MODELVIEW);
664 glLoadMatrixf((float *) glThis->view_mat);
665 glMultMatrixf((float *) glThis->world_mat);
666 glMatrixMode(GL_PROJECTION);
667 glLoadMatrixf((float *) glThis->proj_mat);
668 } else if ((glThis->last_vertices_transformed == FALSE) && (vertex_transformed == TRUE)) {
669 GLdouble height, width, minZ, maxZ;
670
671 glMatrixMode(GL_MODELVIEW);
672 glLoadIdentity();
673 glMatrixMode(GL_PROJECTION);
674 glLoadIdentity();
675
676 if (glThis->parent.current_viewport == NULL) {
677 ERR("No current viewport !\n");
678 /* Using standard values */
679 height = 640.0;
680 width = 480.0;
681 minZ = -10.0;
682 maxZ = 10.0;
683 } else {
684 if (glThis->parent.current_viewport->use_vp2 == 1) {
685 height = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwHeight;
686 width = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwWidth;
687 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMinZ;
688 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMaxZ;
689 } else {
690 height = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwHeight;
691 width = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwWidth;
692 minZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMinZ;
693 maxZ = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMaxZ;
694 }
695 }
696 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
697 }
698
699 if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) {
700 glEnable(GL_LIGHTING);
701 } else if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == TRUE)) {
702 glDisable(GL_LIGHTING);
703 }
704
705 /* And save the current state */
706 glThis->last_vertices_transformed = vertex_transformed;
707 glThis->last_vertices_lit = vertex_lit;
708}
709
710
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000711inline static void draw_primitive(IDirect3DDeviceGLImpl *glThis, DWORD maxvert, WORD *index,
712 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000713{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000714 DWORD vx_index;
715
Lionel Ulmera6e50802002-11-30 19:19:00 +0000716 draw_primitive_handle_GL_state(glThis, d3dvt == D3DVT_TLVERTEX, d3dvt != D3DVT_VERTEX);
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000717 draw_primitive_start_GL(d3dpt);
718
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000719 /* Draw the primitives */
720 for (vx_index = 0; vx_index < maxvert; vx_index++) {
721 switch (d3dvt) {
722 case D3DVT_VERTEX: {
723 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
724
725 glNormal3f(vx->u4.nx, vx->u5.ny, vx->u6.nz);
726 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
727 TRACE(" V: %f %f %f\n", vx->u1.x, vx->u2.y, vx->u3.z);
728 } break;
729
730 case D3DVT_LVERTEX: {
731 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
732 DWORD col = vx->u4.color;
733
734 glColor3f(((col >> 16) & 0xFF) / 255.0,
735 ((col >> 8) & 0xFF) / 255.0,
736 ((col >> 0) & 0xFF) / 255.0);
737 glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
738 TRACE(" LV: %f %f %f (%02lx %02lx %02lx)\n",
739 vx->u1.x, vx->u2.y, vx->u3.z,
740 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF));
741 } break;
742
743 case D3DVT_TLVERTEX: {
744 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
745 DWORD col = vx->u5.color;
746
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000747 glColor4ub((col >> 24) & 0xFF,
748 (col >> 16) & 0xFF,
749 (col >> 8) & 0xFF,
750 (col >> 0) & 0xFF);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000751 glTexCoord2f(vx->u7.tu, vx->u8.tv);
752 if (vx->u4.rhw < 0.01)
753 glVertex3f(vx->u1.sx,
754 vx->u2.sy,
755 vx->u3.sz);
756 else
757 glVertex4f(vx->u1.sx / vx->u4.rhw,
758 vx->u2.sy / vx->u4.rhw,
759 vx->u3.sz / vx->u4.rhw,
760 1.0 / vx->u4.rhw);
761 TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",
762 vx->u1.sx, vx->u2.sy, vx->u3.sz,
763 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF),
764 vx->u7.tu, vx->u8.tv, vx->u4.rhw);
765 } break;
766
767 default:
768 FIXME("Unhandled vertex type\n");
769 break;
770 }
771 }
772
773 glEnd();
774 TRACE("End\n");
775}
776
777HRESULT WINAPI
778GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
779 D3DPRIMITIVETYPE d3dptPrimitiveType,
780 D3DVERTEXTYPE d3dvtVertexType,
781 LPVOID lpvVertices,
782 DWORD dwVertexCount,
783 DWORD dwFlags)
784{
785 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
786 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
787
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000788 ENTER_GL();
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000789 draw_primitive((IDirect3DDeviceGLImpl *) This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
790 LEAVE_GL();
791
792 return DD_OK;
793}
Christian Costab47c14a2002-10-17 01:20:52 +0000794
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000795HRESULT WINAPI
796GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
797 D3DPRIMITIVETYPE d3dptPrimitiveType,
798 D3DVERTEXTYPE d3dvtVertexType,
799 LPVOID lpvVertices,
800 DWORD dwVertexCount,
801 LPWORD dwIndices,
802 DWORD dwIndexCount,
803 DWORD dwFlags)
804{
805 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
806 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
807
808 ENTER_GL();
809 draw_primitive((IDirect3DDeviceGLImpl *) This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
810 LEAVE_GL();
811
812 return DD_OK;
813}
814
815HRESULT WINAPI
816GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
817 LPD3DEXECUTEBUFFERDESC lpDesc,
818 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
819 IUnknown* pUnkOuter)
820{
821 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
822 IDirect3DExecuteBufferImpl *ret;
823 HRESULT ret_value;
824
825 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
826
827 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
828 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
829
830 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
831
832 return ret_value;
833}
834
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000835DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000836{
837 DWORD size = 0;
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000838 DWORD elts = 0;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000839
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000840 if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
841 if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
842 if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000843 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000844 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
845 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000846 default: TRACE(" matrix weighting not handled yet...\n");
847 }
848 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000849 elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
850
851 if (elements) *elements = elts;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000852
853 return size;
854}
855
856void dump_flexible_vertex(DWORD d3dvtVertexType)
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000857{
858 static const flag_info flags[] = {
859 FE(D3DFVF_NORMAL),
860 FE(D3DFVF_RESERVED1),
861 FE(D3DFVF_DIFFUSE),
862 FE(D3DFVF_SPECULAR)
863 };
864 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
865 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
866#define GEN_CASE(a) case a: DPRINTF(#a " "); break
867 GEN_CASE(D3DFVF_XYZ);
868 GEN_CASE(D3DFVF_XYZRHW);
869 GEN_CASE(D3DFVF_XYZB1);
870 GEN_CASE(D3DFVF_XYZB2);
871 GEN_CASE(D3DFVF_XYZB3);
872 GEN_CASE(D3DFVF_XYZB4);
873 GEN_CASE(D3DFVF_XYZB5);
874 }
875 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
876 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
877 GEN_CASE(D3DFVF_TEX0);
878 GEN_CASE(D3DFVF_TEX1);
879 GEN_CASE(D3DFVF_TEX2);
880 GEN_CASE(D3DFVF_TEX3);
881 GEN_CASE(D3DFVF_TEX4);
882 GEN_CASE(D3DFVF_TEX5);
883 GEN_CASE(D3DFVF_TEX6);
884 GEN_CASE(D3DFVF_TEX7);
885 GEN_CASE(D3DFVF_TEX8);
886 }
887#undef GEN_CASE
888 DPRINTF("\n");
889}
890
891/* Some types used by the fast paths... */
892typedef struct {
893 float x, y, z;
894 float nx, ny, nz;
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000895 float tu1, tv1;
896} D3DFVF_VERTEX_1;
897
Lionel Ulmera6e50802002-11-30 19:19:00 +0000898typedef struct {
899 float x, y, z, rhw;
900 DWORD diffuse;
901 DWORD specular;
902 float tu1, tv1;
903} D3DFVF_TLVERTEX_1;
904
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000905typedef struct {
906 int offset;
907 int extra;
908 void (*handler)(char *vertex, int offset, int extra);
909} D3DFVF_GENERIC;
910
911/* These are the various handler used in the generic path */
912static void handle_xyz(char *vertex, int offset, int extra) {
913 glVertex3fv((float *) (vertex + offset));
914}
915static void handle_xyzrhw(char *vertex, int offset, int extra) {
916 float *coords = (float *) (vertex + offset);
917 if (coords[3] < 0.00001)
918 glVertex3f(coords[0], coords[1], coords[2]);
919 else
920 glVertex4f(coords[0] / coords[3],
921 coords[1] / coords[3],
922 coords[2] / coords[3],
923 1.0 / coords[3]);
924}
925static void handle_normal(char *vertex, int offset, int extra) {
926 glNormal3fv((float *) (vertex + offset));
927}
928static void handle_specular(char *vertex, int offset, int extra) {
929 /* Specular not handled yet properly... */
930}
931static void handle_diffuse(char *vertex, int offset, int extra) {
932 DWORD color = *((DWORD *) (vertex + offset));
933 glColor4ub((color >> 24) & 0xFF,
934 (color >> 16) & 0xFF,
935 (color >> 8) & 0xFF,
936 (color >> 0) & 0xFF);
937}
938static void handle_texture(char *vertex, int offset, int extra) {
939 if (extra == 0xFF) {
940 /* Special case for single texture... */
941 glTexCoord2fv((float *) (vertex + offset));
942 } else {
943 /* Multitexturing not handled yet */
944 }
945}
946
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000947static void draw_primitive_7(IDirect3DDeviceImpl *This,
948 D3DPRIMITIVETYPE d3dptPrimitiveType,
949 DWORD d3dvtVertexType,
950 LPVOID lpvVertices,
951 DWORD dwVertexCount,
952 LPWORD dwIndices,
953 DWORD dwIndexCount,
954 DWORD dwFlags)
955{
Lionel Ulmera6e50802002-11-30 19:19:00 +0000956 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000957 if (TRACE_ON(ddraw)) {
958 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
959 }
960
961 ENTER_GL();
Lionel Ulmera6e50802002-11-30 19:19:00 +0000962 draw_primitive_handle_GL_state(glThis,
963 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
964 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000965 draw_primitive_start_GL(d3dptPrimitiveType);
966
967 /* Some fast paths first before the generic case.... */
968 if (d3dvtVertexType == D3DFVF_VERTEX) {
969 D3DFVF_VERTEX_1 *vertices = (D3DFVF_VERTEX_1 *) lpvVertices;
970 int index;
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000971
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000972 for (index = 0; index < dwIndexCount; index++) {
973 int i = (dwIndices == NULL) ? index : dwIndices[index];
974
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000975 glNormal3fv(&(vertices[i].nx));
976 glTexCoord2fv(&(vertices[i].tu1));
977 glVertex3fv(&(vertices[i].x));
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000978 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000979 vertices[i].x, vertices[i].y, vertices[i].z,
980 vertices[i].nx, vertices[i].ny, vertices[i].nz,
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000981 vertices[i].tu1, vertices[i].tv1);
982 }
Lionel Ulmera6e50802002-11-30 19:19:00 +0000983 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
984 D3DFVF_TLVERTEX_1 *vertices = (D3DFVF_TLVERTEX_1 *) lpvVertices;
985 int index;
986
987 for (index = 0; index < dwIndexCount; index++) {
988 int i = (dwIndices == NULL) ? index : dwIndices[index];
989
990 glColor4ub((vertices[i].diffuse >> 24) & 0xFF,
991 (vertices[i].diffuse >> 16) & 0xFF,
992 (vertices[i].diffuse >> 8) & 0xFF,
993 (vertices[i].diffuse >> 0) & 0xFF);
994 /* Todo : handle specular... */
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000995 glTexCoord2fv(&(vertices[i].tu1));
Lionel Ulmera6e50802002-11-30 19:19:00 +0000996 if (vertices[i].rhw < 0.00001)
997 glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
998 else
999 glVertex4f(vertices[i].x / vertices[i].rhw,
1000 vertices[i].y / vertices[i].rhw,
1001 vertices[i].z / vertices[i].rhw,
1002 1.0 / vertices[i].rhw);
1003 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1004 vertices[i].x, vertices[i].y, vertices[i].z, vertices[i].rhw,
1005 (vertices[i].diffuse >> 24) & 0xFF,
1006 (vertices[i].diffuse >> 16) & 0xFF,
1007 (vertices[i].diffuse >> 8) & 0xFF,
1008 (vertices[i].diffuse >> 0) & 0xFF,
1009 (vertices[i].specular >> 24) & 0xFF,
1010 (vertices[i].specular >> 16) & 0xFF,
1011 (vertices[i].specular >> 8) & 0xFF,
1012 (vertices[i].specular >> 0) & 0xFF,
1013 vertices[i].tu1, vertices[i].tv1);
1014 }
Lionel Ulmer91c6f812002-12-15 01:17:59 +00001015 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1016 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1017 /* This is the 'slow path' but that should support all possible vertex formats out there...
1018 Note that people should write a fast path for all vertex formats out there...
1019 */
1020 DWORD elements;
1021 DWORD size = get_flexible_vertex_size(d3dvtVertexType, &elements);
1022 char *vertices = (char *) lpvVertices;
1023 int index;
1024 int current_offset = 0;
1025 int current_position = 0;
1026 D3DFVF_GENERIC *handler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, elements * sizeof(D3DFVF_GENERIC));
1027
1028 WARN(" using draw_primitive generic path - for better performance, add a fast path for your vertex case !\n");
1029
1030 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1031 handler[elements - 1].handler = handle_xyz;
1032 handler[elements - 1].offset = current_offset;
1033 current_offset += 3 * sizeof(D3DVALUE);
1034 } else {
1035 handler[elements - 1].handler = handle_xyzrhw;
1036 handler[elements - 1].offset = current_offset;
1037 current_offset += 4 * sizeof(D3DVALUE);
1038 }
1039 if (d3dvtVertexType & D3DFVF_NORMAL) {
1040 handler[current_position].handler = handle_normal;
1041 handler[current_position].offset = current_offset;
1042 current_position += 1;
1043 current_offset += 3 * sizeof(D3DVALUE);
1044 }
1045 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1046 handler[current_position].handler = handle_diffuse;
1047 handler[current_position].offset = current_offset;
1048 current_position += 1;
1049 current_offset += sizeof(DWORD);
1050 }
1051 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1052 handler[current_position].handler = handle_specular;
1053 handler[current_position].offset = current_offset;
1054 current_position += 1;
1055 current_offset += sizeof(DWORD);
1056 }
1057 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1058 handler[current_position].handler = handle_texture;
1059 handler[current_position].offset = current_offset;
1060 handler[current_position].extra = 0xFF;
1061 current_position += 1;
1062 current_offset += 2 * sizeof(D3DVALUE);
1063 } else {
1064 int tex_index;
1065 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1066 handler[current_position].handler = handle_texture;
1067 handler[current_position].offset = current_offset;
1068 handler[current_position].extra = tex_index;
1069 current_position += 1;
1070 current_offset += 2 * sizeof(D3DVALUE);
1071 }
1072 }
1073
1074 for (index = 0; index < dwIndexCount; index++) {
1075 int i = (dwIndices == NULL) ? index : dwIndices[index];
1076 int elt;
1077 char *vertex = vertices + (i * size);
1078
1079 for (elt = 0; elt < elements; elt++) {
1080 handler[elt].handler(vertex, handler[elt].offset, handler[elt].extra);
1081 }
1082 }
1083 } else {
1084 ERR(" matrix weighting not handled yet....\n");
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001085 }
1086
1087 glEnd();
1088 LEAVE_GL();
1089 TRACE("End\n");
1090}
1091
1092
1093HRESULT WINAPI
1094GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1095 D3DPRIMITIVETYPE d3dptPrimitiveType,
1096 DWORD d3dvtVertexType,
1097 LPVOID lpvVertices,
1098 DWORD dwVertexCount,
1099 DWORD dwFlags)
1100{
1101 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1102 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1103
1104 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, NULL, dwVertexCount, dwFlags);
1105
1106 return DD_OK;
1107}
1108
1109HRESULT WINAPI
1110GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1111 D3DPRIMITIVETYPE d3dptPrimitiveType,
1112 DWORD d3dvtVertexType,
1113 LPVOID lpvVertices,
1114 DWORD dwVertexCount,
1115 LPWORD dwIndices,
1116 DWORD dwIndexCount,
1117 DWORD dwFlags)
1118{
1119 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1120 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1121
1122 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1123
1124 return DD_OK;
1125}
1126
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001127HRESULT WINAPI
1128GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1129 DWORD dwStage,
1130 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1131 DWORD dwState)
1132{
1133 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1134 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1135 GLenum gl_state;
1136
1137 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1138
1139 if (TRACE_ON(ddraw)) {
1140 TRACE(" Stage type is : ");
1141 switch (d3dTexStageStateType) {
1142#define GEN_CASE(a) case a: DPRINTF(#a " "); break
1143 GEN_CASE(D3DTSS_COLOROP);
1144 GEN_CASE(D3DTSS_COLORARG1);
1145 GEN_CASE(D3DTSS_COLORARG2);
1146 GEN_CASE(D3DTSS_ALPHAOP);
1147 GEN_CASE(D3DTSS_ALPHAARG1);
1148 GEN_CASE(D3DTSS_ALPHAARG2);
1149 GEN_CASE(D3DTSS_BUMPENVMAT00);
1150 GEN_CASE(D3DTSS_BUMPENVMAT01);
1151 GEN_CASE(D3DTSS_BUMPENVMAT10);
1152 GEN_CASE(D3DTSS_BUMPENVMAT11);
1153 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1154 GEN_CASE(D3DTSS_ADDRESS);
1155 GEN_CASE(D3DTSS_ADDRESSU);
1156 GEN_CASE(D3DTSS_ADDRESSV);
1157 GEN_CASE(D3DTSS_BORDERCOLOR);
1158 GEN_CASE(D3DTSS_MAGFILTER);
1159 GEN_CASE(D3DTSS_MINFILTER);
1160 GEN_CASE(D3DTSS_MIPFILTER);
1161 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1162 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1163 GEN_CASE(D3DTSS_MAXANISOTROPY);
1164 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1165 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1166 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1167#undef GEN_CASE
1168 default: DPRINTF("UNKNOWN !!!");
1169 }
1170 DPRINTF(" => ");
1171 }
1172
1173 switch (d3dTexStageStateType) {
1174 case D3DTSS_MINFILTER:
1175 switch ((D3DTEXTUREMINFILTER) dwState) {
1176 case D3DTFN_POINT:
1177 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1178 gl_state = GL_NEAREST;
1179 break;
1180 case D3DTFN_LINEAR:
1181 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1182 gl_state = GL_LINEAR;
1183 break;
1184 default:
1185 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1186 gl_state = GL_LINEAR;
1187 break;
1188 }
1189 glThis->render_state.min = gl_state;
1190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1191 break;
1192
1193 case D3DTSS_MAGFILTER:
1194 switch ((D3DTEXTUREMAGFILTER) dwState) {
1195 case D3DTFG_POINT:
1196 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1197 gl_state = GL_NEAREST;
1198 break;
1199 case D3DTFG_LINEAR:
1200 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1201 gl_state = GL_LINEAR;
1202 break;
1203 default:
1204 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1205 gl_state = GL_LINEAR;
1206 break;
1207 }
1208 glThis->render_state.mag = gl_state;
1209 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1210 break;
1211
1212 default:
1213 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1214 }
1215
1216 return DD_OK;
1217}
1218
1219HRESULT WINAPI
1220GL_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface,
1221 DWORD dwStage,
1222 LPDIRECT3DTEXTURE2 lpTexture2)
1223{
1224 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1225
1226 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1227
1228 if (This->current_texture[dwStage] != NULL) {
1229 /* Seems that this is not right... Need to test in real Windows
1230 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1231 }
1232
1233 ENTER_GL();
1234 if (lpTexture2 == NULL) {
1235 TRACE(" disabling 2D texturing.\n");
1236 glBindTexture(GL_TEXTURE_2D, 0);
1237 glDisable(GL_TEXTURE_2D);
1238 } else {
Lionel Ulmer91c6f812002-12-15 01:17:59 +00001239 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpTexture2);
1240 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001241
1242 This->current_texture[dwStage] = tex_impl;
Lionel Ulmer91c6f812002-12-15 01:17:59 +00001243 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7));
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001244
1245 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1246
1247 glEnable(GL_TEXTURE_2D);
1248 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1249 }
1250 LEAVE_GL();
1251
1252 return DD_OK;
1253}
1254
Lionel Ulmer5261f032002-12-02 21:39:34 +00001255HRESULT WINAPI
1256GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1257 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1258{
1259 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1260 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1261
1262 fill_opengl_caps_7(lpD3DHELDevDesc);
1263
1264 TRACE(" returning caps : no dump function yet.\n");
1265
1266 return DD_OK;
1267}
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001268
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001269#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1270# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1271#else
1272# define XCAST(fun) (void*)
1273#endif
1274
1275ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1276{
1277 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1278 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1279 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1280 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
Lionel Ulmer5261f032002-12-02 21:39:34 +00001281 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001282 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1283 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1284 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1285 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1286 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1287 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1288 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1289 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1290 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1291 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1292 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1293 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1294 XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
1295 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1296 XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
1297 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1298 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1299 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1300 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1301 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1302 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001303 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1304 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001305 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1306 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
1307 XCAST(DrawPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1308 XCAST(DrawIndexedPrimitiveStrided) Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
1309 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawPrimitiveVB,
1310 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
1311 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1312 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
1313 XCAST(SetTexture) Main_IDirect3DDeviceImpl_7_SetTexture,
1314 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001315 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001316 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1317 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1318 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1319 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1320 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1321 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1322 XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
1323 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1324 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1325 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1326 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1327};
1328
1329#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1330#undef XCAST
1331#endif
1332
1333
1334#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1335# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1336#else
1337# define XCAST(fun) (void*)
1338#endif
1339
1340ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1341{
1342 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1343 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1344 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1345 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1346 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1347 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1348 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1349 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1350 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1351 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1352 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1353 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1354 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1355 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1356 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1357 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1358 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1359 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1360 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1361 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1362 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1363 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1364 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1365 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1366 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1367 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1368 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1369 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1370 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1371 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1372 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1373 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1374 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1375 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1376 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
1377 XCAST(DrawPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1378 XCAST(DrawIndexedPrimitiveVB) Main_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
1379 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1380 XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001381 XCAST(SetTexture) GL_IDirect3DDeviceImpl_3_SetTexture,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001382 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1383 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1384 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1385};
1386
1387#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1388#undef XCAST
1389#endif
1390
1391
1392#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1393# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1394#else
1395# define XCAST(fun) (void*)
1396#endif
1397
1398ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1399{
1400 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1401 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1402 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1403 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1404 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1405 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
1406 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1407 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1408 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1409 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1410 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1411 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1412 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1413 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1414 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1415 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1416 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1417 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1418 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1419 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1420 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1421 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1422 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1423 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1424 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1425 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1426 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1427 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1428 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1429 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1430 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1431 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1432 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1433 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1434};
1435
1436#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1437#undef XCAST
1438#endif
1439
1440
1441#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1442# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1443#else
1444# define XCAST(fun) (void*)
1445#endif
1446
1447ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1448{
1449 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1450 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1451 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1452 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1453 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1454 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1455 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
1456 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1457 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1458 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1459 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1460 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1461 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1462 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1463 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1464 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1465 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1466 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1467 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1468 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1469 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1470 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1471 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1472};
1473
1474#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1475#undef XCAST
1476#endif
1477
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001478/* TODO for both these functions :
1479 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1480 by other OpenGL code in D3D
1481 - handle the case where no 'Begin / EndScene' was done between two locks
1482 - handle the rectangles in the unlock too
Lionel Ulmera6e50802002-11-30 19:19:00 +00001483 - handle pitch correctly...
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001484*/
1485static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1486{
1487 /* First, check if we need to do anything */
1488 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1489 GLenum buffer_type;
1490 GLenum prev_read;
1491 RECT loc_rect;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001492
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001493 ENTER_GL();
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001494
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001495 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1496 glFlush();
1497
1498 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1499 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1500 /* Application wants to lock the front buffer */
1501 glReadBuffer(GL_FRONT);
1502 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1503 /* Application wants to lock the back buffer */
1504 glReadBuffer(GL_BACK);
1505 } else {
1506 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1507 }
1508
1509 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1510 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1511 } else {
1512 WARN(" unsupported pixel format.\n");
1513 LEAVE_GL();
1514 return;
1515 }
1516 if (pRect == NULL) {
1517 loc_rect.top = 0;
1518 loc_rect.left = 0;
1519 loc_rect.bottom = This->surface_desc.dwHeight;
1520 loc_rect.right = This->surface_desc.dwWidth;
1521 } else {
1522 loc_rect = *pRect;
1523 }
1524 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1525 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1526 + loc_rect.top * This->surface_desc.u1.lPitch
1527 + loc_rect.left * GET_BPP(This->surface_desc)));
1528 glReadBuffer(prev_read);
1529 LEAVE_GL();
1530 }
1531}
1532
1533static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1534{
1535 /* First, check if we need to do anything */
1536 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1537 GLenum buffer_type;
1538 GLenum prev_draw;
1539
1540 ENTER_GL();
1541
1542 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1543
1544 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1545 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1546 /* Application wants to lock the front buffer */
1547 glDrawBuffer(GL_FRONT);
1548 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1549 /* Application wants to lock the back buffer */
1550 glDrawBuffer(GL_BACK);
1551 } else {
Lionel Ulmer708c4b22002-11-30 19:12:32 +00001552 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001553 }
1554
1555 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1556 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1557 } else {
1558 WARN(" unsupported pixel format.\n");
1559 LEAVE_GL();
1560 return;
1561 }
Lionel Ulmera6e50802002-11-30 19:19:00 +00001562 glRasterPos2f(0.0, 0.0);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001563 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
1564 GL_RGB, buffer_type, This->surface_desc.lpSurface);
1565 glDrawBuffer(prev_draw);
1566
1567 LEAVE_GL();
1568 }
1569}
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001570
1571HRESULT
1572d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
1573{
1574 IDirect3DDeviceImpl *object;
1575 IDirect3DDeviceGLImpl *gl_object;
1576 IDirectDrawSurfaceImpl *surf;
1577 HDC device_context;
1578 XVisualInfo *vis;
1579 int num;
1580 XVisualInfo template;
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001581 GLenum buffer;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001582
1583 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1584 if (object == NULL) return DDERR_OUTOFMEMORY;
1585
1586 gl_object = (IDirect3DDeviceGLImpl *) object;
1587
1588 object->ref = 1;
1589 object->d3d = d3d;
1590 object->surface = surface;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001591 object->set_context = set_context;
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001592
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001593 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1594
1595 device_context = GetDC(surface->ddraw_owner->window);
1596 gl_object->display = get_display(device_context);
1597 gl_object->drawable = get_drawable(device_context);
1598 ReleaseDC(surface->ddraw_owner->window,device_context);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001599
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001600 ENTER_GL();
1601 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1602 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
1603 if (vis == NULL) {
1604 HeapFree(GetProcessHeap(), 0, object);
1605 ERR("No visual found !\n");
1606 LEAVE_GL();
1607 return DDERR_INVALIDPARAMS;
1608 } else {
1609 TRACE(" visual found\n");
1610 }
1611
1612 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
1613 NULL, GL_TRUE);
1614
1615 if (gl_object->gl_context == NULL) {
1616 HeapFree(GetProcessHeap(), 0, object);
1617 ERR("Error in context creation !\n");
1618 LEAVE_GL();
1619 return DDERR_INVALIDPARAMS;
1620 } else {
1621 TRACE(" context created (%p)\n", gl_object->gl_context);
1622 }
1623
1624 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
1625 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
1626 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001627 surf->aux_ctx = (LPVOID) gl_object->display;
1628 surf->aux_data = (LPVOID) gl_object->drawable;
1629 surf->aux_flip = opengl_flip;
1630 buffer = GL_BACK;
Christian Costab47c14a2002-10-17 01:20:52 +00001631 break;
1632 }
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001633 }
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001634 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
1635 if (surf == NULL) {
1636 TRACE(" no double buffering : drawing on the front buffer\n");
1637 buffer = GL_FRONT;
1638 }
1639
1640 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
1641 for (; surf != NULL; surf = surf->next_attached) {
1642 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
1643 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
1644 /* Override the Lock / Unlock function for all these surfaces */
1645 surf->lock_update = d3ddevice_lock_update;
1646 surf->unlock_update = d3ddevice_unlock_update;
1647 }
1648 surf->d3ddevice = object;
1649 }
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001650
1651 gl_object->render_state.src = GL_ONE;
1652 gl_object->render_state.dst = GL_ZERO;
1653 gl_object->render_state.mag = GL_NEAREST;
1654 gl_object->render_state.min = GL_NEAREST;
Lionel Ulmerdfddf922002-12-16 22:39:09 +00001655 gl_object->render_state.alpha_ref = 0.0; /* No actual idea about the real default value... */
1656 gl_object->render_state.alpha_func = GL_ALWAYS; /* Here either but it seems logical */
1657
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001658 /* Allocate memory for the matrices */
1659 gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1660 gl_object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1661 gl_object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1662
1663 memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float));
1664 memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float));
1665 memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float));
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001666
1667 /* Initialisation */
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001668 TRACE(" setting current context\n");
Christian Costa427b3332002-09-27 22:01:12 +00001669 LEAVE_GL();
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001670 object->set_context(object);
Christian Costa427b3332002-09-27 22:01:12 +00001671 ENTER_GL();
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001672 TRACE(" current context set\n");
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001673 glClearColor(0.0, 0.0, 0.0, 0.0);
1674 glColor3f(1.0, 1.0, 1.0);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001675 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1676 glDrawBuffer(buffer);
Lionel Ulmera6e50802002-11-30 19:19:00 +00001677 glReadBuffer(buffer);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001678 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
Christian Costa427b3332002-09-27 22:01:12 +00001679 LEAVE_GL();
Lionel Ulmera8cc5f52000-07-16 14:40:35 +00001680
Christian Costa774c5f72002-11-24 22:14:40 +00001681 /* fill_device_capabilities(d3d->ddraw); */
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001682
1683 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
1684 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
1685 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
1686 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
Vincent Béron9a624912002-05-31 23:06:46 +00001687
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001688 *obj = object;
1689
1690 TRACE(" creating implementation at %p.\n", *obj);
1691
1692 return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001693}