2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the MESA implementation of all the D3D devices that
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/debug.h"
33 #include "mesa_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
40 /* They are non-static as they are used by Direct3D in the creation function */
41 const GUID IID_D3DDEVICE_OpenGL
= {
45 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
48 #ifndef HAVE_GLEXT_PROTOTYPES
49 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
50 typedef void (* PFNGLCOLORTABLEEXTPROC
) (GLenum target
, GLenum internalFormat
,
51 GLsizei width
, GLenum format
, GLenum type
,
55 const float id_mat
[16] = {
62 static void draw_primitive_strided(IDirect3DDeviceImpl
*This
,
63 D3DPRIMITIVETYPE d3dptPrimitiveType
,
64 DWORD d3dvtVertexType
,
65 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData
,
72 /* retrieve the X display to use on a given DC */
73 inline static Display
*get_display( HDC hdc
)
76 enum x11drv_escape_codes escape
= X11DRV_GET_DISPLAY
;
78 if (!ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
,
79 sizeof(display
), (LPSTR
)&display
)) display
= NULL
;
85 /* retrieve the X drawable to use on a given DC */
86 inline static Drawable
get_drawable( HDC hdc
)
89 enum x11drv_escape_codes escape
= X11DRV_GET_DRAWABLE
;
91 if (!ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
,
92 sizeof(drawable
), (LPSTR
)&drawable
)) drawable
= 0;
98 static BOOL
opengl_flip( LPVOID display
, LPVOID drawable
)
100 TRACE("(%p, %ld)\n",(Display
*)display
,(Drawable
)drawable
);
102 glXSwapBuffers((Display
*)display
,(Drawable
)drawable
);
108 /*******************************************************************************
109 * OpenGL static functions
111 static void set_context(IDirect3DDeviceImpl
* This
)
113 IDirect3DDeviceGLImpl
* glThis
= (IDirect3DDeviceGLImpl
*) This
;
116 TRACE("glxMakeCurrent %p, %ld, %p\n",glThis
->display
,glThis
->drawable
, glThis
->gl_context
);
117 if (glXMakeCurrent(glThis
->display
, glThis
->drawable
, glThis
->gl_context
) == False
) {
118 ERR("Error in setting current context (context %p drawable %ld)!\n",
119 glThis
->gl_context
, glThis
->drawable
);
124 static void fill_opengl_primcaps(D3DPRIMCAPS
*pc
)
126 pc
->dwSize
= sizeof(*pc
);
127 pc
->dwMiscCaps
= D3DPMISCCAPS_CONFORMANT
| D3DPMISCCAPS_CULLCCW
| D3DPMISCCAPS_CULLCW
|
128 D3DPMISCCAPS_LINEPATTERNREP
| D3DPMISCCAPS_MASKZ
;
129 pc
->dwRasterCaps
= D3DPRASTERCAPS_DITHER
| D3DPRASTERCAPS_FOGRANGE
| D3DPRASTERCAPS_FOGTABLE
|
130 D3DPRASTERCAPS_FOGVERTEX
| D3DPRASTERCAPS_STIPPLE
| D3DPRASTERCAPS_ZBIAS
| D3DPRASTERCAPS_ZTEST
| D3DPRASTERCAPS_SUBPIXEL
;
131 pc
->dwZCmpCaps
= D3DPCMPCAPS_ALWAYS
| D3DPCMPCAPS_EQUAL
| D3DPCMPCAPS_GREATER
| D3DPCMPCAPS_GREATEREQUAL
|
132 D3DPCMPCAPS_LESS
| D3DPCMPCAPS_LESSEQUAL
| D3DPCMPCAPS_NEVER
| D3DPCMPCAPS_NOTEQUAL
;
133 pc
->dwSrcBlendCaps
= D3DPBLENDCAPS_ZERO
| D3DPBLENDCAPS_ONE
| D3DPBLENDCAPS_DESTCOLOR
| D3DPBLENDCAPS_INVDESTCOLOR
|
134 D3DPBLENDCAPS_SRCALPHA
| D3DPBLENDCAPS_INVSRCALPHA
| D3DPBLENDCAPS_DESTALPHA
| D3DPBLENDCAPS_INVDESTALPHA
| D3DPBLENDCAPS_SRCALPHASAT
|
135 D3DPBLENDCAPS_BOTHSRCALPHA
| D3DPBLENDCAPS_BOTHINVSRCALPHA
;
136 pc
->dwDestBlendCaps
= D3DPBLENDCAPS_ZERO
| D3DPBLENDCAPS_ONE
| D3DPBLENDCAPS_SRCCOLOR
| D3DPBLENDCAPS_INVSRCCOLOR
|
137 D3DPBLENDCAPS_SRCALPHA
| D3DPBLENDCAPS_INVSRCALPHA
| D3DPBLENDCAPS_DESTALPHA
| D3DPBLENDCAPS_INVDESTALPHA
| D3DPBLENDCAPS_SRCALPHASAT
|
138 D3DPBLENDCAPS_BOTHSRCALPHA
| D3DPBLENDCAPS_BOTHINVSRCALPHA
;
139 pc
->dwAlphaCmpCaps
= D3DPCMPCAPS_ALWAYS
| D3DPCMPCAPS_EQUAL
| D3DPCMPCAPS_GREATER
| D3DPCMPCAPS_GREATEREQUAL
|
140 D3DPCMPCAPS_LESS
| D3DPCMPCAPS_LESSEQUAL
| D3DPCMPCAPS_NEVER
| D3DPCMPCAPS_NOTEQUAL
;
141 pc
->dwShadeCaps
= D3DPSHADECAPS_ALPHAFLATBLEND
| D3DPSHADECAPS_ALPHAGOURAUDBLEND
| D3DPSHADECAPS_COLORFLATRGB
| D3DPSHADECAPS_COLORGOURAUDRGB
|
142 D3DPSHADECAPS_FOGFLAT
| D3DPSHADECAPS_FOGGOURAUD
| D3DPSHADECAPS_SPECULARFLATRGB
| D3DPSHADECAPS_SPECULARGOURAUDRGB
;
143 pc
->dwTextureCaps
= D3DPTEXTURECAPS_ALPHA
| D3DPTEXTURECAPS_ALPHAPALETTE
| D3DPTEXTURECAPS_BORDER
| D3DPTEXTURECAPS_PERSPECTIVE
|
144 D3DPTEXTURECAPS_POW2
| D3DPTEXTURECAPS_TRANSPARENCY
;
145 pc
->dwTextureFilterCaps
= D3DPTFILTERCAPS_LINEAR
| D3DPTFILTERCAPS_LINEARMIPLINEAR
| D3DPTFILTERCAPS_LINEARMIPNEAREST
|
146 D3DPTFILTERCAPS_MIPLINEAR
| D3DPTFILTERCAPS_MIPNEAREST
| D3DPTFILTERCAPS_NEAREST
;
147 pc
->dwTextureBlendCaps
= D3DPTBLENDCAPS_ADD
| D3DPTBLENDCAPS_COPY
| D3DPTBLENDCAPS_DECAL
| D3DPTBLENDCAPS_DECALALPHA
| D3DPTBLENDCAPS_DECALMASK
|
148 D3DPTBLENDCAPS_MODULATE
| D3DPTBLENDCAPS_MODULATEALPHA
| D3DPTBLENDCAPS_MODULATEMASK
;
149 pc
->dwTextureAddressCaps
= D3DPTADDRESSCAPS_BORDER
| D3DPTADDRESSCAPS_CLAMP
| D3DPTADDRESSCAPS_WRAP
| D3DPTADDRESSCAPS_INDEPENDENTUV
;
150 pc
->dwStippleWidth
= 32;
151 pc
->dwStippleHeight
= 32;
154 static void fill_opengl_caps(D3DDEVICEDESC
*d1
)
156 /* GLint maxlight; */
158 d1
->dwSize
= sizeof(*d1
);
159 d1
->dwFlags
= D3DDD_DEVCAPS
| D3DDD_BCLIPPING
| D3DDD_COLORMODEL
| D3DDD_DEVICERENDERBITDEPTH
| D3DDD_DEVICEZBUFFERBITDEPTH
160 | D3DDD_LIGHTINGCAPS
| D3DDD_LINECAPS
| D3DDD_MAXBUFFERSIZE
| D3DDD_MAXVERTEXCOUNT
| D3DDD_TRANSFORMCAPS
| D3DDD_TRICAPS
;
161 d1
->dcmColorModel
= D3DCOLOR_RGB
;
162 d1
->dwDevCaps
= D3DDEVCAPS_CANRENDERAFTERFLIP
| D3DDEVCAPS_DRAWPRIMTLVERTEX
| D3DDEVCAPS_EXECUTESYSTEMMEMORY
|
163 D3DDEVCAPS_EXECUTEVIDEOMEMORY
| D3DDEVCAPS_FLOATTLVERTEX
| D3DDEVCAPS_TEXTURENONLOCALVIDMEM
| D3DDEVCAPS_TEXTURESYSTEMMEMORY
|
164 D3DDEVCAPS_TEXTUREVIDEOMEMORY
| D3DDEVCAPS_TLVERTEXSYSTEMMEMORY
| D3DDEVCAPS_TLVERTEXVIDEOMEMORY
|
165 /* D3D 7 capabilities */
166 D3DDEVCAPS_DRAWPRIMITIVES2
| D3DDEVCAPS_HWTRANSFORMANDLIGHT
| D3DDEVCAPS_HWRASTERIZATION
;
167 d1
->dtcTransformCaps
.dwSize
= sizeof(D3DTRANSFORMCAPS
);
168 d1
->dtcTransformCaps
.dwCaps
= D3DTRANSFORMCAPS_CLIP
;
169 d1
->bClipping
= TRUE
;
170 d1
->dlcLightingCaps
.dwSize
= sizeof(D3DLIGHTINGCAPS
);
171 d1
->dlcLightingCaps
.dwCaps
= D3DLIGHTCAPS_DIRECTIONAL
| D3DLIGHTCAPS_PARALLELPOINT
| D3DLIGHTCAPS_POINT
| D3DLIGHTCAPS_SPOT
;
172 d1
->dlcLightingCaps
.dwLightingModel
= D3DLIGHTINGMODEL_RGB
;
173 d1
->dlcLightingCaps
.dwNumLights
= 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
174 fill_opengl_primcaps(&(d1
->dpcLineCaps
));
175 fill_opengl_primcaps(&(d1
->dpcTriCaps
));
176 d1
->dwDeviceRenderBitDepth
= DDBD_16
|DDBD_24
|DDBD_32
;
177 d1
->dwDeviceZBufferBitDepth
= DDBD_16
|DDBD_24
|DDBD_32
;
178 d1
->dwMaxBufferSize
= 0;
179 d1
->dwMaxVertexCount
= 65536;
180 d1
->dwMinTextureWidth
= 1;
181 d1
->dwMinTextureHeight
= 1;
182 d1
->dwMaxTextureWidth
= 1024;
183 d1
->dwMaxTextureHeight
= 1024;
184 d1
->dwMinStippleWidth
= 1;
185 d1
->dwMinStippleHeight
= 1;
186 d1
->dwMaxStippleWidth
= 32;
187 d1
->dwMaxStippleHeight
= 32;
188 d1
->dwMaxTextureRepeat
= 16;
189 d1
->dwMaxTextureAspectRatio
= 1024;
190 d1
->dwMaxAnisotropy
= 0;
191 d1
->dvGuardBandLeft
= 0.0;
192 d1
->dvGuardBandRight
= 0.0;
193 d1
->dvGuardBandTop
= 0.0;
194 d1
->dvGuardBandBottom
= 0.0;
195 d1
->dvExtentsAdjust
= 0.0;
196 d1
->dwStencilCaps
= D3DSTENCILCAPS_DECRSAT
| D3DSTENCILCAPS_INCRSAT
| D3DSTENCILCAPS_INVERT
| D3DSTENCILCAPS_KEEP
|
197 D3DSTENCILCAPS_REPLACE
| D3DSTENCILCAPS_ZERO
;
198 d1
->dwFVFCaps
= D3DFVFCAPS_DONOTSTRIPELEMENTS
| 1;
199 d1
->dwTextureOpCaps
= 0; /* TODO add proper caps according to OpenGL multi-texture stuff */
200 d1
->wMaxTextureBlendStages
= 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
201 d1
->wMaxSimultaneousTextures
= 1; /* TODO add proper caps according to OpenGL multi-texture stuff */
204 static void fill_opengl_caps_7(D3DDEVICEDESC7
*d
)
208 /* Copy first D3D1/2/3 capabilities */
209 fill_opengl_caps(&d1
);
211 /* And fill the D3D7 one with it */
212 d
->dwDevCaps
= d1
.dwDevCaps
;
213 d
->dpcLineCaps
= d1
.dpcLineCaps
;
214 d
->dpcTriCaps
= d1
.dpcTriCaps
;
215 d
->dwDeviceRenderBitDepth
= d1
.dwDeviceRenderBitDepth
;
216 d
->dwDeviceZBufferBitDepth
= d1
.dwDeviceZBufferBitDepth
;
217 d
->dwMinTextureWidth
= d1
.dwMinTextureWidth
;
218 d
->dwMinTextureHeight
= d1
.dwMinTextureHeight
;
219 d
->dwMaxTextureWidth
= d1
.dwMaxTextureWidth
;
220 d
->dwMaxTextureHeight
= d1
.dwMaxTextureHeight
;
221 d
->dwMaxTextureRepeat
= d1
.dwMaxTextureRepeat
;
222 d
->dwMaxTextureAspectRatio
= d1
.dwMaxTextureAspectRatio
;
223 d
->dwMaxAnisotropy
= d1
.dwMaxAnisotropy
;
224 d
->dvGuardBandLeft
= d1
.dvGuardBandLeft
;
225 d
->dvGuardBandTop
= d1
.dvGuardBandTop
;
226 d
->dvGuardBandRight
= d1
.dvGuardBandRight
;
227 d
->dvGuardBandBottom
= d1
.dvGuardBandBottom
;
228 d
->dvExtentsAdjust
= d1
.dvExtentsAdjust
;
229 d
->dwStencilCaps
= d1
.dwStencilCaps
;
230 d
->dwFVFCaps
= d1
.dwFVFCaps
;
231 d
->dwTextureOpCaps
= d1
.dwTextureOpCaps
;
232 d
->wMaxTextureBlendStages
= d1
.wMaxTextureBlendStages
;
233 d
->wMaxSimultaneousTextures
= d1
.wMaxSimultaneousTextures
;
234 d
->dwMaxActiveLights
= d1
.dlcLightingCaps
.dwNumLights
;
235 d
->dvMaxVertexW
= 100000000.0; /* No idea exactly what to put here... */
236 d
->deviceGUID
= IID_IDirect3DTnLHalDevice
;
237 d
->wMaxUserClipPlanes
= 1;
238 d
->wMaxVertexBlendMatrices
= 0;
239 d
->dwVertexProcessingCaps
= D3DVTXPCAPS_TEXGEN
| D3DVTXPCAPS_MATERIALSOURCE7
| D3DVTXPCAPS_VERTEXFOG
| D3DVTXPCAPS_DIRECTIONALLIGHTS
|
240 D3DVTXPCAPS_POSITIONALLIGHTS
| D3DVTXPCAPS_LOCALVIEWER
;
247 #if 0 /* TODO : fix this and add multitexturing and other needed stuff */
248 static void fill_device_capabilities(IDirectDrawImpl
* ddraw
)
250 x11_dd_private
*private = (x11_dd_private
*) ddraw
->d
->private;
251 const char *ext_string
;
252 Mesa_DeviceCapabilities
*devcap
;
254 private->device_capabilities
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(Mesa_DeviceCapabilities
));
255 devcap
= (Mesa_DeviceCapabilities
*) private->device_capabilities
;
258 ext_string
= glGetString(GL_EXTENSIONS
);
259 /* Query for the ColorTable Extension */
260 if (strstr(ext_string
, "GL_EXT_paletted_texture")) {
261 devcap
->ptr_ColorTableEXT
= (PFNGLCOLORTABLEEXTPROC
) glXGetProcAddressARB("glColorTableEXT");
262 TRACE("Color table extension supported (function at %p)\n", devcap
->ptr_ColorTableEXT
);
264 TRACE("Color table extension not found.\n");
272 HRESULT
d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
)
274 D3DDEVICEDESC dref
, d1
, d2
;
277 fill_opengl_caps(&dref
);
279 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice
));
282 ret_value
= cb((LPIID
) &IID_IDirect3DRefDevice
, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1
, &d2
, context
);
283 if (ret_value
!= D3DENUMRET_OK
)
286 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL
));
289 ret_value
= cb((LPIID
) &IID_D3DDEVICE_OpenGL
, "WINE Direct3DX using OpenGL", "direct3d", &d1
, &d2
, context
);
290 if (ret_value
!= D3DENUMRET_OK
)
293 return D3DENUMRET_OK
;
296 HRESULT
d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb
, LPVOID context
)
298 D3DDEVICEDESC7 ddesc
;
300 fill_opengl_caps_7(&ddesc
);
302 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
304 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc
, context
);
308 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface
)
310 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
311 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
313 TRACE("(%p/%p)->() decrementing from %lu.\n", This
, iface
, This
->ref
);
314 if (!--(This
->ref
)) {
315 /* Release texture associated with the device */
316 if (This
->current_texture
[0] != NULL
)
317 IDirect3DTexture2_Release(ICOM_INTERFACE(This
->current_texture
[0], IDirect3DTexture2
));
319 /* And warn the D3D object that this device is no longer active... */
320 This
->d3d
->removed_device(This
->d3d
, This
);
322 HeapFree(GetProcessHeap(), 0, This
->world_mat
);
323 HeapFree(GetProcessHeap(), 0, This
->view_mat
);
324 HeapFree(GetProcessHeap(), 0, This
->proj_mat
);
327 glXDestroyContext(glThis
->display
, glThis
->gl_context
);
330 HeapFree(GetProcessHeap(), 0, This
);
337 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface
,
338 LPD3DDEVICEDESC lpD3DHWDevDesc
,
339 LPD3DDEVICEDESC lpD3DHELDevDesc
)
341 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
345 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DHWDevDesc
, lpD3DHELDevDesc
);
347 fill_opengl_caps(&desc
);
348 dwSize
= lpD3DHWDevDesc
->dwSize
;
349 memset(lpD3DHWDevDesc
, 0, dwSize
);
350 memcpy(lpD3DHWDevDesc
, &desc
, (dwSize
<= desc
.dwSize
? dwSize
: desc
.dwSize
));
352 dwSize
= lpD3DHELDevDesc
->dwSize
;
353 memset(lpD3DHELDevDesc
, 0, dwSize
);
354 memcpy(lpD3DHELDevDesc
, &desc
, (dwSize
<= desc
.dwSize
? dwSize
: desc
.dwSize
));
356 TRACE(" returning caps : (no dump function yet)\n");
361 static HRESULT
enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1
,
362 LPD3DENUMPIXELFORMATSCALLBACK cb_2
,
366 LPDDPIXELFORMAT pformat
;
368 /* Do the texture enumeration */
369 sdesc
.dwSize
= sizeof(DDSURFACEDESC
);
370 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
371 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
372 pformat
= &(sdesc
.ddpfPixelFormat
);
373 pformat
->dwSize
= sizeof(DDPIXELFORMAT
);
374 pformat
->dwFourCC
= 0;
376 TRACE("Enumerating GL_RGBA unpacked (32)\n");
377 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
378 pformat
->u1
.dwRGBBitCount
= 32;
379 pformat
->u2
.dwRBitMask
= 0xFF000000;
380 pformat
->u3
.dwGBitMask
= 0x00FF0000;
381 pformat
->u4
.dwBBitMask
= 0x0000FF00;
382 pformat
->u5
.dwRGBAlphaBitMask
= 0x000000FF;
383 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
384 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
386 TRACE("Enumerating GL_RGB unpacked (24)\n");
387 pformat
->dwFlags
= DDPF_RGB
;
388 pformat
->u1
.dwRGBBitCount
= 24;
389 pformat
->u2
.dwRBitMask
= 0x00FF0000;
390 pformat
->u3
.dwGBitMask
= 0x0000FF00;
391 pformat
->u4
.dwBBitMask
= 0x000000FF;
392 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
393 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
394 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
396 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
397 pformat
->dwFlags
= DDPF_RGB
;
398 pformat
->u1
.dwRGBBitCount
= 16;
399 pformat
->u2
.dwRBitMask
= 0x0000F800;
400 pformat
->u3
.dwGBitMask
= 0x000007E0;
401 pformat
->u4
.dwBBitMask
= 0x0000001F;
402 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
403 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
404 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
406 /* Note : even if this is an 'emulated' texture format, it needs to be first
407 as some dumb applications seem to rely on that. */
408 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n");
409 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
410 pformat
->u1
.dwRGBBitCount
= 16;
411 pformat
->u2
.dwRBitMask
= 0x00007C00;
412 pformat
->u3
.dwGBitMask
= 0x000003E0;
413 pformat
->u4
.dwBBitMask
= 0x0000001F;
414 pformat
->u5
.dwRGBAlphaBitMask
= 0x00008000;
415 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
416 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
418 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
419 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
420 pformat
->u1
.dwRGBBitCount
= 16;
421 pformat
->u2
.dwRBitMask
= 0x0000F800;
422 pformat
->u3
.dwGBitMask
= 0x000007C0;
423 pformat
->u4
.dwBBitMask
= 0x0000003E;
424 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000001;
425 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
426 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
428 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
429 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
430 pformat
->u1
.dwRGBBitCount
= 16;
431 pformat
->u2
.dwRBitMask
= 0x00000F00;
432 pformat
->u3
.dwGBitMask
= 0x000000F0;
433 pformat
->u4
.dwBBitMask
= 0x0000000F;
434 pformat
->u5
.dwRGBAlphaBitMask
= 0x0000F000;
435 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
436 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
438 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
439 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
440 pformat
->u1
.dwRGBBitCount
= 16;
441 pformat
->u2
.dwRBitMask
= 0x0000F000;
442 pformat
->u3
.dwGBitMask
= 0x00000F00;
443 pformat
->u4
.dwBBitMask
= 0x000000F0;
444 pformat
->u5
.dwRGBAlphaBitMask
= 0x0000000F;
445 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
446 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
448 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
449 pformat
->dwFlags
= DDPF_RGB
;
450 pformat
->u1
.dwRGBBitCount
= 8;
451 pformat
->u2
.dwRBitMask
= 0x000000E0;
452 pformat
->u3
.dwGBitMask
= 0x0000001C;
453 pformat
->u4
.dwBBitMask
= 0x00000003;
454 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
455 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
456 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
458 TRACE("Enumerating Paletted (8)\n");
459 pformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
460 pformat
->u1
.dwRGBBitCount
= 8;
461 pformat
->u2
.dwRBitMask
= 0x00000000;
462 pformat
->u3
.dwGBitMask
= 0x00000000;
463 pformat
->u4
.dwBBitMask
= 0x00000000;
464 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
465 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
466 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
468 TRACE("End of enumeration\n");
474 d3ddevice_find(IDirect3DImpl
*d3d
,
475 LPD3DFINDDEVICESEARCH lpD3DDFS
,
476 LPD3DFINDDEVICERESULT lplpD3DDevice
)
480 if ((lpD3DDFS
->dwFlags
& D3DFDS_COLORMODEL
) &&
481 (lpD3DDFS
->dcmColorModel
!= D3DCOLOR_RGB
)) {
482 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
483 return DDERR_INVALIDPARAMS
; /* No real idea what to return here :-) */
485 if (lpD3DDFS
->dwFlags
& D3DFDS_GUID
) {
486 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS
->guid
)));
487 if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL
, &(lpD3DDFS
->guid
)) == 0) &&
488 (IsEqualGUID(&IID_IDirect3DHALDevice
, &(lpD3DDFS
->guid
)) == 0) &&
489 (IsEqualGUID(&IID_IDirect3DRefDevice
, &(lpD3DDFS
->guid
)) == 0)) {
490 TRACE(" no match for this GUID.\n");
491 return DDERR_INVALIDPARAMS
;
495 /* Now return our own GUID */
496 lplpD3DDevice
->guid
= IID_D3DDEVICE_OpenGL
;
497 fill_opengl_caps(&desc
);
498 lplpD3DDevice
->ddHwDesc
= desc
;
499 lplpD3DDevice
->ddSwDesc
= desc
;
501 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
507 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface
,
508 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc
,
511 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
512 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DEnumTextureProc
, lpArg
);
513 return enum_texture_format_OpenGL(lpD3DEnumTextureProc
, NULL
, lpArg
);
517 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface
,
518 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc
,
521 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
522 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DEnumPixelProc
, lpArg
);
523 return enum_texture_format_OpenGL(NULL
, lpD3DEnumPixelProc
, lpArg
);
527 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface
,
528 D3DRENDERSTATETYPE dwRenderStateType
,
531 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
532 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
533 TRACE("(%p/%p)->(%08x,%08lx)\n", This
, iface
, dwRenderStateType
, dwRenderState
);
535 /* Call the render state functions */
536 set_render_state(glThis
, dwRenderStateType
, dwRenderState
);
537 store_render_state(dwRenderStateType
, dwRenderState
, &glThis
->parent
.state_block
);
543 GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface
,
544 D3DRENDERSTATETYPE dwRenderStateType
,
545 LPDWORD lpdwRenderState
)
547 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
548 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
549 TRACE("(%p/%p)->(%08x,%p)\n", This
, iface
, dwRenderStateType
, lpdwRenderState
);
551 /* Call the render state functions */
552 get_render_state(dwRenderStateType
, lpdwRenderState
, &glThis
->parent
.state_block
);
558 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface
,
559 D3DLIGHTSTATETYPE dwLightStateType
,
562 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
563 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
565 TRACE("(%p/%p)->(%08x,%08lx)\n", This
, iface
, dwLightStateType
, dwLightState
);
567 switch (dwLightStateType
) {
568 case D3DLIGHTSTATE_MATERIAL
: { /* 1 */
569 IDirect3DMaterialImpl
*mat
= (IDirect3DMaterialImpl
*) dwLightState
;
576 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
580 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
581 /* Call the render_state function... */
582 set_render_state(glThis
, D3DRENDERSTATE_AMBIENT
, dwLightState
);
585 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
595 TRACE("Unexpected Light State Type\n");
596 return DDERR_INVALIDPARAMS
;
599 This
->state_block
.light_state
[dwLightStateType
] = dwLightState
;
604 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt
)
607 case D3DPT_POINTLIST
:
608 TRACE("Start POINTS\n");
613 TRACE("Start LINES\n");
617 case D3DPT_LINESTRIP
:
618 TRACE("Start LINE_STRIP\n");
619 glBegin(GL_LINE_STRIP
);
622 case D3DPT_TRIANGLELIST
:
623 TRACE("Start TRIANGLES\n");
624 glBegin(GL_TRIANGLES
);
627 case D3DPT_TRIANGLESTRIP
:
628 TRACE("Start TRIANGLE_STRIP\n");
629 glBegin(GL_TRIANGLE_STRIP
);
632 case D3DPT_TRIANGLEFAN
:
633 TRACE("Start TRIANGLE_FAN\n");
634 glBegin(GL_TRIANGLE_FAN
);
638 TRACE("Unhandled primitive\n");
643 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl
*This
,
644 BOOLEAN vertex_transformed
,
645 BOOLEAN vertex_lit
) {
646 IDirect3DDeviceGLImpl
* glThis
= (IDirect3DDeviceGLImpl
*) This
;
648 /* Puts GL in the correct lighting / transformation mode */
649 if ((vertex_transformed
== FALSE
) &&
650 (glThis
->transform_state
!= GL_TRANSFORM_NORMAL
)) {
651 /* Need to put the correct transformation again if we go from Transformed
652 vertices to non-transformed ones.
654 This
->set_matrices(This
, VIEWMAT_CHANGED
|WORLDMAT_CHANGED
|PROJMAT_CHANGED
,
655 This
->world_mat
, This
->view_mat
, This
->proj_mat
);
656 glThis
->transform_state
= GL_TRANSFORM_NORMAL
;
658 if (glThis
->render_state
.fog_on
== TRUE
)
660 } else if ((vertex_transformed
== TRUE
) &&
661 (glThis
->transform_state
!= GL_TRANSFORM_ORTHO
)) {
662 GLfloat height
, width
;
663 GLfloat trans_mat
[16];
665 glThis
->transform_state
= GL_TRANSFORM_ORTHO
;
667 width
= glThis
->parent
.surface
->surface_desc
.dwWidth
;
668 height
= glThis
->parent
.surface
->surface_desc
.dwHeight
;
670 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
671 to OpenGL screen coordinates (ie the upper left corner is not the same).
672 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
673 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
674 trans_mat
[ 0] = 2.0 / width
; trans_mat
[ 4] = 0.0; trans_mat
[ 8] = 0.0; trans_mat
[12] = -1.0;
675 trans_mat
[ 1] = 0.0; trans_mat
[ 5] = -2.0 / height
; trans_mat
[ 9] = 0.0; trans_mat
[13] = 1.0;
676 trans_mat
[ 2] = 0.0; trans_mat
[ 6] = 0.0; trans_mat
[10] = 1.0; trans_mat
[14] = -1.0;
677 trans_mat
[ 3] = 0.0; trans_mat
[ 7] = 0.0; trans_mat
[11] = 0.0; trans_mat
[15] = 1.0;
679 glMatrixMode(GL_MODELVIEW
);
681 glMatrixMode(GL_PROJECTION
);
682 glLoadMatrixf(trans_mat
);
684 /* Remove also fogging... */
688 /* Handle the 'no-normal' case */
689 if (vertex_lit
== FALSE
)
690 glDisable(GL_LIGHTING
);
691 else if (glThis
->render_state
.lighting_enable
== TRUE
)
692 glEnable(GL_LIGHTING
);
694 /* Handle the code for pre-vertex material properties */
695 if (vertex_transformed
== FALSE
) {
696 if (glThis
->render_state
.lighting_enable
== TRUE
) {
697 if ((glThis
->render_state
.color_diffuse
!= D3DMCS_MATERIAL
) ||
698 (glThis
->render_state
.color_specular
!= D3DMCS_MATERIAL
) ||
699 (glThis
->render_state
.color_ambient
!= D3DMCS_MATERIAL
) ||
700 (glThis
->render_state
.color_emissive
!= D3DMCS_MATERIAL
)) {
701 glEnable(GL_COLOR_MATERIAL
);
708 inline static void draw_primitive(IDirect3DDeviceImpl
*This
, DWORD maxvert
, WORD
*index
,
709 D3DVERTEXTYPE d3dvt
, D3DPRIMITIVETYPE d3dpt
, void *lpvertex
)
711 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
715 strided
.position
.lpvData
= &((D3DVERTEX
*) lpvertex
)->u1
.x
;
716 strided
.position
.dwStride
= sizeof(D3DVERTEX
);
717 strided
.normal
.lpvData
= &((D3DVERTEX
*) lpvertex
)->u4
.nx
;
718 strided
.normal
.dwStride
= sizeof(D3DVERTEX
);
719 strided
.textureCoords
[0].lpvData
= &((D3DVERTEX
*) lpvertex
)->u7
.tu
;
720 strided
.textureCoords
[0].dwStride
= sizeof(D3DVERTEX
);
721 draw_primitive_strided(This
, d3dpt
, D3DFVF_VERTEX
, &strided
, 0, 0 /* Unused */, index
, maxvert
, 0 /* Unused */);
724 case D3DVT_LVERTEX
: {
725 strided
.position
.lpvData
= &((D3DLVERTEX
*) lpvertex
)->u1
.x
;
726 strided
.position
.dwStride
= sizeof(D3DLVERTEX
);
727 strided
.diffuse
.lpvData
= &((D3DLVERTEX
*) lpvertex
)->u4
.color
;
728 strided
.diffuse
.dwStride
= sizeof(D3DLVERTEX
);
729 strided
.specular
.lpvData
= &((D3DLVERTEX
*) lpvertex
)->u5
.specular
;
730 strided
.specular
.dwStride
= sizeof(D3DLVERTEX
);
731 strided
.textureCoords
[0].lpvData
= &((D3DLVERTEX
*) lpvertex
)->u6
.tu
;
732 strided
.textureCoords
[0].dwStride
= sizeof(D3DLVERTEX
);
733 draw_primitive_strided(This
, d3dpt
, D3DFVF_LVERTEX
, &strided
, 0, 0 /* Unused */, index
, maxvert
, 0 /* Unused */);
736 case D3DVT_TLVERTEX
: {
737 strided
.position
.lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u1
.sx
;
738 strided
.position
.dwStride
= sizeof(D3DTLVERTEX
);
739 strided
.diffuse
.lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u5
.color
;
740 strided
.diffuse
.dwStride
= sizeof(D3DTLVERTEX
);
741 strided
.specular
.lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u6
.specular
;
742 strided
.specular
.dwStride
= sizeof(D3DTLVERTEX
);
743 strided
.textureCoords
[0].lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u7
.tu
;
744 strided
.textureCoords
[0].dwStride
= sizeof(D3DTLVERTEX
);
745 draw_primitive_strided(This
, d3dpt
, D3DFVF_TLVERTEX
, &strided
, 0, 0 /* Unused */, index
, maxvert
, 0 /* Unused */);
749 FIXME("Unhandled vertex type\n");
755 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface
,
756 D3DPRIMITIVETYPE d3dptPrimitiveType
,
757 D3DVERTEXTYPE d3dvtVertexType
,
762 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
764 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwFlags
);
765 if (TRACE_ON(ddraw
)) {
766 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
769 draw_primitive(This
, dwVertexCount
, NULL
, d3dvtVertexType
, d3dptPrimitiveType
, lpvVertices
);
775 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface
,
776 D3DPRIMITIVETYPE d3dptPrimitiveType
,
777 D3DVERTEXTYPE d3dvtVertexType
,
784 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
785 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwIndices
, dwIndexCount
, dwFlags
);
786 if (TRACE_ON(ddraw
)) {
787 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
790 draw_primitive(This
, dwIndexCount
, dwIndices
, d3dvtVertexType
, d3dptPrimitiveType
, lpvVertices
);
796 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface
,
797 LPD3DEXECUTEBUFFERDESC lpDesc
,
798 LPDIRECT3DEXECUTEBUFFER
* lplpDirect3DExecuteBuffer
,
801 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
802 IDirect3DExecuteBufferImpl
*ret
;
805 TRACE("(%p/%p)->(%p,%p,%p)\n", This
, iface
, lpDesc
, lplpDirect3DExecuteBuffer
, pUnkOuter
);
807 ret_value
= d3dexecutebuffer_create(&ret
, This
->d3d
, This
, lpDesc
);
808 *lplpDirect3DExecuteBuffer
= ICOM_INTERFACE(ret
, IDirect3DExecuteBuffer
);
810 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer
);
815 /* These are the various handler used in the generic path */
816 inline static void handle_xyz(D3DVALUE
*coords
) {
819 inline static void handle_xyzrhw(D3DVALUE
*coords
) {
820 if (coords
[3] < 1e-8)
823 GLfloat w
= 1.0 / coords
[3];
825 glVertex4f(coords
[0] * w
,
831 inline static void handle_normal(D3DVALUE
*coords
) {
835 inline static void handle_diffuse_base(RenderState
*rs
, DWORD
*color
) {
836 if (rs
->alpha_blend_enable
== TRUE
) {
837 glColor4ub((*color
>> 16) & 0xFF,
838 (*color
>> 8) & 0xFF,
839 (*color
>> 0) & 0xFF,
840 (*color
>> 24) & 0xFF);
842 glColor3ub((*color
>> 16) & 0xFF,
843 (*color
>> 8) & 0xFF,
844 (*color
>> 0) & 0xFF);
848 inline static void handle_specular_base(RenderState
*rs
, DWORD
*color
) {
849 glColor4ub((*color
>> 16) & 0xFF,
850 (*color
>> 8) & 0xFF,
851 (*color
>> 0) & 0xFF,
852 (*color
>> 24) & 0xFF); /* No idea if the alpha field is really used.. */
855 inline static void handle_diffuse(RenderState
*rs
, DWORD
*color
) {
856 if (rs
->lighting_enable
== TRUE
) {
857 if (rs
->color_diffuse
== D3DMCS_COLOR1
) {
858 glColorMaterial(GL_FRONT_AND_BACK
, GL_DIFFUSE
);
859 handle_diffuse_base(rs
, color
);
861 if (rs
->color_ambient
== D3DMCS_COLOR1
) {
862 glColorMaterial(GL_FRONT_AND_BACK
, GL_AMBIENT
);
863 handle_diffuse_base(rs
, color
);
865 if ((rs
->color_specular
== D3DMCS_COLOR1
) && (rs
->specular_enable
== TRUE
)) {
866 glColorMaterial(GL_FRONT_AND_BACK
, GL_SPECULAR
);
867 handle_diffuse_base(rs
, color
);
869 if (rs
->color_emissive
== D3DMCS_COLOR1
) {
870 glColorMaterial(GL_FRONT_AND_BACK
, GL_EMISSION
);
871 handle_diffuse_base(rs
, color
);
874 handle_diffuse_base(rs
, color
);
878 inline static void handle_specular(RenderState
*rs
, DWORD
*color
) {
879 if (rs
->lighting_enable
== TRUE
) {
880 if (rs
->color_diffuse
== D3DMCS_COLOR2
) {
881 glColorMaterial(GL_FRONT_AND_BACK
, GL_DIFFUSE
);
882 handle_specular(rs
, color
);
884 if (rs
->color_ambient
== D3DMCS_COLOR2
) {
885 glColorMaterial(GL_FRONT_AND_BACK
, GL_AMBIENT
);
886 handle_specular(rs
, color
);
888 if ((rs
->color_specular
== D3DMCS_COLOR2
) && (rs
->specular_enable
== TRUE
)) {
889 glColorMaterial(GL_FRONT_AND_BACK
, GL_SPECULAR
);
890 handle_specular(rs
, color
);
892 if (rs
->color_emissive
== D3DMCS_COLOR2
) {
893 glColorMaterial(GL_FRONT_AND_BACK
, GL_EMISSION
);
894 handle_specular(rs
, color
);
897 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
900 inline static void handle_diffuse_and_specular(RenderState
*rs
, DWORD
*color_d
, DWORD
*color_s
, BOOLEAN transformed
) {
901 if (transformed
== TRUE
) {
902 if (rs
->fog_on
== TRUE
) {
903 /* Special case where the specular value is used to do fogging. TODO */
905 if (rs
->specular_enable
== TRUE
) {
906 /* Standard specular value in transformed mode. TODO */
908 handle_diffuse_base(rs
, color_d
);
910 if (rs
->lighting_enable
== TRUE
) {
911 handle_diffuse(rs
, color_d
);
912 handle_specular(rs
, color_s
);
914 /* In that case, only put the diffuse color... */
915 handle_diffuse_base(rs
, color_d
);
920 inline static void handle_texture(D3DVALUE
*coords
) {
921 glTexCoord2fv(coords
);
923 inline static void handle_textures(D3DVALUE
*coords
, int tex_index
) {
924 /* For the moment, draw only the first texture.. */
925 if (tex_index
== 0) glTexCoord2fv(coords
);
928 static void draw_primitive_strided(IDirect3DDeviceImpl
*This
,
929 D3DPRIMITIVETYPE d3dptPrimitiveType
,
930 DWORD d3dvtVertexType
,
931 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData
,
938 IDirect3DDeviceGLImpl
* glThis
= (IDirect3DDeviceGLImpl
*) This
;
939 if (TRACE_ON(ddraw
)) {
940 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType
);
944 draw_primitive_handle_GL_state(This
,
945 (d3dvtVertexType
& D3DFVF_POSITION_MASK
) != D3DFVF_XYZ
,
946 (d3dvtVertexType
& D3DFVF_NORMAL
) == 0);
947 draw_primitive_start_GL(d3dptPrimitiveType
);
949 /* Some fast paths first before the generic case.... */
950 if (d3dvtVertexType
== D3DFVF_VERTEX
) {
953 for (index
= 0; index
< dwIndexCount
; index
++) {
954 int i
= (dwIndices
== NULL
) ? index
: dwIndices
[index
];
956 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->normal
.lpvData
) + i
* lpD3DDrawPrimStrideData
->normal
.dwStride
);
957 D3DVALUE
*tex_coord
=
958 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[0].lpvData
) + i
* lpD3DDrawPrimStrideData
->textureCoords
[0].dwStride
);
960 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
962 handle_normal(normal
);
963 handle_texture(tex_coord
);
964 handle_xyz(position
);
966 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
967 position
[0], position
[1], position
[2],
968 normal
[0], normal
[1], normal
[2],
969 tex_coord
[0], tex_coord
[1]);
971 } else if (d3dvtVertexType
== D3DFVF_TLVERTEX
) {
974 for (index
= 0; index
< dwIndexCount
; index
++) {
975 int i
= (dwIndices
== NULL
) ? index
: dwIndices
[index
];
977 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
979 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
980 D3DVALUE
*tex_coord
=
981 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[0].lpvData
) + i
* lpD3DDrawPrimStrideData
->textureCoords
[0].dwStride
);
983 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
985 handle_diffuse_and_specular(&(glThis
->render_state
), color_d
, color_s
, TRUE
);
986 handle_texture(tex_coord
);
987 handle_xyzrhw(position
);
989 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
990 position
[0], position
[1], position
[2], position
[3],
991 (*color_d
>> 16) & 0xFF,
992 (*color_d
>> 8) & 0xFF,
993 (*color_d
>> 0) & 0xFF,
994 (*color_d
>> 24) & 0xFF,
995 (*color_s
>> 16) & 0xFF,
996 (*color_s
>> 8) & 0xFF,
997 (*color_s
>> 0) & 0xFF,
998 (*color_s
>> 24) & 0xFF,
999 tex_coord
[0], tex_coord
[1]);
1001 } else if (((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) ||
1002 ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
)) {
1003 /* This is the 'slow path' but that should support all possible vertex formats out there...
1004 Note that people should write a fast path for all vertex formats out there...
1007 for (index
= 0; index
< dwIndexCount
; index
++) {
1008 int i
= (dwIndices
== NULL
) ? index
: dwIndices
[index
];
1010 if (d3dvtVertexType
& D3DFVF_NORMAL
) {
1012 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->normal
.lpvData
) + i
* lpD3DDrawPrimStrideData
->normal
.dwStride
);
1013 handle_normal(normal
);
1015 if ((d3dvtVertexType
& (D3DFVF_DIFFUSE
|D3DFVF_SPECULAR
)) == (D3DFVF_DIFFUSE
|D3DFVF_SPECULAR
)) {
1017 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
1019 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
1020 handle_diffuse_and_specular(&(glThis
->render_state
), color_d
, color_s
, (d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
);
1022 if (d3dvtVertexType
& D3DFVF_SPECULAR
) {
1024 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
1025 handle_specular(&(glThis
->render_state
), color_s
);
1026 } else if (d3dvtVertexType
& D3DFVF_DIFFUSE
) {
1028 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
1029 handle_diffuse(&(glThis
->render_state
), color_d
);
1033 if (((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
) == 1) {
1034 /* Special case for single texture... */
1035 D3DVALUE
*tex_coord
=
1036 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[0].lpvData
) + i
* lpD3DDrawPrimStrideData
->textureCoords
[0].dwStride
);
1037 handle_texture(tex_coord
);
1040 for (tex_index
= 0; tex_index
< ((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); tex_index
++) {
1041 D3DVALUE
*tex_coord
=
1042 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].lpvData
) +
1043 i
* lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].dwStride
);
1044 handle_textures(tex_coord
, tex_index
);
1047 if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) {
1048 D3DVALUE
*position
=
1049 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1050 handle_xyz(position
);
1051 } else if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
) {
1052 D3DVALUE
*position
=
1053 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1054 handle_xyzrhw(position
);
1057 if (TRACE_ON(ddraw
)) {
1060 if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) {
1061 D3DVALUE
*position
=
1062 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1063 TRACE(" %f %f %f", position
[0], position
[1], position
[2]);
1064 } else if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
) {
1065 D3DVALUE
*position
=
1066 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1067 TRACE(" %f %f %f %f", position
[0], position
[1], position
[2], position
[3]);
1069 if (d3dvtVertexType
& D3DFVF_NORMAL
) {
1071 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->normal
.lpvData
) + i
* lpD3DDrawPrimStrideData
->normal
.dwStride
);
1072 DPRINTF(" / %f %f %f", normal
[0], normal
[1], normal
[2]);
1074 if (d3dvtVertexType
& D3DFVF_DIFFUSE
) {
1076 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
1077 DPRINTF(" / %02lx %02lx %02lx %02lx",
1078 (*color_d
>> 16) & 0xFF,
1079 (*color_d
>> 8) & 0xFF,
1080 (*color_d
>> 0) & 0xFF,
1081 (*color_d
>> 24) & 0xFF);
1083 if (d3dvtVertexType
& D3DFVF_SPECULAR
) {
1085 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
1086 DPRINTF(" / %02lx %02lx %02lx %02lx",
1087 (*color_s
>> 16) & 0xFF,
1088 (*color_s
>> 8) & 0xFF,
1089 (*color_s
>> 0) & 0xFF,
1090 (*color_s
>> 24) & 0xFF);
1092 for (tex_index
= 0; tex_index
< ((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); tex_index
++) {
1093 D3DVALUE
*tex_coord
=
1094 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].lpvData
) +
1095 i
* lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].dwStride
);
1096 DPRINTF(" / %f %f", tex_coord
[0], tex_coord
[1]);
1102 ERR(" matrix weighting not handled yet....\n");
1107 /* Whatever the case, disable the color material stuff */
1108 glDisable(GL_COLOR_MATERIAL
);
1115 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface
,
1116 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1117 DWORD d3dvtVertexType
,
1119 DWORD dwVertexCount
,
1122 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1123 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
1125 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwFlags
);
1126 if (TRACE_ON(ddraw
)) {
1127 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
1130 convert_FVF_to_strided_data(d3dvtVertexType
, lpvVertices
, &strided
);
1131 draw_primitive_strided(This
, d3dptPrimitiveType
, d3dvtVertexType
, &strided
, 0, dwVertexCount
, NULL
, dwVertexCount
, dwFlags
);
1137 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface
,
1138 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1139 DWORD d3dvtVertexType
,
1141 DWORD dwVertexCount
,
1146 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1147 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
1149 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwIndices
, dwIndexCount
, dwFlags
);
1150 if (TRACE_ON(ddraw
)) {
1151 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
1154 convert_FVF_to_strided_data(d3dvtVertexType
, lpvVertices
, &strided
);
1155 draw_primitive_strided(This
, d3dptPrimitiveType
, d3dvtVertexType
, &strided
, 0, dwVertexCount
, dwIndices
, dwIndexCount
, dwFlags
);
1161 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface
,
1162 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1164 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData
,
1165 DWORD dwVertexCount
,
1168 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1170 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, dwVertexCount
, dwFlags
);
1171 if (TRACE_ON(ddraw
)) {
1172 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
1174 draw_primitive_strided(This
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, 0, dwVertexCount
, NULL
, dwVertexCount
, dwFlags
);
1180 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface
,
1181 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1183 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData
,
1184 DWORD dwVertexCount
,
1189 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1191 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, dwVertexCount
, lpIndex
, dwIndexCount
, dwFlags
);
1192 if (TRACE_ON(ddraw
)) {
1193 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
1196 draw_primitive_strided(This
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, 0, dwVertexCount
, lpIndex
, dwIndexCount
, dwFlags
);
1202 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface
,
1203 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1204 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf
,
1205 DWORD dwStartVertex
,
1206 DWORD dwNumVertices
,
1209 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1210 IDirect3DVertexBufferImpl
*vb_impl
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, lpD3DVertexBuf
);
1211 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
1213 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, lpD3DVertexBuf
, dwStartVertex
, dwNumVertices
, dwFlags
);
1214 if (TRACE_ON(ddraw
)) {
1215 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
1218 if (vb_impl
->processed
== TRUE
) {
1219 IDirect3DVertexBufferGLImpl
*vb_glimp
= (IDirect3DVertexBufferGLImpl
*) vb_impl
;
1220 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
1222 glThis
->transform_state
= GL_TRANSFORM_VERTEXBUFFER
;
1223 This
->set_matrices(This
, VIEWMAT_CHANGED
|WORLDMAT_CHANGED
|PROJMAT_CHANGED
,
1224 &(vb_glimp
->world_mat
), &(vb_glimp
->view_mat
), &(vb_glimp
->proj_mat
));
1226 convert_FVF_to_strided_data(vb_glimp
->dwVertexTypeDesc
, vb_glimp
->vertices
, &strided
);
1227 draw_primitive_strided(This
, d3dptPrimitiveType
, vb_glimp
->dwVertexTypeDesc
, &strided
, dwStartVertex
, dwNumVertices
, NULL
, dwNumVertices
, dwFlags
);
1230 convert_FVF_to_strided_data(vb_impl
->desc
.dwFVF
, vb_impl
->vertices
, &strided
);
1231 draw_primitive_strided(This
, d3dptPrimitiveType
, vb_impl
->desc
.dwFVF
, &strided
, dwStartVertex
, dwNumVertices
, NULL
, dwNumVertices
, dwFlags
);
1238 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface
,
1239 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1240 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf
,
1241 DWORD dwStartVertex
,
1242 DWORD dwNumVertices
,
1247 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1248 IDirect3DVertexBufferImpl
*vb_impl
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, lpD3DVertexBuf
);
1249 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
1251 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, lpD3DVertexBuf
, dwStartVertex
, dwNumVertices
, lpwIndices
, dwIndexCount
, dwFlags
);
1252 if (TRACE_ON(ddraw
)) {
1253 TRACE(" - flags : "); dump_DPFLAGS(dwFlags
);
1256 if (vb_impl
->processed
== TRUE
) {
1257 IDirect3DVertexBufferGLImpl
*vb_glimp
= (IDirect3DVertexBufferGLImpl
*) vb_impl
;
1258 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
1260 glThis
->transform_state
= GL_TRANSFORM_VERTEXBUFFER
;
1261 This
->set_matrices(This
, VIEWMAT_CHANGED
|WORLDMAT_CHANGED
|PROJMAT_CHANGED
,
1262 &(vb_glimp
->world_mat
), &(vb_glimp
->view_mat
), &(vb_glimp
->proj_mat
));
1264 convert_FVF_to_strided_data(vb_glimp
->dwVertexTypeDesc
, vb_glimp
->vertices
, &strided
);
1265 draw_primitive_strided(This
, d3dptPrimitiveType
, vb_glimp
->dwVertexTypeDesc
, &strided
, dwStartVertex
, dwNumVertices
, lpwIndices
, dwIndexCount
, dwFlags
);
1268 convert_FVF_to_strided_data(vb_impl
->desc
.dwFVF
, vb_impl
->vertices
, &strided
);
1269 draw_primitive_strided(This
, d3dptPrimitiveType
, vb_impl
->desc
.dwFVF
, &strided
, dwStartVertex
, dwNumVertices
, lpwIndices
, dwIndexCount
, dwFlags
);
1276 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface
,
1278 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType
,
1281 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1282 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
1285 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This
, iface
, dwStage
, d3dTexStageStateType
, dwState
);
1287 if (TRACE_ON(ddraw
)) {
1288 TRACE(" Stage type is : ");
1289 switch (d3dTexStageStateType
) {
1290 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1291 GEN_CASE(D3DTSS_COLOROP
);
1292 GEN_CASE(D3DTSS_COLORARG1
);
1293 GEN_CASE(D3DTSS_COLORARG2
);
1294 GEN_CASE(D3DTSS_ALPHAOP
);
1295 GEN_CASE(D3DTSS_ALPHAARG1
);
1296 GEN_CASE(D3DTSS_ALPHAARG2
);
1297 GEN_CASE(D3DTSS_BUMPENVMAT00
);
1298 GEN_CASE(D3DTSS_BUMPENVMAT01
);
1299 GEN_CASE(D3DTSS_BUMPENVMAT10
);
1300 GEN_CASE(D3DTSS_BUMPENVMAT11
);
1301 GEN_CASE(D3DTSS_TEXCOORDINDEX
);
1302 GEN_CASE(D3DTSS_ADDRESS
);
1303 GEN_CASE(D3DTSS_ADDRESSU
);
1304 GEN_CASE(D3DTSS_ADDRESSV
);
1305 GEN_CASE(D3DTSS_BORDERCOLOR
);
1306 GEN_CASE(D3DTSS_MAGFILTER
);
1307 GEN_CASE(D3DTSS_MINFILTER
);
1308 GEN_CASE(D3DTSS_MIPFILTER
);
1309 GEN_CASE(D3DTSS_MIPMAPLODBIAS
);
1310 GEN_CASE(D3DTSS_MAXMIPLEVEL
);
1311 GEN_CASE(D3DTSS_MAXANISOTROPY
);
1312 GEN_CASE(D3DTSS_BUMPENVLSCALE
);
1313 GEN_CASE(D3DTSS_BUMPENVLOFFSET
);
1314 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS
);
1316 default: DPRINTF("UNKNOWN !!!");
1321 switch (d3dTexStageStateType
) {
1322 case D3DTSS_MINFILTER
:
1323 switch ((D3DTEXTUREMINFILTER
) dwState
) {
1325 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFN_POINT\n");
1326 gl_state
= GL_NEAREST
;
1329 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFN_LINEAR\n");
1330 gl_state
= GL_LINEAR
;
1333 if (TRACE_ON(ddraw
)) DPRINTF(" state unhandled (%ld).\n", dwState
);
1334 gl_state
= GL_LINEAR
;
1337 glThis
->render_state
.min
= gl_state
;
1338 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, gl_state
);
1341 case D3DTSS_MAGFILTER
:
1342 switch ((D3DTEXTUREMAGFILTER
) dwState
) {
1344 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFG_POINT\n");
1345 gl_state
= GL_NEAREST
;
1348 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFG_LINEAR\n");
1349 gl_state
= GL_LINEAR
;
1352 if (TRACE_ON(ddraw
)) DPRINTF(" state unhandled (%ld).\n", dwState
);
1353 gl_state
= GL_LINEAR
;
1356 glThis
->render_state
.mag
= gl_state
;
1357 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, gl_state
);
1360 case D3DTSS_ADDRESS
:
1361 case D3DTSS_ADDRESSU
:
1362 case D3DTSS_ADDRESSV
: {
1363 GLenum arg
= GL_REPEAT
; /* Default value */
1364 switch ((D3DTEXTUREADDRESS
) dwState
) {
1365 case D3DTADDRESS_WRAP
: if (TRACE_ON(ddraw
)) DPRINTF("D3DTADDRESS_WRAP\n"); arg
= GL_REPEAT
; break;
1366 case D3DTADDRESS_CLAMP
: if (TRACE_ON(ddraw
)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg
= GL_CLAMP
; break;
1367 case D3DTADDRESS_BORDER
: if (TRACE_ON(ddraw
)) DPRINTF("D3DTADDRESS_BORDER\n"); arg
= GL_CLAMP_TO_EDGE
; break;
1368 default: DPRINTF(" state unhandled (%ld).\n", dwState
);
1370 if ((d3dTexStageStateType
== D3DTSS_ADDRESS
) ||
1371 (d3dTexStageStateType
== D3DTSS_ADDRESSU
))
1372 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, arg
);
1373 if ((d3dTexStageStateType
== D3DTSS_ADDRESS
) ||
1374 (d3dTexStageStateType
== D3DTSS_ADDRESSV
))
1375 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, arg
);
1379 if (TRACE_ON(ddraw
)) DPRINTF(" unhandled.\n");
1382 This
->state_block
.texture_stage_state
[dwStage
][d3dTexStageStateType
-1] = dwState
;
1388 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface
,
1390 LPDIRECTDRAWSURFACE7 lpTexture2
)
1392 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1393 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
1395 TRACE("(%p/%p)->(%08lx,%p)\n", This
, iface
, dwStage
, lpTexture2
);
1397 if (This
->current_texture
[dwStage
] != NULL
) {
1398 /* Seems that this is not right... Need to test in real Windows
1399 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1403 if (lpTexture2
== NULL
) {
1404 TRACE(" disabling 2D texturing.\n");
1405 glBindTexture(GL_TEXTURE_2D
, 0);
1406 glDisable(GL_TEXTURE_2D
);
1408 IDirectDrawSurfaceImpl
*tex_impl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, lpTexture2
);
1409 IDirect3DTextureGLImpl
*tex_glimpl
= (IDirect3DTextureGLImpl
*) tex_impl
->tex_private
;
1411 This
->current_texture
[dwStage
] = tex_impl
;
1412 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl
, IDirectDrawSurface7
)); /* Not sure about this either */
1414 TRACE(" activating OpenGL texture %d.\n", tex_glimpl
->tex_name
);
1416 glEnable(GL_TEXTURE_2D
);
1417 glBindTexture(GL_TEXTURE_2D
, tex_glimpl
->tex_name
);
1418 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, glThis
->render_state
.mag
);
1419 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, glThis
->render_state
.min
);
1427 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface
,
1428 LPD3DDEVICEDESC7 lpD3DHELDevDesc
)
1430 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1431 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpD3DHELDevDesc
);
1433 fill_opengl_caps_7(lpD3DHELDevDesc
);
1435 TRACE(" returning caps : no dump function yet.\n");
1441 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface
,
1442 LPD3DMATERIAL7 lpMat
)
1444 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1445 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpMat
);
1447 if (TRACE_ON(ddraw
)) {
1448 TRACE(" material is : \n");
1449 dump_D3DMATERIAL7(lpMat
);
1452 This
->current_material
= *lpMat
;
1454 glMaterialfv(GL_FRONT_AND_BACK
,
1456 (float *) &(This
->current_material
.u
.diffuse
));
1457 glMaterialfv(GL_FRONT_AND_BACK
,
1459 (float *) &(This
->current_material
.u1
.ambient
));
1460 glMaterialfv(GL_FRONT_AND_BACK
,
1462 (float *) &(This
->current_material
.u2
.specular
));
1463 glMaterialfv(GL_FRONT_AND_BACK
,
1465 (float *) &(This
->current_material
.u3
.emissive
));
1466 glMaterialf(GL_FRONT_AND_BACK
,
1468 This
->current_material
.u4
.power
); /* Not sure about this... */
1475 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface
,
1477 LPD3DLIGHT7 lpLight
)
1479 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1480 TRACE("(%p/%p)->(%08lx,%p)\n", This
, iface
, dwLightIndex
, lpLight
);
1482 if (TRACE_ON(ddraw
)) {
1483 TRACE(" setting light : \n");
1484 dump_D3DLIGHT7(lpLight
);
1487 if (dwLightIndex
> MAX_LIGHTS
) return DDERR_INVALIDPARAMS
;
1488 This
->set_lights
|= 0x00000001 << dwLightIndex
;
1489 This
->light_parameters
[dwLightIndex
] = *lpLight
;
1491 switch (lpLight
->dltType
) {
1492 case D3DLIGHT_DIRECTIONAL
: {
1494 float cut_off
= 180.0;
1496 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_AMBIENT
, (float *) &(lpLight
->dcvAmbient
));
1497 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_DIFFUSE
, (float *) &(lpLight
->dcvDiffuse
));
1498 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPECULAR
, (float *) &(lpLight
->dcvSpecular
));
1499 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPOT_CUTOFF
, &cut_off
);
1501 direction
[0] = lpLight
->dvDirection
.u1
.x
;
1502 direction
[1] = lpLight
->dvDirection
.u2
.y
;
1503 direction
[2] = lpLight
->dvDirection
.u3
.z
;
1505 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_POSITION
, (float *) direction
);
1508 case D3DLIGHT_POINT
: {
1510 float cut_off
= 180.0;
1512 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_AMBIENT
, (float *) &(lpLight
->dcvAmbient
));
1513 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_DIFFUSE
, (float *) &(lpLight
->dcvDiffuse
));
1514 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPECULAR
, (float *) &(lpLight
->dcvSpecular
));
1515 position
[0] = lpLight
->dvPosition
.u1
.x
;
1516 position
[1] = lpLight
->dvPosition
.u2
.y
;
1517 position
[2] = lpLight
->dvPosition
.u3
.z
;
1519 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_POSITION
, (float *) position
);
1520 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_CONSTANT_ATTENUATION
, &(lpLight
->dvAttenuation0
));
1521 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_LINEAR_ATTENUATION
, &(lpLight
->dvAttenuation1
));
1522 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_QUADRATIC_ATTENUATION
, &(lpLight
->dvAttenuation2
));
1523 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPOT_CUTOFF
, &cut_off
);
1526 case D3DLIGHT_SPOT
: {
1529 float cut_off
= 90.0 * (lpLight
->dvPhi
/ M_PI
);
1531 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_AMBIENT
, (float *) &(lpLight
->dcvAmbient
));
1532 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_DIFFUSE
, (float *) &(lpLight
->dcvDiffuse
));
1533 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPECULAR
, (float *) &(lpLight
->dcvSpecular
));
1535 direction
[0] = lpLight
->dvDirection
.u1
.x
;
1536 direction
[1] = lpLight
->dvDirection
.u2
.y
;
1537 direction
[2] = lpLight
->dvDirection
.u3
.z
;
1539 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPOT_DIRECTION
, (float *) direction
);
1540 position
[0] = lpLight
->dvPosition
.u1
.x
;
1541 position
[1] = lpLight
->dvPosition
.u2
.y
;
1542 position
[2] = lpLight
->dvPosition
.u3
.z
;
1544 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_POSITION
, (float *) position
);
1545 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_CONSTANT_ATTENUATION
, &(lpLight
->dvAttenuation0
));
1546 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_LINEAR_ATTENUATION
, &(lpLight
->dvAttenuation1
));
1547 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_QUADRATIC_ATTENUATION
, &(lpLight
->dvAttenuation2
));
1548 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPOT_CUTOFF
, &cut_off
);
1549 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPOT_EXPONENT
, &(lpLight
->dvFalloff
));
1550 if ((lpLight
->dvTheta
!= 0.0) || (lpLight
->dvTheta
!= lpLight
->dvPhi
)) {
1551 WARN("dvTheta not fully supported yet !\n");
1555 default: WARN(" light type not handled yet...\n");
1562 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface
,
1566 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1567 TRACE("(%p/%p)->(%08lx,%d)\n", This
, iface
, dwLightIndex
, bEnable
);
1569 if (dwLightIndex
> MAX_LIGHTS
) return DDERR_INVALIDPARAMS
;
1572 if (((0x00000001 << dwLightIndex
) & This
->set_lights
) == 0) {
1573 /* Set the default parameters.. */
1574 TRACE(" setting default light parameters...\n");
1575 GL_IDirect3DDeviceImpl_7_SetLight(iface
, dwLightIndex
, &(This
->light_parameters
[dwLightIndex
]));
1577 glEnable(GL_LIGHT0
+ dwLightIndex
);
1579 glDisable(GL_LIGHT0
+ dwLightIndex
);
1585 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1586 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1588 # define XCAST(fun) (void*)
1591 ICOM_VTABLE(IDirect3DDevice7
) VTABLE_IDirect3DDevice7
=
1593 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1594 XCAST(QueryInterface
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface
,
1595 XCAST(AddRef
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef
,
1596 XCAST(Release
) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release
,
1597 XCAST(GetCaps
) GL_IDirect3DDeviceImpl_7_GetCaps
,
1598 XCAST(EnumTextureFormats
) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats
,
1599 XCAST(BeginScene
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene
,
1600 XCAST(EndScene
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene
,
1601 XCAST(GetDirect3D
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D
,
1602 XCAST(SetRenderTarget
) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget
,
1603 XCAST(GetRenderTarget
) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget
,
1604 XCAST(Clear
) Main_IDirect3DDeviceImpl_7_Clear
,
1605 XCAST(SetTransform
) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform
,
1606 XCAST(GetTransform
) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform
,
1607 XCAST(SetViewport
) Main_IDirect3DDeviceImpl_7_SetViewport
,
1608 XCAST(MultiplyTransform
) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform
,
1609 XCAST(GetViewport
) Main_IDirect3DDeviceImpl_7_GetViewport
,
1610 XCAST(SetMaterial
) GL_IDirect3DDeviceImpl_7_SetMaterial
,
1611 XCAST(GetMaterial
) Main_IDirect3DDeviceImpl_7_GetMaterial
,
1612 XCAST(SetLight
) GL_IDirect3DDeviceImpl_7_SetLight
,
1613 XCAST(GetLight
) Main_IDirect3DDeviceImpl_7_GetLight
,
1614 XCAST(SetRenderState
) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState
,
1615 XCAST(GetRenderState
) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState
,
1616 XCAST(BeginStateBlock
) Main_IDirect3DDeviceImpl_7_BeginStateBlock
,
1617 XCAST(EndStateBlock
) Main_IDirect3DDeviceImpl_7_EndStateBlock
,
1618 XCAST(PreLoad
) Main_IDirect3DDeviceImpl_7_PreLoad
,
1619 XCAST(DrawPrimitive
) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive
,
1620 XCAST(DrawIndexedPrimitive
) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive
,
1621 XCAST(SetClipStatus
) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus
,
1622 XCAST(GetClipStatus
) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus
,
1623 XCAST(DrawPrimitiveStrided
) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided
,
1624 XCAST(DrawIndexedPrimitiveStrided
) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided
,
1625 XCAST(DrawPrimitiveVB
) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB
,
1626 XCAST(DrawIndexedPrimitiveVB
) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB
,
1627 XCAST(ComputeSphereVisibility
) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility
,
1628 XCAST(GetTexture
) Main_IDirect3DDeviceImpl_7_3T_GetTexture
,
1629 XCAST(SetTexture
) GL_IDirect3DDeviceImpl_7_3T_SetTexture
,
1630 XCAST(GetTextureStageState
) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState
,
1631 XCAST(SetTextureStageState
) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState
,
1632 XCAST(ValidateDevice
) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice
,
1633 XCAST(ApplyStateBlock
) Main_IDirect3DDeviceImpl_7_ApplyStateBlock
,
1634 XCAST(CaptureStateBlock
) Main_IDirect3DDeviceImpl_7_CaptureStateBlock
,
1635 XCAST(DeleteStateBlock
) Main_IDirect3DDeviceImpl_7_DeleteStateBlock
,
1636 XCAST(CreateStateBlock
) Main_IDirect3DDeviceImpl_7_CreateStateBlock
,
1637 XCAST(Load
) Main_IDirect3DDeviceImpl_7_Load
,
1638 XCAST(LightEnable
) GL_IDirect3DDeviceImpl_7_LightEnable
,
1639 XCAST(GetLightEnable
) Main_IDirect3DDeviceImpl_7_GetLightEnable
,
1640 XCAST(SetClipPlane
) Main_IDirect3DDeviceImpl_7_SetClipPlane
,
1641 XCAST(GetClipPlane
) Main_IDirect3DDeviceImpl_7_GetClipPlane
,
1642 XCAST(GetInfo
) Main_IDirect3DDeviceImpl_7_GetInfo
,
1645 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1650 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1651 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1653 # define XCAST(fun) (void*)
1656 ICOM_VTABLE(IDirect3DDevice3
) VTABLE_IDirect3DDevice3
=
1658 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1659 XCAST(QueryInterface
) Thunk_IDirect3DDeviceImpl_3_QueryInterface
,
1660 XCAST(AddRef
) Thunk_IDirect3DDeviceImpl_3_AddRef
,
1661 XCAST(Release
) Thunk_IDirect3DDeviceImpl_3_Release
,
1662 XCAST(GetCaps
) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps
,
1663 XCAST(GetStats
) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats
,
1664 XCAST(AddViewport
) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport
,
1665 XCAST(DeleteViewport
) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport
,
1666 XCAST(NextViewport
) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport
,
1667 XCAST(EnumTextureFormats
) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats
,
1668 XCAST(BeginScene
) Thunk_IDirect3DDeviceImpl_3_BeginScene
,
1669 XCAST(EndScene
) Thunk_IDirect3DDeviceImpl_3_EndScene
,
1670 XCAST(GetDirect3D
) Thunk_IDirect3DDeviceImpl_3_GetDirect3D
,
1671 XCAST(SetCurrentViewport
) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport
,
1672 XCAST(GetCurrentViewport
) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport
,
1673 XCAST(SetRenderTarget
) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget
,
1674 XCAST(GetRenderTarget
) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget
,
1675 XCAST(Begin
) Main_IDirect3DDeviceImpl_3_Begin
,
1676 XCAST(BeginIndexed
) Main_IDirect3DDeviceImpl_3_BeginIndexed
,
1677 XCAST(Vertex
) Main_IDirect3DDeviceImpl_3_2T_Vertex
,
1678 XCAST(Index
) Main_IDirect3DDeviceImpl_3_2T_Index
,
1679 XCAST(End
) Main_IDirect3DDeviceImpl_3_2T_End
,
1680 XCAST(GetRenderState
) Thunk_IDirect3DDeviceImpl_3_GetRenderState
,
1681 XCAST(SetRenderState
) Thunk_IDirect3DDeviceImpl_3_SetRenderState
,
1682 XCAST(GetLightState
) Main_IDirect3DDeviceImpl_3_2T_GetLightState
,
1683 XCAST(SetLightState
) GL_IDirect3DDeviceImpl_3_2T_SetLightState
,
1684 XCAST(SetTransform
) Thunk_IDirect3DDeviceImpl_3_SetTransform
,
1685 XCAST(GetTransform
) Thunk_IDirect3DDeviceImpl_3_GetTransform
,
1686 XCAST(MultiplyTransform
) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform
,
1687 XCAST(DrawPrimitive
) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive
,
1688 XCAST(DrawIndexedPrimitive
) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
1689 XCAST(SetClipStatus
) Thunk_IDirect3DDeviceImpl_3_SetClipStatus
,
1690 XCAST(GetClipStatus
) Thunk_IDirect3DDeviceImpl_3_GetClipStatus
,
1691 XCAST(DrawPrimitiveStrided
) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
1692 XCAST(DrawIndexedPrimitiveStrided
) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
1693 XCAST(DrawPrimitiveVB
) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
1694 XCAST(DrawIndexedPrimitiveVB
) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
1695 XCAST(ComputeSphereVisibility
) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
1696 XCAST(GetTexture
) Thunk_IDirect3DDeviceImpl_3_GetTexture
,
1697 XCAST(SetTexture
) Thunk_IDirect3DDeviceImpl_3_SetTexture
,
1698 XCAST(GetTextureStageState
) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState
,
1699 XCAST(SetTextureStageState
) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState
,
1700 XCAST(ValidateDevice
) Thunk_IDirect3DDeviceImpl_3_ValidateDevice
,
1703 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1708 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1709 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1711 # define XCAST(fun) (void*)
1714 ICOM_VTABLE(IDirect3DDevice2
) VTABLE_IDirect3DDevice2
=
1716 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1717 XCAST(QueryInterface
) Thunk_IDirect3DDeviceImpl_2_QueryInterface
,
1718 XCAST(AddRef
) Thunk_IDirect3DDeviceImpl_2_AddRef
,
1719 XCAST(Release
) Thunk_IDirect3DDeviceImpl_2_Release
,
1720 XCAST(GetCaps
) Thunk_IDirect3DDeviceImpl_2_GetCaps
,
1721 XCAST(SwapTextureHandles
) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles
,
1722 XCAST(GetStats
) Thunk_IDirect3DDeviceImpl_2_GetStats
,
1723 XCAST(AddViewport
) Thunk_IDirect3DDeviceImpl_2_AddViewport
,
1724 XCAST(DeleteViewport
) Thunk_IDirect3DDeviceImpl_2_DeleteViewport
,
1725 XCAST(NextViewport
) Thunk_IDirect3DDeviceImpl_2_NextViewport
,
1726 XCAST(EnumTextureFormats
) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats
,
1727 XCAST(BeginScene
) Thunk_IDirect3DDeviceImpl_2_BeginScene
,
1728 XCAST(EndScene
) Thunk_IDirect3DDeviceImpl_2_EndScene
,
1729 XCAST(GetDirect3D
) Thunk_IDirect3DDeviceImpl_2_GetDirect3D
,
1730 XCAST(SetCurrentViewport
) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport
,
1731 XCAST(GetCurrentViewport
) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport
,
1732 XCAST(SetRenderTarget
) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget
,
1733 XCAST(GetRenderTarget
) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget
,
1734 XCAST(Begin
) Main_IDirect3DDeviceImpl_2_Begin
,
1735 XCAST(BeginIndexed
) Main_IDirect3DDeviceImpl_2_BeginIndexed
,
1736 XCAST(Vertex
) Thunk_IDirect3DDeviceImpl_2_Vertex
,
1737 XCAST(Index
) Thunk_IDirect3DDeviceImpl_2_Index
,
1738 XCAST(End
) Thunk_IDirect3DDeviceImpl_2_End
,
1739 XCAST(GetRenderState
) Thunk_IDirect3DDeviceImpl_2_GetRenderState
,
1740 XCAST(SetRenderState
) Thunk_IDirect3DDeviceImpl_2_SetRenderState
,
1741 XCAST(GetLightState
) Thunk_IDirect3DDeviceImpl_2_GetLightState
,
1742 XCAST(SetLightState
) Thunk_IDirect3DDeviceImpl_2_SetLightState
,
1743 XCAST(SetTransform
) Thunk_IDirect3DDeviceImpl_2_SetTransform
,
1744 XCAST(GetTransform
) Thunk_IDirect3DDeviceImpl_2_GetTransform
,
1745 XCAST(MultiplyTransform
) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform
,
1746 XCAST(DrawPrimitive
) GL_IDirect3DDeviceImpl_2_DrawPrimitive
,
1747 XCAST(DrawIndexedPrimitive
) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
1748 XCAST(SetClipStatus
) Thunk_IDirect3DDeviceImpl_2_SetClipStatus
,
1749 XCAST(GetClipStatus
) Thunk_IDirect3DDeviceImpl_2_GetClipStatus
,
1752 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1757 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1758 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1760 # define XCAST(fun) (void*)
1763 ICOM_VTABLE(IDirect3DDevice
) VTABLE_IDirect3DDevice
=
1765 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1766 XCAST(QueryInterface
) Thunk_IDirect3DDeviceImpl_1_QueryInterface
,
1767 XCAST(AddRef
) Thunk_IDirect3DDeviceImpl_1_AddRef
,
1768 XCAST(Release
) Thunk_IDirect3DDeviceImpl_1_Release
,
1769 XCAST(Initialize
) Main_IDirect3DDeviceImpl_1_Initialize
,
1770 XCAST(GetCaps
) Thunk_IDirect3DDeviceImpl_1_GetCaps
,
1771 XCAST(SwapTextureHandles
) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles
,
1772 XCAST(CreateExecuteBuffer
) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
1773 XCAST(GetStats
) Thunk_IDirect3DDeviceImpl_1_GetStats
,
1774 XCAST(Execute
) Main_IDirect3DDeviceImpl_1_Execute
,
1775 XCAST(AddViewport
) Thunk_IDirect3DDeviceImpl_1_AddViewport
,
1776 XCAST(DeleteViewport
) Thunk_IDirect3DDeviceImpl_1_DeleteViewport
,
1777 XCAST(NextViewport
) Thunk_IDirect3DDeviceImpl_1_NextViewport
,
1778 XCAST(Pick
) Main_IDirect3DDeviceImpl_1_Pick
,
1779 XCAST(GetPickRecords
) Main_IDirect3DDeviceImpl_1_GetPickRecords
,
1780 XCAST(EnumTextureFormats
) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats
,
1781 XCAST(CreateMatrix
) Main_IDirect3DDeviceImpl_1_CreateMatrix
,
1782 XCAST(SetMatrix
) Main_IDirect3DDeviceImpl_1_SetMatrix
,
1783 XCAST(GetMatrix
) Main_IDirect3DDeviceImpl_1_GetMatrix
,
1784 XCAST(DeleteMatrix
) Main_IDirect3DDeviceImpl_1_DeleteMatrix
,
1785 XCAST(BeginScene
) Thunk_IDirect3DDeviceImpl_1_BeginScene
,
1786 XCAST(EndScene
) Thunk_IDirect3DDeviceImpl_1_EndScene
,
1787 XCAST(GetDirect3D
) Thunk_IDirect3DDeviceImpl_1_GetDirect3D
,
1790 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1794 static HRESULT
d3ddevice_clear(IDirect3DDeviceImpl
*This
,
1803 GLfloat old_z_clear_value
;
1804 GLbitfield bitfield
= 0;
1805 GLint old_stencil_clear_value
;
1806 GLfloat old_color_clear_value
[4];
1808 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This
, dwCount
, lpRects
, dwFlags
, dwColor
, dvZ
, dwStencil
);
1809 if (TRACE_ON(ddraw
)) {
1812 TRACE(" rectangles : \n");
1813 for (i
= 0; i
< dwCount
; i
++) {
1814 TRACE(" - %ld x %ld %ld x %ld\n", lpRects
[i
].u1
.x1
, lpRects
[i
].u2
.y1
, lpRects
[i
].u3
.x2
, lpRects
[i
].u4
.y2
);
1820 WARN(" Warning, this function only for now clears the whole screen...\n");
1823 /* Clears the screen */
1825 if (dwFlags
& D3DCLEAR_ZBUFFER
) {
1826 bitfield
|= GL_DEPTH_BUFFER_BIT
;
1827 glGetBooleanv(GL_DEPTH_WRITEMASK
, &ztest
);
1828 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
1829 glGetFloatv(GL_DEPTH_CLEAR_VALUE
, &old_z_clear_value
);
1831 TRACE(" depth value : %f\n", dvZ
);
1833 if (dwFlags
& D3DCLEAR_STENCIL
) {
1834 bitfield
|= GL_STENCIL_BUFFER_BIT
;
1835 glGetIntegerv(GL_STENCIL_CLEAR_VALUE
, &old_stencil_clear_value
);
1836 glClearStencil(dwStencil
);
1837 TRACE(" stencil value : %ld\n", dwStencil
);
1839 if (dwFlags
& D3DCLEAR_TARGET
) {
1840 bitfield
|= GL_COLOR_BUFFER_BIT
;
1841 glGetFloatv(GL_COLOR_CLEAR_VALUE
, old_color_clear_value
);
1842 glClearColor(((dwColor
>> 16) & 0xFF) / 255.0,
1843 ((dwColor
>> 8) & 0xFF) / 255.0,
1844 ((dwColor
>> 0) & 0xFF) / 255.0,
1845 ((dwColor
>> 24) & 0xFF) / 255.0);
1846 TRACE(" color value (ARGB) : %08lx\n", dwColor
);
1851 if (dwFlags
& D3DCLEAR_ZBUFFER
) {
1853 glClearDepth(old_z_clear_value
);
1855 if (dwFlags
& D3DCLEAR_STENCIL
) {
1856 bitfield
|= GL_STENCIL_BUFFER_BIT
;
1857 glClearStencil(old_stencil_clear_value
);
1859 if (dwFlags
& D3DCLEAR_TARGET
) {
1860 bitfield
|= GL_COLOR_BUFFER_BIT
;
1861 glClearColor(old_color_clear_value
[0],
1862 old_color_clear_value
[1],
1863 old_color_clear_value
[2],
1864 old_color_clear_value
[3]);
1873 d3ddevice_blt(IDirectDrawSurfaceImpl
*This
, LPRECT rdst
,
1874 LPDIRECTDRAWSURFACE7 src
, LPRECT rsrc
,
1875 DWORD dwFlags
, LPDDBLTFX lpbltfx
)
1877 if (dwFlags
& DDBLT_COLORFILL
) {
1878 /* This is easy to handle for the D3D Device... */
1879 DWORD color
= lpbltfx
->u5
.dwFillColor
;
1880 TRACE(" executing D3D Device override.\n");
1881 d3ddevice_clear(This
->d3ddevice
, 0, NULL
, D3DCLEAR_TARGET
, color
, 0.0, 0x00000000);
1884 return DDERR_INVALIDPARAMS
;
1888 d3ddevice_bltfast(IDirectDrawSurfaceImpl
*This
, DWORD dstx
,
1889 DWORD dsty
, LPDIRECTDRAWSURFACE7 src
,
1890 LPRECT rsrc
, DWORD trans
)
1892 return DDERR_INVALIDPARAMS
;
1896 d3ddevice_set_matrices(IDirect3DDeviceImpl
*This
, DWORD matrices
,
1897 D3DMATRIX
*world_mat
, D3DMATRIX
*view_mat
, D3DMATRIX
*proj_mat
)
1899 if ((matrices
& (VIEWMAT_CHANGED
|WORLDMAT_CHANGED
)) != 0) {
1900 glMatrixMode(GL_MODELVIEW
);
1901 glLoadMatrixf((float *) view_mat
);
1902 glMultMatrixf((float *) world_mat
);
1904 if ((matrices
& PROJMAT_CHANGED
) != 0) {
1905 glMatrixMode(GL_PROJECTION
);
1906 glLoadMatrixf((float *) proj_mat
);
1911 d3ddevice_matrices_updated(IDirect3DDeviceImpl
*This
, DWORD matrices
)
1913 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
1914 if (glThis
->transform_state
== GL_TRANSFORM_NORMAL
) {
1915 /* This will force an update of the transform state at the next drawing. */
1916 glThis
->transform_state
= GL_TRANSFORM_NONE
;
1920 /* TODO for both these functions :
1921 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1922 by other OpenGL code in D3D
1923 - handle the case where no 'Begin / EndScene' was done between two locks
1924 - handle the rectangles in the unlock too
1925 - handle pitch correctly...
1927 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl
* This
, LPCRECT pRect
, DWORD dwFlags
)
1929 /* First, check if we need to do anything */
1930 if ((This
->lastlocktype
& DDLOCK_WRITEONLY
) == 0) {
1937 glGetIntegerv(GL_READ_BUFFER
, &prev_read
);
1940 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1941 if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_FRONTBUFFER
|DDSCAPS_PRIMARYSURFACE
)) != 0) {
1942 /* Application wants to lock the front buffer */
1943 glReadBuffer(GL_FRONT
);
1944 } else if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_BACKBUFFER
)) == (DDSCAPS_BACKBUFFER
)) {
1945 /* Application wants to lock the back buffer */
1946 glReadBuffer(GL_BACK
);
1948 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1951 if (This
->surface_desc
.u4
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16) {
1952 buffer_type
= GL_UNSIGNED_SHORT_5_6_5
;
1954 WARN(" unsupported pixel format.\n");
1958 if (pRect
== NULL
) {
1961 loc_rect
.bottom
= This
->surface_desc
.dwHeight
;
1962 loc_rect
.right
= This
->surface_desc
.dwWidth
;
1966 glReadPixels(loc_rect
.left
, loc_rect
.top
, loc_rect
.right
, loc_rect
.bottom
,
1967 GL_RGB
, buffer_type
, ((char *)This
->surface_desc
.lpSurface
1968 + loc_rect
.top
* This
->surface_desc
.u1
.lPitch
1969 + loc_rect
.left
* GET_BPP(This
->surface_desc
)));
1970 glReadBuffer(prev_read
);
1975 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl
* This
, LPCRECT pRect
)
1977 /* First, check if we need to do anything */
1978 if ((This
->lastlocktype
& DDLOCK_READONLY
) == 0) {
1984 glGetIntegerv(GL_DRAW_BUFFER
, &prev_draw
);
1986 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
1987 if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_FRONTBUFFER
|DDSCAPS_PRIMARYSURFACE
)) != 0) {
1988 /* Application wants to lock the front buffer */
1989 glDrawBuffer(GL_FRONT
);
1990 } else if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_BACKBUFFER
)) == (DDSCAPS_BACKBUFFER
)) {
1991 /* Application wants to lock the back buffer */
1992 glDrawBuffer(GL_BACK
);
1994 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
1997 if (This
->surface_desc
.u4
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16) {
1998 buffer_type
= GL_UNSIGNED_SHORT_5_6_5
;
2000 WARN(" unsupported pixel format.\n");
2004 glRasterPos2f(0.0, 0.0);
2005 glDrawPixels(This
->surface_desc
.dwWidth
, This
->surface_desc
.dwHeight
,
2006 GL_RGB
, buffer_type
, This
->surface_desc
.lpSurface
);
2007 glDrawBuffer(prev_draw
);
2014 d3ddevice_create(IDirect3DDeviceImpl
**obj
, IDirect3DImpl
*d3d
, IDirectDrawSurfaceImpl
*surface
)
2016 IDirect3DDeviceImpl
*object
;
2017 IDirect3DDeviceGLImpl
*gl_object
;
2018 IDirectDrawSurfaceImpl
*surf
;
2022 XVisualInfo
template;
2023 GLenum buffer
= GL_FRONT
;
2026 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DDeviceGLImpl
));
2027 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
2029 gl_object
= (IDirect3DDeviceGLImpl
*) object
;
2033 object
->surface
= surface
;
2034 object
->set_context
= set_context
;
2035 object
->clear
= d3ddevice_clear
;
2036 object
->set_matrices
= d3ddevice_set_matrices
;
2037 object
->matrices_updated
= d3ddevice_matrices_updated
;
2039 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface
, d3d
);
2041 device_context
= GetDC(surface
->ddraw_owner
->window
);
2042 gl_object
->display
= get_display(device_context
);
2043 gl_object
->drawable
= get_drawable(device_context
);
2044 ReleaseDC(surface
->ddraw_owner
->window
,device_context
);
2047 template.visualid
= (VisualID
)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2048 vis
= XGetVisualInfo(gl_object
->display
, VisualIDMask
, &template, &num
);
2050 HeapFree(GetProcessHeap(), 0, object
);
2051 ERR("No visual found !\n");
2053 return DDERR_INVALIDPARAMS
;
2055 TRACE(" visual found\n");
2058 gl_object
->gl_context
= glXCreateContext(gl_object
->display
, vis
,
2061 if (gl_object
->gl_context
== NULL
) {
2062 HeapFree(GetProcessHeap(), 0, object
);
2063 ERR("Error in context creation !\n");
2065 return DDERR_INVALIDPARAMS
;
2067 TRACE(" context created (%p)\n", gl_object
->gl_context
);
2070 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2071 for (surf
= surface
; surf
!= NULL
; surf
= surf
->surface_owner
) {
2072 if ((surf
->surface_desc
.ddsCaps
.dwCaps
&(DDSCAPS_FLIP
|DDSCAPS_FRONTBUFFER
)) == (DDSCAPS_FLIP
|DDSCAPS_FRONTBUFFER
)) {
2073 surf
->aux_ctx
= (LPVOID
) gl_object
->display
;
2074 surf
->aux_data
= (LPVOID
) gl_object
->drawable
;
2075 surf
->aux_flip
= opengl_flip
;
2080 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2082 TRACE(" no double buffering : drawing on the front buffer\n");
2086 for (surf
= surface
; surf
->prev_attached
!= NULL
; surf
= surf
->prev_attached
) ;
2087 for (; surf
!= NULL
; surf
= surf
->next_attached
) {
2088 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_3DDEVICE
)) == (DDSCAPS_3DDEVICE
)) &&
2089 ((surf
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_ZBUFFER
)) != (DDSCAPS_ZBUFFER
))) {
2090 /* Override the Lock / Unlock function for all these surfaces */
2091 surf
->lock_update
= d3ddevice_lock_update
;
2092 surf
->unlock_update
= d3ddevice_unlock_update
;
2093 /* And install also the blt / bltfast overrides */
2094 surf
->aux_blt
= d3ddevice_blt
;
2095 surf
->aux_bltfast
= d3ddevice_bltfast
;
2097 surf
->d3ddevice
= object
;
2100 /* FIXME: Should handle other versions than just 7 */
2101 InitDefaultStateBlock(&object
->state_block
,7);
2103 /* FIXME: These 4 statements are kept for compatibility but should be removed as soon
2104 as they are correctly handled */
2105 gl_object
->render_state
.fog_on
= FALSE
;
2106 gl_object
->render_state
.stencil_enable
= FALSE
;
2107 gl_object
->render_state
.lighting_enable
= FALSE
;
2108 gl_object
->render_state
.specular_enable
= FALSE
;
2110 /* Set the various light parameters */
2111 for (light
= 0; light
< MAX_LIGHTS
; light
++) {
2112 /* Only set the fields that are not zero-created */
2113 object
->light_parameters
[light
].dltType
= D3DLIGHT_DIRECTIONAL
;
2114 object
->light_parameters
[light
].dcvDiffuse
.u1
.r
= 1.0;
2115 object
->light_parameters
[light
].dcvDiffuse
.u2
.g
= 1.0;
2116 object
->light_parameters
[light
].dcvDiffuse
.u3
.b
= 1.0;
2117 object
->light_parameters
[light
].dvDirection
.u3
.z
= 1.0;
2120 /* Allocate memory for the matrices */
2121 object
->world_mat
= (D3DMATRIX
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 16 * sizeof(float));
2122 object
->view_mat
= (D3DMATRIX
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 16 * sizeof(float));
2123 object
->proj_mat
= (D3DMATRIX
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 16 * sizeof(float));
2124 memcpy(object
->world_mat
, id_mat
, 16 * sizeof(float));
2125 memcpy(object
->view_mat
, id_mat
, 16 * sizeof(float));
2126 memcpy(object
->proj_mat
, id_mat
, 16 * sizeof(float));
2128 /* Initialisation */
2129 TRACE(" setting current context\n");
2131 object
->set_context(object
);
2133 TRACE(" current context set\n");
2135 /* Apply default render state values */
2136 apply_render_state(gl_object
, &object
->state_block
);
2137 /* FIXME: do something similar for ligh_state and texture_stage_state */
2139 glClearColor(0.0, 0.0, 0.0, 0.0);
2140 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
2141 glDrawBuffer(buffer
);
2142 glReadBuffer(buffer
);
2143 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2146 /* fill_device_capabilities(d3d->ddraw); */
2148 ICOM_INIT_INTERFACE(object
, IDirect3DDevice
, VTABLE_IDirect3DDevice
);
2149 ICOM_INIT_INTERFACE(object
, IDirect3DDevice2
, VTABLE_IDirect3DDevice2
);
2150 ICOM_INIT_INTERFACE(object
, IDirect3DDevice3
, VTABLE_IDirect3DDevice3
);
2151 ICOM_INIT_INTERFACE(object
, IDirect3DDevice7
, VTABLE_IDirect3DDevice7
);
2155 TRACE(" creating implementation at %p.\n", *obj
);
2157 /* And finally warn D3D that this device is now present */
2158 object
->d3d
->added_device(object
->d3d
, object
);