blob: 5a5fc92bf1736a1b5430805af96a3e6b4e4f90f9 [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
Lionel Ulmer8768a6b2002-12-24 00:48:03 +000062static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
63 D3DPRIMITIVETYPE d3dptPrimitiveType,
64 DWORD d3dvtVertexType,
65 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
Lionel Ulmerce3d9682003-01-02 19:46:46 +000066 DWORD dwStartVertex,
Lionel Ulmer8768a6b2002-12-24 00:48:03 +000067 DWORD dwVertexCount,
68 LPWORD dwIndices,
69 DWORD dwIndexCount,
70 DWORD dwFlags) ;
71
Christian Costa427b3332002-09-27 22:01:12 +000072/* retrieve the X display to use on a given DC */
73inline static Display *get_display( HDC hdc )
74{
75 Display *display;
76 enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
77
78 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
79 sizeof(display), (LPSTR)&display )) display = NULL;
80
81 return display;
82}
83
84
85/* retrieve the X drawable to use on a given DC */
86inline static Drawable get_drawable( HDC hdc )
87{
88 Drawable drawable;
89 enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
90
91 if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
92 sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
93
94 return drawable;
95}
96
Christian Costab47c14a2002-10-17 01:20:52 +000097
98static BOOL opengl_flip( LPVOID display, LPVOID drawable)
99{
100 TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
101 ENTER_GL();
102 glXSwapBuffers((Display*)display,(Drawable)drawable);
103 LEAVE_GL();
104 return TRUE;
105}
106
107
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000108/*******************************************************************************
109 * OpenGL static functions
110 */
Christian Costa774c5f72002-11-24 22:14:40 +0000111static void set_context(IDirect3DDeviceImpl* This)
112{
113 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
114
Christian Costa427b3332002-09-27 22:01:12 +0000115 ENTER_GL();
Christian Costa774c5f72002-11-24 22:14:40 +0000116 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context);
117 if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) {
Christian Costa427b3332002-09-27 22:01:12 +0000118 ERR("Error in setting current context (context %p drawable %ld)!\n",
Christian Costa774c5f72002-11-24 22:14:40 +0000119 glThis->gl_context, glThis->drawable);
Christian Costa427b3332002-09-27 22:01:12 +0000120 }
121 LEAVE_GL();
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000122}
123
124static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
125{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000126 pc->dwSize = sizeof(*pc);
127 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
128 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
129 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
Lionel Ulmerc6f5baa2002-12-23 02:03:38 +0000130 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL;
131 pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
132 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
133 pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR |
134 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
135 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
136 pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR |
137 D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT |
138 D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA;
139 pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL |
140 D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL;
141 pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB |
142 D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB;
143 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000144 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
145 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
146 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
Lionel Ulmerc6f5baa2002-12-23 02:03:38 +0000147 pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK |
148 D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK;
149 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000150 pc->dwStippleWidth = 32;
151 pc->dwStippleHeight = 32;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000152}
153
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000154static void fill_opengl_caps(D3DDEVICEDESC *d1)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000155{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000156 /* GLint maxlight; */
Vincent Béron9a624912002-05-31 23:06:46 +0000157
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000158 d1->dwSize = sizeof(*d1);
159 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
160 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
161 d1->dcmColorModel = D3DCOLOR_RGB;
162 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
163 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
Lionel Ulmerc40b7562002-12-24 00:58:27 +0000164 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY |
165 /* D3D 7 capabilities */
166 D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_HWTRANSFORMANDLIGHT | D3DDEVCAPS_HWRASTERIZATION;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000167 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
168 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
169 d1->bClipping = TRUE;
170 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
171 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
172 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
173 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
174 fill_opengl_primcaps(&(d1->dpcLineCaps));
175 fill_opengl_primcaps(&(d1->dpcTriCaps));
Lionel Ulmer5261f032002-12-02 21:39:34 +0000176 d1->dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000177 d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000178 d1->dwMaxBufferSize = 0;
179 d1->dwMaxVertexCount = 65536;
180 d1->dwMinTextureWidth = 1;
181 d1->dwMinTextureHeight = 1;
182 d1->dwMaxTextureWidth = 1024;
183 d1->dwMaxTextureHeight = 1024;
184 d1->dwMinStippleWidth = 1;
185 d1->dwMinStippleHeight = 1;
186 d1->dwMaxStippleWidth = 32;
187 d1->dwMaxStippleHeight = 32;
Lionel Ulmerda0b4dc2002-11-30 01:49:08 +0000188 d1->dwMaxTextureRepeat = 16;
189 d1->dwMaxTextureAspectRatio = 1024;
190 d1->dwMaxAnisotropy = 0;
191 d1->dvGuardBandLeft = 0.0;
192 d1->dvGuardBandRight = 0.0;
193 d1->dvGuardBandTop = 0.0;
194 d1->dvGuardBandBottom = 0.0;
195 d1->dvExtentsAdjust = 0.0;
Lionel Ulmerc40b7562002-12-24 00:58:27 +0000196 d1->dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP |
197 D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO;
Lionel Ulmerda0b4dc2002-11-30 01:49:08 +0000198 d1->dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1;
199 d1->dwTextureOpCaps = 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
200 d1->wMaxTextureBlendStages = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
201 d1->wMaxSimultaneousTextures = 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000202}
203
Lionel Ulmerf4b941e2002-11-30 19:21:42 +0000204static void fill_opengl_caps_7(D3DDEVICEDESC7 *d)
205{
206 D3DDEVICEDESC d1;
207
208 /* Copy first D3D1/2/3 capabilities */
209 fill_opengl_caps(&d1);
210
211 /* And fill the D3D7 one with it */
212 d->dwDevCaps = d1.dwDevCaps;
213 d->dpcLineCaps = d1.dpcLineCaps;
214 d->dpcTriCaps = d1.dpcTriCaps;
215 d->dwDeviceRenderBitDepth = d1.dwDeviceRenderBitDepth;
216 d->dwDeviceZBufferBitDepth = d1.dwDeviceZBufferBitDepth;
217 d->dwMinTextureWidth = d1.dwMinTextureWidth;
218 d->dwMinTextureHeight = d1.dwMinTextureHeight;
219 d->dwMaxTextureWidth = d1.dwMaxTextureWidth;
220 d->dwMaxTextureHeight = d1.dwMaxTextureHeight;
221 d->dwMaxTextureRepeat = d1.dwMaxTextureRepeat;
222 d->dwMaxTextureAspectRatio = d1.dwMaxTextureAspectRatio;
223 d->dwMaxAnisotropy = d1.dwMaxAnisotropy;
224 d->dvGuardBandLeft = d1.dvGuardBandLeft;
225 d->dvGuardBandTop = d1.dvGuardBandTop;
226 d->dvGuardBandRight = d1.dvGuardBandRight;
227 d->dvGuardBandBottom = d1.dvGuardBandBottom;
228 d->dvExtentsAdjust = d1.dvExtentsAdjust;
229 d->dwStencilCaps = d1.dwStencilCaps;
230 d->dwFVFCaps = d1.dwFVFCaps;
231 d->dwTextureOpCaps = d1.dwTextureOpCaps;
232 d->wMaxTextureBlendStages = d1.wMaxTextureBlendStages;
233 d->wMaxSimultaneousTextures = d1.wMaxSimultaneousTextures;
234 d->dwMaxActiveLights = d1.dlcLightingCaps.dwNumLights;
235 d->dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */
236 d->deviceGUID = IID_IDirect3DTnLHalDevice;
237 d->wMaxUserClipPlanes = 1;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000238 d->wMaxVertexBlendMatrices = 0;
Lionel Ulmerf4b941e2002-11-30 19:21:42 +0000239 d->dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | D3DVTXPCAPS_DIRECTIONALLIGHTS |
240 D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER;
241 d->dwReserved1 = 0;
242 d->dwReserved2 = 0;
243 d->dwReserved3 = 0;
244 d->dwReserved4 = 0;
245}
246
Lionel Ulmerda0b4dc2002-11-30 01:49:08 +0000247#if 0 /* TODO : fix this and add multitexturing and other needed stuff */
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000248static void fill_device_capabilities(IDirectDrawImpl* ddraw)
249{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000250 x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
251 const char *ext_string;
252 Mesa_DeviceCapabilities *devcap;
Vincent Béron9a624912002-05-31 23:06:46 +0000253
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000254 private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
255 devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
Vincent Béron9a624912002-05-31 23:06:46 +0000256
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000257 ENTER_GL();
258 ext_string = glGetString(GL_EXTENSIONS);
259 /* Query for the ColorTable Extension */
260 if (strstr(ext_string, "GL_EXT_paletted_texture")) {
261 devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
262 TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
263 } else {
264 TRACE("Color table extension not found.\n");
265 }
266 LEAVE_GL();
Lionel Ulmera8cc5f52000-07-16 14:40:35 +0000267}
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000268#endif
Lionel Ulmera8cc5f52000-07-16 14:40:35 +0000269
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000270
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000271
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000272HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000273{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000274 D3DDEVICEDESC d1, d2;
Christian Costa427b3332002-09-27 22:01:12 +0000275
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000276 fill_opengl_caps(&d1);
277 d2 = d1;
278
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000279 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
280 return cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000281}
282
Lionel Ulmerf4b941e2002-11-30 19:21:42 +0000283HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context)
284{
285 D3DDEVICEDESC7 ddesc;
286
287 fill_opengl_caps_7(&ddesc);
288
289 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
290
291 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc, context);
292}
293
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000294ULONG WINAPI
295GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface)
296{
297 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
298 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
299
300 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
301 if (!--(This->ref)) {
302 /* Release texture associated with the device */
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +0000303 if (This->current_texture[0] != NULL)
304 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2));
Lionel Ulmeree65d592002-12-16 22:57:39 +0000305
Lionel Ulmer8cd26092003-01-02 19:39:57 +0000306 /* And warn the D3D object that this device is no longer active... */
307 This->d3d->removed_device(This->d3d, This);
308
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000309 ENTER_GL();
310 glXDestroyContext(glThis->display, glThis->gl_context);
311 LEAVE_GL();
312
313 HeapFree(GetProcessHeap(), 0, This);
314 return 0;
315 }
316 return This->ref;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000317}
318
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000319HRESULT WINAPI
320GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface,
321 LPD3DDEVICEDESC lpD3DHWDevDesc,
322 LPD3DDEVICEDESC lpD3DHELDevDesc)
323{
324 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
325 D3DDEVICEDESC desc;
326 DWORD dwSize;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000327
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000328 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc);
Vincent Béron9a624912002-05-31 23:06:46 +0000329
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000330 fill_opengl_caps(&desc);
331 dwSize = lpD3DHWDevDesc->dwSize;
332 memset(lpD3DHWDevDesc, 0, dwSize);
333 memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
334
335 dwSize = lpD3DHELDevDesc->dwSize;
336 memset(lpD3DHELDevDesc, 0, dwSize);
337 memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize));
338
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000339 TRACE(" returning caps : (no dump function yet)\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000340
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000341 return DD_OK;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000342}
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000343
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000344static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
345 LPD3DENUMPIXELFORMATSCALLBACK cb_2,
346 LPVOID context)
347{
348 DDSURFACEDESC sdesc;
349 LPDDPIXELFORMAT pformat;
350
351 /* Do the texture enumeration */
352 sdesc.dwSize = sizeof(DDSURFACEDESC);
353 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
354 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
355 pformat = &(sdesc.ddpfPixelFormat);
356 pformat->dwSize = sizeof(DDPIXELFORMAT);
357 pformat->dwFourCC = 0;
358
359 TRACE("Enumerating GL_RGBA unpacked (32)\n");
360 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
361 pformat->u1.dwRGBBitCount = 32;
362 pformat->u2.dwRBitMask = 0xFF000000;
363 pformat->u3.dwGBitMask = 0x00FF0000;
364 pformat->u4.dwBBitMask = 0x0000FF00;
365 pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
366 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
367 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
368
369 TRACE("Enumerating GL_RGB unpacked (24)\n");
370 pformat->dwFlags = DDPF_RGB;
371 pformat->u1.dwRGBBitCount = 24;
372 pformat->u2.dwRBitMask = 0x00FF0000;
373 pformat->u3.dwGBitMask = 0x0000FF00;
374 pformat->u4.dwBBitMask = 0x000000FF;
375 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
376 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
377 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000378
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000379 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
380 pformat->dwFlags = DDPF_RGB;
381 pformat->u1.dwRGBBitCount = 16;
382 pformat->u2.dwRBitMask = 0x0000F800;
383 pformat->u3.dwGBitMask = 0x000007E0;
384 pformat->u4.dwBBitMask = 0x0000001F;
385 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
386 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
387 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000388
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000389 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
390 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
391 pformat->u1.dwRGBBitCount = 16;
Lionel Ulmera62fc662002-12-17 04:14:55 +0000392 pformat->u2.dwRBitMask = 0x0000F800;
393 pformat->u3.dwGBitMask = 0x000007C0;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000394 pformat->u4.dwBBitMask = 0x0000003E;
395 pformat->u5.dwRGBAlphaBitMask = 0x00000001;
396 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
397 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000398
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000399 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
400 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
401 pformat->u1.dwRGBBitCount = 16;
Lionel Ulmera62fc662002-12-17 04:14:55 +0000402 pformat->u2.dwRBitMask = 0x0000F000;
403 pformat->u3.dwGBitMask = 0x00000F00;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000404 pformat->u4.dwBBitMask = 0x000000F0;
405 pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
406 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
407 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000408
Lionel Ulmera62fc662002-12-17 04:14:55 +0000409 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (16)\n");
410 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
411 pformat->u1.dwRGBBitCount = 16;
412 pformat->u2.dwRBitMask = 0x00007C00;
413 pformat->u3.dwGBitMask = 0x000003E0;
414 pformat->u4.dwBBitMask = 0x0000001F;
415 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
416 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
417 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
418
419 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
420 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
421 pformat->u1.dwRGBBitCount = 16;
422 pformat->u2.dwRBitMask = 0x00000F00;
423 pformat->u3.dwGBitMask = 0x000000F0;
424 pformat->u4.dwBBitMask = 0x0000000F;
425 pformat->u5.dwRGBAlphaBitMask = 0x0000F000;
426 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
427 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
428
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000429 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
430 pformat->dwFlags = DDPF_RGB;
431 pformat->u1.dwRGBBitCount = 8;
432 pformat->u2.dwRBitMask = 0x000000E0;
433 pformat->u3.dwGBitMask = 0x0000001C;
434 pformat->u4.dwBBitMask = 0x00000003;
435 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
436 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
437 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000438
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000439 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
440 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
441 pformat->u1.dwRGBBitCount = 16;
442 pformat->u2.dwRBitMask = 0x00007C00;
443 pformat->u3.dwGBitMask = 0x000003E0;
444 pformat->u4.dwBBitMask = 0x0000001F;
445 pformat->u5.dwRGBAlphaBitMask = 0x00008000;
446 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
447 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
448
449 TRACE("Enumerating Paletted (8)\n");
450 pformat->dwFlags = DDPF_PALETTEINDEXED8;
451 pformat->u1.dwRGBBitCount = 8;
452 pformat->u2.dwRBitMask = 0x00000000;
453 pformat->u3.dwGBitMask = 0x00000000;
454 pformat->u4.dwBBitMask = 0x00000000;
455 pformat->u5.dwRGBAlphaBitMask = 0x00000000;
456 if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
457 if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
458
459 TRACE("End of enumeration\n");
Vincent Béron9a624912002-05-31 23:06:46 +0000460 return DD_OK;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000461}
Vincent Béron9a624912002-05-31 23:06:46 +0000462
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000463
464HRESULT
465d3ddevice_find(IDirect3DImpl *d3d,
466 LPD3DFINDDEVICESEARCH lpD3DDFS,
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000467 LPD3DFINDDEVICERESULT lplpD3DDevice)
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000468{
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000469 D3DDEVICEDESC desc;
470
471 if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) &&
472 (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) {
473 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
474 return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */
475 }
476 if (lpD3DDFS->dwFlags & D3DFDS_GUID) {
477 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid)));
478 if ((IsEqualGUID( &IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) &&
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000479 (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0)) {
480 TRACE(" no match for this GUID.\n");
481 return DDERR_INVALIDPARAMS;
482 }
483 }
484
Lionel Ulmerb0350a32002-12-05 19:07:59 +0000485 /* Now return our own GUID */
486 lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL;
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000487 fill_opengl_caps(&desc);
Lionel Ulmerc6f5baa2002-12-23 02:03:38 +0000488 lplpD3DDevice->ddHwDesc = desc;
489 lplpD3DDevice->ddSwDesc = desc;
490
491 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
Lionel Ulmer710b86e2002-11-24 22:33:41 +0000492
493 return D3D_OK;
494}
495
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000496HRESULT WINAPI
497GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
498 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc,
499 LPVOID lpArg)
500{
501 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
502 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
503 return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
504}
505
506HRESULT WINAPI
507GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface,
508 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc,
509 LPVOID lpArg)
510{
511 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
512 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
513 return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
514}
515
516HRESULT WINAPI
517GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface,
518 D3DRENDERSTATETYPE dwRenderStateType,
519 DWORD dwRenderState)
520{
521 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
522 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
523 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState);
524
525 /* Call the render state functions */
526 set_render_state(dwRenderStateType, dwRenderState, &(glThis->render_state));
527
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000528 return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000529}
530
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000531HRESULT WINAPI
532GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface,
533 D3DLIGHTSTATETYPE dwLightStateType,
534 DWORD dwLightState)
535{
536 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
537 TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState);
Vincent Béron9a624912002-05-31 23:06:46 +0000538
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000539 switch (dwLightStateType) {
540 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
541 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000542
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000543 if (mat != NULL) {
544 ENTER_GL();
545 mat->activate(mat);
546 LEAVE_GL();
547 } else {
548 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
549 }
550 } break;
Vincent Béron9a624912002-05-31 23:06:46 +0000551
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000552 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
553 float light[4];
Vincent Béron9a624912002-05-31 23:06:46 +0000554
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000555 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
556 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
557 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
558 light[3] = 1.0;
559 ENTER_GL();
560 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
561 LEAVE_GL();
562 } break;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000563
564#define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000565 UNSUP(COLORMODEL);
566 UNSUP(FOGMODE);
567 UNSUP(FOGSTART);
568 UNSUP(FOGEND);
569 UNSUP(FOGDENSITY);
Christian Costa2db04152002-12-02 21:11:47 +0000570 UNSUP(COLORVERTEX);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000571#undef UNSUP
Vincent Béron9a624912002-05-31 23:06:46 +0000572
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000573 default:
574 TRACE("Unexpected Light State Type\n");
575 return DDERR_INVALIDPARAMS;
576 }
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000577
Marcus Meissner3873f442000-04-10 13:45:17 +0000578 return DD_OK;
579}
580
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000581HRESULT WINAPI
582GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface,
583 D3DTRANSFORMSTATETYPE dtstTransformStateType,
584 LPD3DMATRIX lpD3DMatrix)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000585{
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000586 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
587 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
Vincent Béron9a624912002-05-31 23:06:46 +0000588
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000589 TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix);
Vincent Béron9a624912002-05-31 23:06:46 +0000590
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000591 ENTER_GL();
Vincent Béron9a624912002-05-31 23:06:46 +0000592
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000593 /* Using a trial and failure approach, I found that the order of
594 Direct3D transformations that works best is :
Vincent Béron9a624912002-05-31 23:06:46 +0000595
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000596 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
Vincent Béron9a624912002-05-31 23:06:46 +0000597
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000598 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
599 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
Vincent Béron9a624912002-05-31 23:06:46 +0000600
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000601 If anyone has a good explanation of the three different matrices in
602 the SDK online documentation, feel free to point it to me. For example,
603 which matrices transform lights ? In OpenGL only the PROJECTION matrix
604 transform the lights, not the MODELVIEW. Using the matrix names, I
605 supposed that PROJECTION and VIEW (all 'camera' related names) do
606 transform lights, but WORLD do not. It may be wrong though... */
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000607
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000608 /* After reading through both OpenGL and Direct3D documentations, I
609 thought that D3D matrices were written in 'line major mode' transposed
610 from OpenGL's 'column major mode'. But I found out that a simple memcpy
611 works fine to transfer one matrix format to the other (it did not work
612 when transposing)....
Vincent Béron9a624912002-05-31 23:06:46 +0000613
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000614 So :
615 1) are the documentations wrong
616 2) does the matrix work even if they are not read correctly
617 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
618 loading using glLoadMatrix ?
Vincent Béron9a624912002-05-31 23:06:46 +0000619
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000620 Anyway, I always use 'conv_mat' to transfer the matrices from one format
621 to the other so that if I ever find out that I need to transpose them, I
622 will able to do it quickly, only by changing the macro conv_mat. */
Vincent Béron9a624912002-05-31 23:06:46 +0000623
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000624 switch (dtstTransformStateType) {
625 case D3DTRANSFORMSTATE_WORLD: {
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000626 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000627 conv_mat(lpD3DMatrix, glThis->world_mat);
628 glMatrixMode(GL_MODELVIEW);
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000629 glLoadMatrixf((float *) glThis->view_mat);
630 glMultMatrixf((float *) glThis->world_mat);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000631 } break;
632
633 case D3DTRANSFORMSTATE_VIEW: {
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000634 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000635 conv_mat(lpD3DMatrix, glThis->view_mat);
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000636 glMatrixMode(GL_MODELVIEW);
637 glLoadMatrixf((float *) glThis->view_mat);
638 glMultMatrixf((float *) glThis->world_mat);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000639 } break;
640
641 case D3DTRANSFORMSTATE_PROJECTION: {
Lionel Ulmer708c4b22002-11-30 19:12:32 +0000642 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000643 conv_mat(lpD3DMatrix, glThis->proj_mat);
644 glMatrixMode(GL_PROJECTION);
645 glLoadMatrixf((float *) glThis->proj_mat);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000646 } break;
647
648 default:
Lionel Ulmer74c3eab2002-12-24 01:07:21 +0000649 ERR("Unknown transform type %08x !!!\n", dtstTransformStateType);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000650 break;
651 }
652 LEAVE_GL();
653
Lionel Ulmer74c3eab2002-12-24 01:07:21 +0000654 /* And set the 'matrix changed' flag */
655 glThis->matrices_changed = TRUE;
656
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000657 return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000658}
659
Lionel Ulmera6e50802002-11-30 19:19:00 +0000660static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000661{
662 switch (d3dpt) {
663 case D3DPT_POINTLIST:
664 TRACE("Start POINTS\n");
665 glBegin(GL_POINTS);
666 break;
667
668 case D3DPT_LINELIST:
669 TRACE("Start LINES\n");
670 glBegin(GL_LINES);
671 break;
672
673 case D3DPT_LINESTRIP:
674 TRACE("Start LINE_STRIP\n");
675 glBegin(GL_LINE_STRIP);
676 break;
677
678 case D3DPT_TRIANGLELIST:
679 TRACE("Start TRIANGLES\n");
680 glBegin(GL_TRIANGLES);
681 break;
682
683 case D3DPT_TRIANGLESTRIP:
684 TRACE("Start TRIANGLE_STRIP\n");
685 glBegin(GL_TRIANGLE_STRIP);
686 break;
687
688 case D3DPT_TRIANGLEFAN:
689 TRACE("Start TRIANGLE_FAN\n");
690 glBegin(GL_TRIANGLE_FAN);
691 break;
692
693 default:
694 TRACE("Unhandled primitive\n");
695 break;
696 }
697}
698
Lionel Ulmera6e50802002-11-30 19:19:00 +0000699static void draw_primitive_handle_GL_state(IDirect3DDeviceGLImpl *glThis,
700 BOOLEAN vertex_transformed,
701 BOOLEAN vertex_lit) {
702 /* Puts GL in the correct lighting / transformation mode */
Lionel Ulmer74c3eab2002-12-24 01:07:21 +0000703 if ((vertex_transformed == FALSE) &&
704 ((glThis->last_vertices_transformed == TRUE) ||
705 (glThis->matrices_changed == TRUE))) {
Lionel Ulmera6e50802002-11-30 19:19:00 +0000706 /* Need to put the correct transformation again if we go from Transformed
707 vertices to non-transformed ones.
708 */
709 glMatrixMode(GL_MODELVIEW);
710 glLoadMatrixf((float *) glThis->view_mat);
711 glMultMatrixf((float *) glThis->world_mat);
712 glMatrixMode(GL_PROJECTION);
713 glLoadMatrixf((float *) glThis->proj_mat);
Lionel Ulmerc3d89f52003-01-02 19:45:23 +0000714
715 if (glThis->render_state.fog_on == TRUE) glEnable(GL_FOG);
Lionel Ulmer74c3eab2002-12-24 01:07:21 +0000716 } else if ((vertex_transformed == TRUE) &&
717 ((glThis->last_vertices_transformed == FALSE) ||
718 (glThis->matrices_changed == TRUE))) {
719 GLfloat height, width;
720 GLfloat trans_mat[16];
721
722 width = glThis->parent.surface->surface_desc.dwWidth;
723 height = glThis->parent.surface->surface_desc.dwHeight;
724
725 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
726 to OpenGL screen coordinates (ie the upper left corner is not the same).
727 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
728 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
729 trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
730 trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
731 trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0;
732 trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
733
Lionel Ulmera6e50802002-11-30 19:19:00 +0000734 glMatrixMode(GL_MODELVIEW);
735 glLoadIdentity();
736 glMatrixMode(GL_PROJECTION);
Lionel Ulmer74c3eab2002-12-24 01:07:21 +0000737 glLoadMatrixf(trans_mat);
Lionel Ulmerc3d89f52003-01-02 19:45:23 +0000738
739 /* Remove also fogging... */
740 glDisable(GL_FOG);
Lionel Ulmera6e50802002-11-30 19:19:00 +0000741 }
Lionel Ulmer74c3eab2002-12-24 01:07:21 +0000742 glThis->matrices_changed = FALSE;
Lionel Ulmera6e50802002-11-30 19:19:00 +0000743
744 if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) {
745 glEnable(GL_LIGHTING);
746 } else if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == TRUE)) {
747 glDisable(GL_LIGHTING);
748 }
749
750 /* And save the current state */
751 glThis->last_vertices_transformed = vertex_transformed;
752 glThis->last_vertices_lit = vertex_lit;
753}
754
755
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000756inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000757 D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000758{
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000759 D3DDRAWPRIMITIVESTRIDEDDATA strided;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000760
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000761 switch (d3dvt) {
762 case D3DVT_VERTEX: {
763 strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x;
764 strided.position.dwStride = sizeof(D3DVERTEX);
765 strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx;
766 strided.normal.dwStride = sizeof(D3DVERTEX);
767 strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu;
768 strided.textureCoords[0].dwStride = sizeof(D3DVERTEX);
Lionel Ulmerce3d9682003-01-02 19:46:46 +0000769 draw_primitive_strided_7(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000770 } break;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000771
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000772 case D3DVT_LVERTEX: {
773 strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x;
774 strided.position.dwStride = sizeof(D3DLVERTEX);
775 strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color;
776 strided.diffuse.dwStride = sizeof(D3DLVERTEX);
777 strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular;
778 strided.specular.dwStride = sizeof(D3DLVERTEX);
779 strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu;
780 strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX);
Lionel Ulmerce3d9682003-01-02 19:46:46 +0000781 draw_primitive_strided_7(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000782 } break;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000783
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000784 case D3DVT_TLVERTEX: {
785 strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx;
786 strided.position.dwStride = sizeof(D3DTLVERTEX);
787 strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color;
788 strided.diffuse.dwStride = sizeof(D3DTLVERTEX);
789 strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular;
790 strided.specular.dwStride = sizeof(D3DTLVERTEX);
791 strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu;
792 strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX);
Lionel Ulmerce3d9682003-01-02 19:46:46 +0000793 draw_primitive_strided_7(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */);
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000794 } break;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000795
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000796 default:
797 FIXME("Unhandled vertex type\n");
798 break;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000799 }
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000800}
801
802HRESULT WINAPI
803GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
804 D3DPRIMITIVETYPE d3dptPrimitiveType,
805 D3DVERTEXTYPE d3dvtVertexType,
806 LPVOID lpvVertices,
807 DWORD dwVertexCount,
808 DWORD dwFlags)
809{
810 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
811 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
812
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000813 ENTER_GL();
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000814 draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000815 LEAVE_GL();
816
817 return DD_OK;
818}
Christian Costab47c14a2002-10-17 01:20:52 +0000819
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000820HRESULT WINAPI
821GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
822 D3DPRIMITIVETYPE d3dptPrimitiveType,
823 D3DVERTEXTYPE d3dvtVertexType,
824 LPVOID lpvVertices,
825 DWORD dwVertexCount,
826 LPWORD dwIndices,
827 DWORD dwIndexCount,
828 DWORD dwFlags)
829{
830 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
831 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
832
833 ENTER_GL();
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000834 draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +0000835 LEAVE_GL();
836
837 return DD_OK;
838}
839
840HRESULT WINAPI
841GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
842 LPD3DEXECUTEBUFFERDESC lpDesc,
843 LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer,
844 IUnknown* pUnkOuter)
845{
846 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
847 IDirect3DExecuteBufferImpl *ret;
848 HRESULT ret_value;
849
850 TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
851
852 ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc);
853 *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer);
854
855 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer);
856
857 return ret_value;
858}
859
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000860DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000861{
862 DWORD size = 0;
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000863 DWORD elts = 0;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000864
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000865 if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
866 if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
867 if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000868 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000869 case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
870 case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000871 default: TRACE(" matrix weighting not handled yet...\n");
872 }
873 size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000874 elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
875
876 if (elements) *elements = elts;
Lionel Ulmerc5f38752002-11-30 19:27:19 +0000877
878 return size;
879}
880
881void dump_flexible_vertex(DWORD d3dvtVertexType)
Lionel Ulmer5f49e782002-11-30 19:06:52 +0000882{
883 static const flag_info flags[] = {
884 FE(D3DFVF_NORMAL),
885 FE(D3DFVF_RESERVED1),
886 FE(D3DFVF_DIFFUSE),
887 FE(D3DFVF_SPECULAR)
888 };
889 if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 ");
890 switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
891#define GEN_CASE(a) case a: DPRINTF(#a " "); break
892 GEN_CASE(D3DFVF_XYZ);
893 GEN_CASE(D3DFVF_XYZRHW);
894 GEN_CASE(D3DFVF_XYZB1);
895 GEN_CASE(D3DFVF_XYZB2);
896 GEN_CASE(D3DFVF_XYZB3);
897 GEN_CASE(D3DFVF_XYZB4);
898 GEN_CASE(D3DFVF_XYZB5);
899 }
900 DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE);
901 switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) {
902 GEN_CASE(D3DFVF_TEX0);
903 GEN_CASE(D3DFVF_TEX1);
904 GEN_CASE(D3DFVF_TEX2);
905 GEN_CASE(D3DFVF_TEX3);
906 GEN_CASE(D3DFVF_TEX4);
907 GEN_CASE(D3DFVF_TEX5);
908 GEN_CASE(D3DFVF_TEX6);
909 GEN_CASE(D3DFVF_TEX7);
910 GEN_CASE(D3DFVF_TEX8);
911 }
912#undef GEN_CASE
913 DPRINTF("\n");
914}
915
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000916/* These are the various handler used in the generic path */
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000917inline static void handle_xyz(D3DVALUE *coords) {
Christian Costa3da729e2002-12-24 00:25:39 +0000918 glVertex3fv(coords);
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000919}
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000920inline static void handle_xyzrhw(D3DVALUE *coords) {
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000921 if (coords[3] < 0.00001)
Lionel Ulmer74c3eab2002-12-24 01:07:21 +0000922 glVertex3fv(coords);
923 else {
924 GLfloat w = 1.0 / coords[3];
925
926 glVertex4f(coords[0] * w,
927 coords[1] * w,
928 coords[2] * w,
929 w);
930 }
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000931}
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000932inline static void handle_normal(D3DVALUE *coords) {
Christian Costa3da729e2002-12-24 00:25:39 +0000933 glNormal3fv(coords);
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000934}
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000935inline static void handle_specular(DWORD *color) {
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000936 /* Specular not handled yet properly... */
937}
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000938inline static void handle_diffuse(DWORD *color) {
939 glColor4ub((*color >> 16) & 0xFF,
940 (*color >> 8) & 0xFF,
941 (*color >> 0) & 0xFF,
942 (*color >> 24) & 0xFF);
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000943}
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000944inline static void handle_diffuse_and_specular(DWORD *color_d, DWORD *color_s) {
Lionel Ulmerc3d89f52003-01-02 19:45:23 +0000945 handle_diffuse(color_d);
946}
947inline static void handle_diffuse_no_alpha(DWORD *color) {
948 glColor3ub((*color >> 16) & 0xFF,
949 (*color >> 8) & 0xFF,
950 (*color >> 0) & 0xFF);
951}
952inline static void handle_diffuse_and_specular_no_alpha(DWORD *color_d, DWORD *color_s) {
953 handle_diffuse_no_alpha(color_d);
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000954}
955inline static void handle_texture(D3DVALUE *coords) {
956 glTexCoord2fv(coords);
957}
Lionel Ulmer5f785682002-12-24 01:00:45 +0000958inline static void handle_textures(D3DVALUE *coords, int tex_index) {
959 /* For the moment, draw only the first texture.. */
960 if (tex_index == 0) glTexCoord2fv(coords);
Lionel Ulmer91c6f812002-12-15 01:17:59 +0000961}
962
Christian Costa47b6b942002-12-16 23:07:41 +0000963static void draw_primitive_strided_7(IDirect3DDeviceImpl *This,
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000964 D3DPRIMITIVETYPE d3dptPrimitiveType,
965 DWORD d3dvtVertexType,
966 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
Lionel Ulmerce3d9682003-01-02 19:46:46 +0000967 DWORD dwStartVertex,
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000968 DWORD dwVertexCount,
969 LPWORD dwIndices,
970 DWORD dwIndexCount,
971 DWORD dwFlags)
Christian Costa47b6b942002-12-16 23:07:41 +0000972{
973 IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
974 if (TRACE_ON(ddraw)) {
975 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
976 }
977
978 ENTER_GL();
979 draw_primitive_handle_GL_state(glThis,
980 (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
981 (d3dvtVertexType & D3DFVF_NORMAL) == 0);
982 draw_primitive_start_GL(d3dptPrimitiveType);
983
984 /* Some fast paths first before the generic case.... */
985 if (d3dvtVertexType == D3DFVF_VERTEX) {
986 int index;
987
988 for (index = 0; index < dwIndexCount; index++) {
989 int i = (dwIndices == NULL) ? index : dwIndices[index];
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000990 D3DVALUE *normal =
991 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
992 D3DVALUE *tex_coord =
993 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
994 D3DVALUE *position =
995 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
Christian Costa47b6b942002-12-16 23:07:41 +0000996
Lionel Ulmer8768a6b2002-12-24 00:48:03 +0000997 handle_normal(normal);
998 handle_texture(tex_coord);
999 handle_xyz(position);
1000
Christian Costa3da729e2002-12-24 00:25:39 +00001001 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001002 position[0], position[1], position[2],
1003 normal[0], normal[1], normal[2],
1004 tex_coord[0], tex_coord[1]);
Christian Costa47b6b942002-12-16 23:07:41 +00001005 }
Christian Costa3da729e2002-12-24 00:25:39 +00001006 } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
Christian Costa47b6b942002-12-16 23:07:41 +00001007 int index;
1008
1009 for (index = 0; index < dwIndexCount; index++) {
1010 int i = (dwIndices == NULL) ? index : dwIndices[index];
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001011 DWORD *color_d =
1012 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1013 DWORD *color_s =
1014 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1015 D3DVALUE *tex_coord =
1016 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1017 D3DVALUE *position =
1018 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
Christian Costa3da729e2002-12-24 00:25:39 +00001019
Lionel Ulmerc3d89f52003-01-02 19:45:23 +00001020 if (glThis->render_state.alpha_blend_enable == TRUE)
1021 handle_diffuse_and_specular(color_d, color_s);
1022 else
1023 handle_diffuse_and_specular_no_alpha(color_d, color_s);
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001024 handle_texture(tex_coord);
1025 handle_xyzrhw(position);
1026
Christian Costa3da729e2002-12-24 00:25:39 +00001027 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001028 position[0], position[1], position[2], position[3],
1029 (*color_d >> 16) & 0xFF,
1030 (*color_d >> 8) & 0xFF,
1031 (*color_d >> 0) & 0xFF,
1032 (*color_d >> 24) & 0xFF,
1033 (*color_s >> 16) & 0xFF,
1034 (*color_s >> 8) & 0xFF,
1035 (*color_s >> 0) & 0xFF,
1036 (*color_s >> 24) & 0xFF,
1037 tex_coord[0], tex_coord[1]);
Christian Costa47b6b942002-12-16 23:07:41 +00001038 }
Christian Costa3da729e2002-12-24 00:25:39 +00001039 } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
1040 ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
1041 /* This is the 'slow path' but that should support all possible vertex formats out there...
1042 Note that people should write a fast path for all vertex formats out there...
1043 */
1044 int index;
1045 for (index = 0; index < dwIndexCount; index++) {
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001046 int i = (dwIndices == NULL) ? index : dwIndices[index];
1047
Christian Costa3da729e2002-12-24 00:25:39 +00001048 if (d3dvtVertexType & D3DFVF_NORMAL) {
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001049 D3DVALUE *normal =
1050 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1051 handle_normal(normal);
Christian Costa3da729e2002-12-24 00:25:39 +00001052 }
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001053 if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) {
1054 DWORD *color_d =
1055 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1056 DWORD *color_s =
1057 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
Lionel Ulmerc3d89f52003-01-02 19:45:23 +00001058 if (glThis->render_state.alpha_blend_enable == TRUE)
1059 handle_diffuse_and_specular(color_d, color_s);
1060 else
1061 handle_diffuse_and_specular_no_alpha(color_d, color_s);
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001062 } else {
1063 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1064 DWORD *color_s =
1065 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1066 handle_specular(color_s);
1067 } else if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1068 DWORD *color_d =
1069 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
Lionel Ulmerc3d89f52003-01-02 19:45:23 +00001070 if (glThis->render_state.alpha_blend_enable == TRUE)
1071 handle_diffuse(color_d);
1072 else
1073 handle_diffuse_no_alpha(color_d);
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001074 }
Christian Costa3da729e2002-12-24 00:25:39 +00001075 }
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001076
Christian Costa3da729e2002-12-24 00:25:39 +00001077 if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) {
1078 /* Special case for single texture... */
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001079 D3DVALUE *tex_coord =
1080 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride);
1081 handle_texture(tex_coord);
Christian Costa3da729e2002-12-24 00:25:39 +00001082 } else {
1083 int tex_index;
1084 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001085 D3DVALUE *tex_coord =
1086 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1087 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1088 handle_textures(tex_coord, tex_index);
Christian Costa3da729e2002-12-24 00:25:39 +00001089 }
1090 }
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001091 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1092 D3DVALUE *position =
1093 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1094 handle_xyz(position);
1095 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1096 D3DVALUE *position =
1097 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1098 handle_xyzrhw(position);
1099 }
Lionel Ulmer5f785682002-12-24 01:00:45 +00001100
1101 if (TRACE_ON(ddraw)) {
1102 int tex_index;
1103
1104 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1105 D3DVALUE *position =
1106 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1107 TRACE(" %f %f %f", position[0], position[1], position[2]);
1108 } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
1109 D3DVALUE *position =
1110 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride);
1111 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
1112 }
1113 if (d3dvtVertexType & D3DFVF_NORMAL) {
1114 D3DVALUE *normal =
1115 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride);
1116 DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]);
1117 }
1118 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
1119 DWORD *color_d =
1120 (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride);
1121 DPRINTF(" / %02lx %02lx %02lx %02lx",
1122 (*color_d >> 16) & 0xFF,
1123 (*color_d >> 8) & 0xFF,
1124 (*color_d >> 0) & 0xFF,
1125 (*color_d >> 24) & 0xFF);
1126 }
1127 if (d3dvtVertexType & D3DFVF_SPECULAR) {
1128 DWORD *color_s =
1129 (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride);
1130 DPRINTF(" / %02lx %02lx %02lx %02lx",
1131 (*color_s >> 16) & 0xFF,
1132 (*color_s >> 8) & 0xFF,
1133 (*color_s >> 0) & 0xFF,
1134 (*color_s >> 24) & 0xFF);
1135 }
1136 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
1137 D3DVALUE *tex_coord =
1138 (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) +
1139 i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride);
1140 DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]);
1141 }
1142 DPRINTF("\n");
1143 }
Christian Costa3da729e2002-12-24 00:25:39 +00001144 }
1145 } else {
1146 ERR(" matrix weighting not handled yet....\n");
Christian Costa47b6b942002-12-16 23:07:41 +00001147 }
1148
1149 glEnd();
1150 LEAVE_GL();
1151 TRACE("End\n");
1152}
1153
Christian Costa3da729e2002-12-24 00:25:39 +00001154static void draw_primitive_7(IDirect3DDeviceImpl *This,
1155 D3DPRIMITIVETYPE d3dptPrimitiveType,
1156 DWORD d3dvtVertexType,
1157 LPVOID lpvVertices,
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001158 DWORD dwStartVertex,
Christian Costa3da729e2002-12-24 00:25:39 +00001159 DWORD dwVertexCount,
1160 LPWORD dwIndices,
1161 DWORD dwIndexCount,
1162 DWORD dwFlags)
1163{
1164 D3DDRAWPRIMITIVESTRIDEDDATA strided;
1165 int current_offset = 0;
1166 int tex_index;
1167
1168 if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
1169 strided.position.lpvData = lpvVertices;
1170 current_offset += 3 * sizeof(D3DVALUE);
1171 } else {
1172 strided.position.lpvData = lpvVertices;
1173 current_offset += 4 * sizeof(D3DVALUE);
1174 }
1175 if (d3dvtVertexType & D3DFVF_NORMAL) {
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001176 strided.normal.lpvData = ((char *) lpvVertices) + current_offset;
Christian Costa3da729e2002-12-24 00:25:39 +00001177 current_offset += 3 * sizeof(D3DVALUE);
1178 }
1179 if (d3dvtVertexType & D3DFVF_DIFFUSE) {
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001180 strided.diffuse.lpvData = ((char *) lpvVertices) + current_offset;
Christian Costa3da729e2002-12-24 00:25:39 +00001181 current_offset += sizeof(DWORD);
1182 }
1183 if (d3dvtVertexType & D3DFVF_SPECULAR) {
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001184 strided.specular.lpvData = ((char *) lpvVertices) + current_offset;
Christian Costa3da729e2002-12-24 00:25:39 +00001185 current_offset += sizeof(DWORD);
1186 }
1187 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
Lionel Ulmer8768a6b2002-12-24 00:48:03 +00001188 strided.textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset;
Lionel Ulmer74c3eab2002-12-24 01:07:21 +00001189 current_offset += 2 * sizeof(D3DVALUE);
Christian Costa3da729e2002-12-24 00:25:39 +00001190 }
1191 strided.position.dwStride = current_offset;
1192 strided.normal.dwStride = current_offset;
1193 strided.diffuse.dwStride = current_offset;
1194 strided.specular.dwStride = current_offset;
1195 for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++)
1196 strided.textureCoords[tex_index].dwStride = current_offset;
1197
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001198 draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwStartVertex, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
Christian Costa3da729e2002-12-24 00:25:39 +00001199}
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001200
1201HRESULT WINAPI
1202GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface,
1203 D3DPRIMITIVETYPE d3dptPrimitiveType,
1204 DWORD d3dvtVertexType,
1205 LPVOID lpvVertices,
1206 DWORD dwVertexCount,
1207 DWORD dwFlags)
1208{
1209 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1210 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags);
1211
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001212 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001213
1214 return DD_OK;
1215}
1216
1217HRESULT WINAPI
1218GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface,
1219 D3DPRIMITIVETYPE d3dptPrimitiveType,
1220 DWORD d3dvtVertexType,
1221 LPVOID lpvVertices,
1222 DWORD dwVertexCount,
1223 LPWORD dwIndices,
1224 DWORD dwIndexCount,
1225 DWORD dwFlags)
1226{
1227 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1228 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
1229
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001230 draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001231
1232 return DD_OK;
1233}
1234
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001235HRESULT WINAPI
Christian Costa47b6b942002-12-16 23:07:41 +00001236GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1237 D3DPRIMITIVETYPE d3dptPrimitiveType,
1238 DWORD dwVertexType,
1239 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1240 DWORD dwVertexCount,
1241 DWORD dwFlags)
1242{
1243 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1244 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags);
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001245 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags);
Christian Costa47b6b942002-12-16 23:07:41 +00001246 return DD_OK;
1247}
1248
1249HRESULT WINAPI
1250GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface,
1251 D3DPRIMITIVETYPE d3dptPrimitiveType,
1252 DWORD dwVertexType,
1253 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,
1254 DWORD dwVertexCount,
1255 LPWORD lpIndex,
1256 DWORD dwIndexCount,
1257 DWORD dwFlags)
1258{
1259 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1260 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001261 draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags);
1262 return DD_OK;
1263}
1264
1265HRESULT WINAPI
1266GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1267 D3DPRIMITIVETYPE d3dptPrimitiveType,
1268 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1269 DWORD dwStartVertex,
1270 DWORD dwNumVertices,
1271 DWORD dwFlags)
1272{
1273 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1274 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1275
1276 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags);
1277
1278 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags);
1279
1280 return DD_OK;
1281}
1282
1283HRESULT WINAPI
1284GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface,
1285 D3DPRIMITIVETYPE d3dptPrimitiveType,
1286 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,
1287 DWORD dwStartVertex,
1288 DWORD dwNumVertices,
1289 LPWORD lpwIndices,
1290 DWORD dwIndexCount,
1291 DWORD dwFlags)
1292{
1293 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1294 IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf);
1295
1296 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1297
1298 draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags);
1299
Christian Costa47b6b942002-12-16 23:07:41 +00001300 return DD_OK;
1301}
1302
1303HRESULT WINAPI
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001304GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
1305 DWORD dwStage,
1306 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,
1307 DWORD dwState)
1308{
1309 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1310 IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
1311 GLenum gl_state;
1312
1313 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
1314
1315 if (TRACE_ON(ddraw)) {
1316 TRACE(" Stage type is : ");
1317 switch (d3dTexStageStateType) {
1318#define GEN_CASE(a) case a: DPRINTF(#a " "); break
1319 GEN_CASE(D3DTSS_COLOROP);
1320 GEN_CASE(D3DTSS_COLORARG1);
1321 GEN_CASE(D3DTSS_COLORARG2);
1322 GEN_CASE(D3DTSS_ALPHAOP);
1323 GEN_CASE(D3DTSS_ALPHAARG1);
1324 GEN_CASE(D3DTSS_ALPHAARG2);
1325 GEN_CASE(D3DTSS_BUMPENVMAT00);
1326 GEN_CASE(D3DTSS_BUMPENVMAT01);
1327 GEN_CASE(D3DTSS_BUMPENVMAT10);
1328 GEN_CASE(D3DTSS_BUMPENVMAT11);
1329 GEN_CASE(D3DTSS_TEXCOORDINDEX);
1330 GEN_CASE(D3DTSS_ADDRESS);
1331 GEN_CASE(D3DTSS_ADDRESSU);
1332 GEN_CASE(D3DTSS_ADDRESSV);
1333 GEN_CASE(D3DTSS_BORDERCOLOR);
1334 GEN_CASE(D3DTSS_MAGFILTER);
1335 GEN_CASE(D3DTSS_MINFILTER);
1336 GEN_CASE(D3DTSS_MIPFILTER);
1337 GEN_CASE(D3DTSS_MIPMAPLODBIAS);
1338 GEN_CASE(D3DTSS_MAXMIPLEVEL);
1339 GEN_CASE(D3DTSS_MAXANISOTROPY);
1340 GEN_CASE(D3DTSS_BUMPENVLSCALE);
1341 GEN_CASE(D3DTSS_BUMPENVLOFFSET);
1342 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
1343#undef GEN_CASE
1344 default: DPRINTF("UNKNOWN !!!");
1345 }
1346 DPRINTF(" => ");
1347 }
1348
1349 switch (d3dTexStageStateType) {
1350 case D3DTSS_MINFILTER:
1351 switch ((D3DTEXTUREMINFILTER) dwState) {
1352 case D3DTFN_POINT:
1353 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_POINT\n");
1354 gl_state = GL_NEAREST;
1355 break;
1356 case D3DTFN_LINEAR:
1357 if (TRACE_ON(ddraw)) DPRINTF("D3DTFN_LINEAR\n");
1358 gl_state = GL_LINEAR;
1359 break;
1360 default:
1361 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1362 gl_state = GL_LINEAR;
1363 break;
1364 }
1365 glThis->render_state.min = gl_state;
1366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_state);
1367 break;
1368
1369 case D3DTSS_MAGFILTER:
1370 switch ((D3DTEXTUREMAGFILTER) dwState) {
1371 case D3DTFG_POINT:
1372 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_POINT\n");
1373 gl_state = GL_NEAREST;
1374 break;
1375 case D3DTFG_LINEAR:
1376 if (TRACE_ON(ddraw)) DPRINTF("D3DTFG_LINEAR\n");
1377 gl_state = GL_LINEAR;
1378 break;
1379 default:
1380 if (TRACE_ON(ddraw)) DPRINTF(" state unhandled.\n");
1381 gl_state = GL_LINEAR;
1382 break;
1383 }
1384 glThis->render_state.mag = gl_state;
1385 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_state);
1386 break;
Lionel Ulmerda66dad2003-01-02 19:43:08 +00001387
1388 case D3DTSS_ADDRESS:
1389 case D3DTSS_ADDRESSU:
1390 case D3DTSS_ADDRESSV: {
1391 GLenum arg = GL_REPEAT; /* Default value */
1392 switch ((D3DTEXTUREADDRESS) dwState) {
1393 case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
1394 case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
1395 case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) DPRINTF("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
1396 default: ERR("Unhandled TEXTUREADDRESS mode %ld !\n", dwState);
1397 }
1398 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1399 (d3dTexStageStateType == D3DTSS_ADDRESSU))
1400 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg);
1401 if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
1402 (d3dTexStageStateType == D3DTSS_ADDRESSV))
1403 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
1404 } break;
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001405
1406 default:
1407 if (TRACE_ON(ddraw)) DPRINTF(" unhandled.\n");
1408 }
1409
1410 return DD_OK;
1411}
1412
1413HRESULT WINAPI
Lionel Ulmer90bf1f22002-12-24 00:53:50 +00001414GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface,
1415 DWORD dwStage,
1416 LPDIRECTDRAWSURFACE7 lpTexture2)
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001417{
Lionel Ulmer90bf1f22002-12-24 00:53:50 +00001418 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001419
1420 TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2);
1421
1422 if (This->current_texture[dwStage] != NULL) {
1423 /* Seems that this is not right... Need to test in real Windows
1424 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1425 }
1426
1427 ENTER_GL();
1428 if (lpTexture2 == NULL) {
1429 TRACE(" disabling 2D texturing.\n");
1430 glBindTexture(GL_TEXTURE_2D, 0);
1431 glDisable(GL_TEXTURE_2D);
1432 } else {
Lionel Ulmer90bf1f22002-12-24 00:53:50 +00001433 IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
Lionel Ulmer91c6f812002-12-15 01:17:59 +00001434 IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001435
1436 This->current_texture[dwStage] = tex_impl;
Lionel Ulmer90bf1f22002-12-24 00:53:50 +00001437 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001438
1439 TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
1440
1441 glEnable(GL_TEXTURE_2D);
1442 glBindTexture(GL_TEXTURE_2D, tex_glimpl->tex_name);
1443 }
1444 LEAVE_GL();
1445
1446 return DD_OK;
1447}
1448
Lionel Ulmer5261f032002-12-02 21:39:34 +00001449HRESULT WINAPI
1450GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface,
1451 LPD3DDEVICEDESC7 lpD3DHELDevDesc)
1452{
1453 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1454 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc);
1455
1456 fill_opengl_caps_7(lpD3DHELDevDesc);
1457
1458 TRACE(" returning caps : no dump function yet.\n");
1459
1460 return DD_OK;
1461}
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001462
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001463#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1464# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1465#else
1466# define XCAST(fun) (void*)
1467#endif
1468
1469ICOM_VTABLE(IDirect3DDevice7) VTABLE_IDirect3DDevice7 =
1470{
1471 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1472 XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface,
1473 XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef,
1474 XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release,
Lionel Ulmer5261f032002-12-02 21:39:34 +00001475 XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001476 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats,
1477 XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene,
1478 XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene,
1479 XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D,
1480 XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget,
1481 XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget,
1482 XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear,
1483 XCAST(SetTransform) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform,
1484 XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform,
1485 XCAST(SetViewport) Main_IDirect3DDeviceImpl_7_SetViewport,
1486 XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform,
1487 XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport,
1488 XCAST(SetMaterial) Main_IDirect3DDeviceImpl_7_SetMaterial,
1489 XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial,
1490 XCAST(SetLight) Main_IDirect3DDeviceImpl_7_SetLight,
1491 XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight,
1492 XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState,
1493 XCAST(GetRenderState) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState,
1494 XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock,
1495 XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock,
1496 XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad,
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001497 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive,
1498 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001499 XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus,
1500 XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus,
Christian Costa47b6b942002-12-16 23:07:41 +00001501 XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided,
1502 XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided,
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001503 XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB,
1504 XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001505 XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility,
1506 XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_GetTexture,
Lionel Ulmer90bf1f22002-12-24 00:53:50 +00001507 XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001508 XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState,
Lionel Ulmer41fcb0b2002-12-02 18:59:11 +00001509 XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001510 XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice,
1511 XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock,
1512 XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock,
1513 XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock,
1514 XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock,
1515 XCAST(Load) Main_IDirect3DDeviceImpl_7_Load,
1516 XCAST(LightEnable) Main_IDirect3DDeviceImpl_7_LightEnable,
1517 XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable,
1518 XCAST(SetClipPlane) Main_IDirect3DDeviceImpl_7_SetClipPlane,
1519 XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane,
1520 XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo,
1521};
1522
1523#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1524#undef XCAST
1525#endif
1526
1527
1528#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1529# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1530#else
1531# define XCAST(fun) (void*)
1532#endif
1533
1534ICOM_VTABLE(IDirect3DDevice3) VTABLE_IDirect3DDevice3 =
1535{
1536 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1537 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface,
1538 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef,
1539 XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release,
1540 XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps,
1541 XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats,
1542 XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport,
1543 XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport,
1544 XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport,
1545 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
1546 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene,
1547 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene,
1548 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
1549 XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport,
1550 XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport,
1551 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
1552 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
1553 XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin,
1554 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed,
1555 XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex,
1556 XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index,
1557 XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End,
1558 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState,
1559 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState,
1560 XCAST(GetLightState) Main_IDirect3DDeviceImpl_3_2T_GetLightState,
1561 XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState,
1562 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform,
1563 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform,
1564 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
1565 XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
1566 XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
1567 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
1568 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
1569 XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
1570 XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
Lionel Ulmerce3d9682003-01-02 19:46:46 +00001571 XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
1572 XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001573 XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
1574 XCAST(GetTexture) Main_IDirect3DDeviceImpl_3_GetTexture,
Lionel Ulmer90bf1f22002-12-24 00:53:50 +00001575 XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture,
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001576 XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
1577 XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
1578 XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice,
1579};
1580
1581#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1582#undef XCAST
1583#endif
1584
1585
1586#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1587# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1588#else
1589# define XCAST(fun) (void*)
1590#endif
1591
1592ICOM_VTABLE(IDirect3DDevice2) VTABLE_IDirect3DDevice2 =
1593{
1594 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1595 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface,
1596 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef,
1597 XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release,
1598 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps,
1599 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_SwapTextureHandles,
1600 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats,
1601 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport,
1602 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
1603 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport,
1604 XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats,
1605 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene,
1606 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene,
1607 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
1608 XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
1609 XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
1610 XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
1611 XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
1612 XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin,
1613 XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed,
1614 XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex,
1615 XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index,
1616 XCAST(End) Thunk_IDirect3DDeviceImpl_2_End,
1617 XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState,
1618 XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState,
1619 XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState,
1620 XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState,
1621 XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform,
1622 XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform,
1623 XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
1624 XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive,
1625 XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
1626 XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
1627 XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus,
1628};
1629
1630#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1631#undef XCAST
1632#endif
1633
1634
1635#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1636# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1637#else
1638# define XCAST(fun) (void*)
1639#endif
1640
1641ICOM_VTABLE(IDirect3DDevice) VTABLE_IDirect3DDevice =
1642{
1643 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1644 XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface,
1645 XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef,
1646 XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release,
1647 XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize,
1648 XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps,
1649 XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_1_SwapTextureHandles,
1650 XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer,
1651 XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats,
1652 XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute,
1653 XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport,
1654 XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
1655 XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport,
1656 XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick,
1657 XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords,
1658 XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
1659 XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix,
1660 XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix,
1661 XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix,
1662 XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix,
1663 XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene,
1664 XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene,
1665 XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D,
1666};
1667
1668#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1669#undef XCAST
1670#endif
1671
Lionel Ulmer608da062002-12-24 01:03:04 +00001672static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This,
1673 DWORD dwCount,
1674 LPD3DRECT lpRects,
1675 DWORD dwFlags,
1676 DWORD dwColor,
1677 D3DVALUE dvZ,
1678 DWORD dwStencil)
1679{
1680 GLboolean ztest;
1681 GLfloat old_z_clear_value;
1682 GLbitfield bitfield = 0;
1683 GLint old_stencil_clear_value;
1684 GLfloat old_color_clear_value[4];
1685
1686 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
1687 if (TRACE_ON(ddraw)) {
1688 int i;
1689 TRACE(" rectangles : \n");
1690 for (i = 0; i < dwCount; i++) {
1691 TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2);
1692 }
1693 }
1694
1695 if (dwCount != 1) {
1696 WARN(" Warning, this function only for now clears the whole screen...\n");
1697 }
1698
1699 /* Clears the screen */
1700 ENTER_GL();
1701 if (dwFlags & D3DCLEAR_ZBUFFER) {
1702 bitfield |= GL_DEPTH_BUFFER_BIT;
1703 glGetBooleanv(GL_DEPTH_WRITEMASK, &ztest);
1704 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1705 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
1706 glClearDepth(dvZ);
1707 TRACE(" depth value : %f\n", dvZ);
1708 }
1709 if (dwFlags & D3DCLEAR_STENCIL) {
1710 bitfield |= GL_STENCIL_BUFFER_BIT;
1711 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
1712 glClearStencil(dwStencil);
1713 TRACE(" stencil value : %ld\n", dwStencil);
1714 }
1715 if (dwFlags & D3DCLEAR_TARGET) {
1716 bitfield |= GL_COLOR_BUFFER_BIT;
1717 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
1718 glClearColor(((dwColor >> 16) & 0xFF) / 255.0,
1719 ((dwColor >> 8) & 0xFF) / 255.0,
1720 ((dwColor >> 0) & 0xFF) / 255.0,
1721 ((dwColor >> 24) & 0xFF) / 255.0);
1722 TRACE(" color value (ARGB) : %08lx\n", dwColor);
1723 }
1724
1725 glClear(bitfield);
1726
1727 if (dwFlags & D3DCLEAR_ZBUFFER) {
1728 glDepthMask(ztest);
1729 glClearDepth(old_z_clear_value);
1730 }
1731 if (dwFlags & D3DCLEAR_STENCIL) {
1732 bitfield |= GL_STENCIL_BUFFER_BIT;
1733 glClearStencil(old_stencil_clear_value);
1734 }
1735 if (dwFlags & D3DCLEAR_TARGET) {
1736 bitfield |= GL_COLOR_BUFFER_BIT;
1737 glClearColor(old_color_clear_value[0],
1738 old_color_clear_value[1],
1739 old_color_clear_value[2],
1740 old_color_clear_value[3]);
1741 }
1742
1743 LEAVE_GL();
1744
1745 return DD_OK;
1746}
1747
1748
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001749/* TODO for both these functions :
1750 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1751 by other OpenGL code in D3D
1752 - handle the case where no 'Begin / EndScene' was done between two locks
1753 - handle the rectangles in the unlock too
Lionel Ulmera6e50802002-11-30 19:19:00 +00001754 - handle pitch correctly...
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001755*/
1756static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
1757{
1758 /* First, check if we need to do anything */
1759 if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
1760 GLenum buffer_type;
1761 GLenum prev_read;
1762 RECT loc_rect;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001763
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001764 ENTER_GL();
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001765
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001766 glGetIntegerv(GL_READ_BUFFER, &prev_read);
1767 glFlush();
1768
1769 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1770 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1771 /* Application wants to lock the front buffer */
1772 glReadBuffer(GL_FRONT);
1773 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1774 /* Application wants to lock the back buffer */
1775 glReadBuffer(GL_BACK);
1776 } else {
1777 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1778 }
1779
1780 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1781 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1782 } else {
1783 WARN(" unsupported pixel format.\n");
1784 LEAVE_GL();
1785 return;
1786 }
1787 if (pRect == NULL) {
1788 loc_rect.top = 0;
1789 loc_rect.left = 0;
1790 loc_rect.bottom = This->surface_desc.dwHeight;
1791 loc_rect.right = This->surface_desc.dwWidth;
1792 } else {
1793 loc_rect = *pRect;
1794 }
1795 glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
1796 GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
1797 + loc_rect.top * This->surface_desc.u1.lPitch
1798 + loc_rect.left * GET_BPP(This->surface_desc)));
1799 glReadBuffer(prev_read);
1800 LEAVE_GL();
1801 }
1802}
1803
1804static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
1805{
1806 /* First, check if we need to do anything */
1807 if ((This->lastlocktype & DDLOCK_READONLY) == 0) {
1808 GLenum buffer_type;
1809 GLenum prev_draw;
1810
1811 ENTER_GL();
1812
1813 glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
1814
1815 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1816 if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
1817 /* Application wants to lock the front buffer */
1818 glDrawBuffer(GL_FRONT);
1819 } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) {
1820 /* Application wants to lock the back buffer */
1821 glDrawBuffer(GL_BACK);
1822 } else {
Lionel Ulmer708c4b22002-11-30 19:12:32 +00001823 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001824 }
1825
1826 if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
1827 buffer_type = GL_UNSIGNED_SHORT_5_6_5;
1828 } else {
1829 WARN(" unsupported pixel format.\n");
1830 LEAVE_GL();
1831 return;
1832 }
Lionel Ulmera6e50802002-11-30 19:19:00 +00001833 glRasterPos2f(0.0, 0.0);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001834 glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
1835 GL_RGB, buffer_type, This->surface_desc.lpSurface);
1836 glDrawBuffer(prev_draw);
1837
1838 LEAVE_GL();
1839 }
1840}
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001841
1842HRESULT
1843d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
1844{
1845 IDirect3DDeviceImpl *object;
1846 IDirect3DDeviceGLImpl *gl_object;
1847 IDirectDrawSurfaceImpl *surf;
1848 HDC device_context;
1849 XVisualInfo *vis;
1850 int num;
1851 XVisualInfo template;
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001852 GLenum buffer;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001853
1854 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl));
1855 if (object == NULL) return DDERR_OUTOFMEMORY;
1856
1857 gl_object = (IDirect3DDeviceGLImpl *) object;
1858
1859 object->ref = 1;
1860 object->d3d = d3d;
1861 object->surface = surface;
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001862 object->set_context = set_context;
Lionel Ulmer608da062002-12-24 01:03:04 +00001863 object->clear = d3ddevice_clear;
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001864
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001865 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
1866
1867 device_context = GetDC(surface->ddraw_owner->window);
1868 gl_object->display = get_display(device_context);
1869 gl_object->drawable = get_drawable(device_context);
1870 ReleaseDC(surface->ddraw_owner->window,device_context);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001871
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001872 ENTER_GL();
1873 template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
1874 vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num);
1875 if (vis == NULL) {
1876 HeapFree(GetProcessHeap(), 0, object);
1877 ERR("No visual found !\n");
1878 LEAVE_GL();
1879 return DDERR_INVALIDPARAMS;
1880 } else {
1881 TRACE(" visual found\n");
1882 }
1883
1884 gl_object->gl_context = glXCreateContext(gl_object->display, vis,
1885 NULL, GL_TRUE);
1886
1887 if (gl_object->gl_context == NULL) {
1888 HeapFree(GetProcessHeap(), 0, object);
1889 ERR("Error in context creation !\n");
1890 LEAVE_GL();
1891 return DDERR_INVALIDPARAMS;
1892 } else {
1893 TRACE(" context created (%p)\n", gl_object->gl_context);
1894 }
1895
1896 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
1897 for (surf = surface; surf != NULL; surf = surf->surface_owner) {
1898 if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) {
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001899 surf->aux_ctx = (LPVOID) gl_object->display;
1900 surf->aux_data = (LPVOID) gl_object->drawable;
1901 surf->aux_flip = opengl_flip;
1902 buffer = GL_BACK;
Christian Costab47c14a2002-10-17 01:20:52 +00001903 break;
1904 }
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001905 }
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001906 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
1907 if (surf == NULL) {
1908 TRACE(" no double buffering : drawing on the front buffer\n");
1909 buffer = GL_FRONT;
1910 }
1911
1912 for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
1913 for (; surf != NULL; surf = surf->next_attached) {
1914 if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
1915 ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
1916 /* Override the Lock / Unlock function for all these surfaces */
1917 surf->lock_update = d3ddevice_lock_update;
1918 surf->unlock_update = d3ddevice_unlock_update;
1919 }
1920 surf->d3ddevice = object;
1921 }
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001922
1923 gl_object->render_state.src = GL_ONE;
1924 gl_object->render_state.dst = GL_ZERO;
1925 gl_object->render_state.mag = GL_NEAREST;
1926 gl_object->render_state.min = GL_NEAREST;
Lionel Ulmerdfddf922002-12-16 22:39:09 +00001927 gl_object->render_state.alpha_ref = 0.0; /* No actual idea about the real default value... */
1928 gl_object->render_state.alpha_func = GL_ALWAYS; /* Here either but it seems logical */
Lionel Ulmerc3d89f52003-01-02 19:45:23 +00001929 gl_object->render_state.alpha_blend_enable = FALSE;
1930 gl_object->render_state.fog_on = FALSE;
Lionel Ulmerdfddf922002-12-16 22:39:09 +00001931
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001932 /* Allocate memory for the matrices */
1933 gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1934 gl_object->view_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
1935 gl_object->proj_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
Lionel Ulmer74c3eab2002-12-24 01:07:21 +00001936 gl_object->matrices_changed = TRUE;
1937
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001938 memcpy(gl_object->world_mat, id_mat, 16 * sizeof(float));
1939 memcpy(gl_object->view_mat , id_mat, 16 * sizeof(float));
1940 memcpy(gl_object->proj_mat , id_mat, 16 * sizeof(float));
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001941
1942 /* Initialisation */
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001943 TRACE(" setting current context\n");
Christian Costa427b3332002-09-27 22:01:12 +00001944 LEAVE_GL();
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001945 object->set_context(object);
Christian Costa427b3332002-09-27 22:01:12 +00001946 ENTER_GL();
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001947 TRACE(" current context set\n");
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001948 glClearColor(0.0, 0.0, 0.0, 0.0);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001949 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1950 glDrawBuffer(buffer);
Lionel Ulmera6e50802002-11-30 19:19:00 +00001951 glReadBuffer(buffer);
Lionel Ulmer5f49e782002-11-30 19:06:52 +00001952 /* 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 +00001953 LEAVE_GL();
Lionel Ulmera8cc5f52000-07-16 14:40:35 +00001954
Christian Costa774c5f72002-11-24 22:14:40 +00001955 /* fill_device_capabilities(d3d->ddraw); */
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001956
1957 ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice);
1958 ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2);
1959 ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3);
1960 ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7);
Vincent Béron9a624912002-05-31 23:06:46 +00001961
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001962 *obj = object;
1963
1964 TRACE(" creating implementation at %p.\n", *obj);
Lionel Ulmer8cd26092003-01-02 19:39:57 +00001965
1966 /* And finally warn D3D that this device is now present */
1967 object->d3d->added_device(object->d3d, object);
Lionel Ulmer43c3dc42002-11-21 21:04:16 +00001968
1969 return DD_OK;
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001970}